Created
May 7, 2018 00:03
-
-
Save strass/1e4a3d7e4b34918a15d07484d12a420b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Editor } from 'slate-react'; | |
import { toNumber } from 'lodash'; | |
import Plain from 'slate-plain-serializer'; | |
import PropTypes from 'prop-types'; | |
import React from 'react'; | |
class PlainTextEditor extends React.Component { | |
static propTypes = { | |
inline: PropTypes.bool, | |
value: PropTypes.string, | |
number: PropTypes.bool, | |
placeholder: PropTypes.string, | |
className: PropTypes.string, | |
name: PropTypes.string.isRequired, | |
onChange: PropTypes.func.isRequired, | |
}; | |
static defaultProps = { | |
inline: true, | |
value: '', | |
number: false, | |
placeholder: 'Enter text...', | |
className: '', | |
}; | |
constructor(props) { | |
super(props); | |
this.state = { | |
value: Plain.deserialize(this.props.value), | |
}; | |
} | |
componentWillReceiveProps(nextProps) { | |
if (this.props.value !== nextProps.value) { | |
console.log('value changed'); | |
// Is there anything I need to do here to prevent losing details such as cursor position? | |
this.setState({ | |
value: Plain.deserialize(this.props.value), | |
}); | |
} | |
} | |
_renderPlaceholder = params => { | |
const { node, editor } = params; | |
if (node.object !== 'block') return; | |
// if (node.type !== 'caption') return; | |
if (node.text !== '') return; | |
// Since I am trying to use an inline text editor, I need the placeholder not to have width: 0 | |
return ( | |
<span | |
contentEditable={false} | |
style={{ display: 'inline-block', whiteSpace: 'nowrap', opacity: '0.33', pointerEvents: 'none' }} | |
> | |
{editor.props.placeholder} | |
</span> | |
); | |
}; | |
_onChange = ({ value }) => { | |
if (value.document !== this.state.value.document) { | |
this.setState({ value }, () => | |
this.props.onChange( | |
this.props.number ? toNumber(Plain.serialize(value)) : Plain.serialize(value), | |
this.props.name, | |
), | |
); | |
} | |
}; | |
render() { | |
const WrapperEl = this.props.inline ? 'span' : 'div'; | |
return ( | |
<WrapperEl className={this.props.className}> | |
<Editor | |
placeholder={this.props.placeholder} | |
value={this.state.value} | |
renderPlaceholder={this._renderPlaceholder} | |
onChange={this._onChange} | |
/> | |
</WrapperEl> | |
); | |
} | |
} | |
export default PlainTextEditor; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment