Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | 1x 1x 1x | import React, {Component} from 'react'; import PropTypes from 'prop-types/prop-types'; import shallowequal from 'shallowequal'; /** * Single line contentEditable * * This component creates a span with contenteditable * It only supports one line content, so users are expected * to pass in onKeyDown and intercept the enter key */ function getInnerHTML(txt) { const el = document.createElement('div'); el.textContent = txt; return el.innerHTML; } export default class ContentEditable extends Component { static defaultProps = { onChange: () => {}, onKeyDown: () => {}, itDidMount: () => {}, value: '', } static propTypes = { onChange: PropTypes.func, onKeyDown: PropTypes.func, itDidMount: PropTypes.func, value: PropTypes.string, id: PropTypes.string, 'aria-label': PropTypes.string, } handleChange = _ => { this.props.onChange(this.elem.textContent); } handleKeyDown = e => { if (e.keyCode === 13 && !e.shiftKey) { // ENTER e.preventDefault(); } e.stopPropagation(); this.props.onKeyDown(e); } handlePaste = ev => { ev.preventDefault(); const text = ev.clipboardData.getData('text'); document.execCommand('insertText', false, text); } componentDidMount() { this.props.itDidMount(this.elem); this.elem.spellcheck = false; this.elem.focus(); } /*eslint no-unused-vars: "off"*/ shouldComponentUpdate(props) { const {value: newValue, 'aria-label': newAriaLabel, ...newProps} = props; const {value: oldValue, 'aria-label': oldAriaLabel, ...oldProps} = this.props; return ( (getInnerHTML(newValue) !== this.elem.innerHTML) || !shallowequal(newProps, oldProps) ); } render () { const {value, itDidMount, ...props} = this.props; return ( <span {...props} ref={elem => this.elem = elem} dangerouslySetInnerHTML={{__html: getInnerHTML(value)}} contentEditable={true} onInput={this.handleChange} onKeyDown={this.handleKeyDown} onPaste={this.handlePaste} /> ); } } |