import React from 'react'; import 'wdk-client/Components/InputControls/wdk-SaveableTextEditor.scss'; import Icon from 'wdk-client/Components/Icon/IconAlt'; import TextBox from 'wdk-client/Components/InputControls/TextBox'; import TextArea from 'wdk-client/Components/InputControls/TextArea'; function sanitaryTextReformat (text: string) { return text .split('<').join('<') .split('>') .join('>') .split('\n').join('
'); } type InputProps = React.TextareaHTMLAttributes & React.InputHTMLAttributes; type InputPropsWithoutOnChange = Omit; interface Props extends InputPropsWithoutOnChange { value: string; onSave: (value: string) => void; multiLine?: boolean; className?: string; displayValue?: (value: string, handleEdit: () => void) => React.ReactNode emptyText?: string; } interface State { editing: boolean; editingValue: string; } class SaveableTextEditor extends React.Component { constructor (props: Props) { super(props); this.state = { editing: false, editingValue: props.value }; this.handleEdit = this.handleEdit.bind(this); this.handleSave = this.handleSave.bind(this); this.handleCancel = this.handleCancel.bind(this); this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleEdit () { if (this.state.editing) return; const { value } = this.props; this.setState({ editing: true, editingValue: value }); } handleSave () { if (!this.state.editing) return; const { onSave } = this.props; const { editingValue } = this.state; onSave(editingValue); this.handleCancel(); } handleCancel () { if (!this.state.editing) return; this.setState({ editing: false, editingValue: this.props.value }); } handleChange (editingValue: string) { if (!this.state.editing) return; this.setState({ editingValue }); } handleSubmit (event: React.FormEvent) { event.preventDefault(); if (!this.state.editing) return; this.handleSave(); } render () { const { multiLine, className, value, onSave, emptyText, children, displayValue, readOnly, ...others } = this.props; const { handleEdit, handleSave, handleCancel, handleChange, handleSubmit } = this; const { editing, editingValue } = this.state; const Input = multiLine ? TextArea : TextBox; const inputProps = { value: editingValue, onChange: handleChange, rows: 3, autoFocus: true, onFocus, ...others }; return (
{!children ? null : (
{children}
)}
{editing && }
{typeof displayValue === 'function' ? displayValue(value, handleEdit) : !value.length && emptyText ? {emptyText} : (
null : handleEdit} dangerouslySetInnerHTML={{ __html: sanitaryTextReformat(value) }} /> ) }
{readOnly ? null : (
{editing ? ( ) : ( ) }
)}
); } } export default SaveableTextEditor; function onFocus(event: React.FocusEvent) { event.target.select(); }