From 9b9376bd041559766fe86786c749a0d033c837b1 Mon Sep 17 00:00:00 2001 From: Kevin Chavez Date: Tue, 28 Jan 2020 03:02:24 -0800 Subject: [PATCH] Re-write `DraftEditorExample` in the website using react hooks (#2287) Summary: Also took the oportunity to clean up the component- it had unused imports and `_handleKeyCommand` was returning a boolean instead of `"handled"` and `"not-handled"`. `yarn && yarn start`, used the editor. Pull Request resolved: https://github.com/facebook/draft-js/pull/2287 Differential Revision: D19598449 Pulled By: claudiopro fbshipit-source-id: 275ef520c10f941236138211c8eb572c6df28f9d --- .../components/DraftEditorExample/index.js | 217 ++++++++---------- 1 file changed, 101 insertions(+), 116 deletions(-) diff --git a/website/src/components/DraftEditorExample/index.js b/website/src/components/DraftEditorExample/index.js index 06c7ea1b01..96ce378da9 100644 --- a/website/src/components/DraftEditorExample/index.js +++ b/website/src/components/DraftEditorExample/index.js @@ -6,111 +6,102 @@ */ import React from 'react'; -import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import useBaseUrl from '@docusaurus/useBaseUrl'; import {Editor, EditorState, RichUtils, getDefaultKeyBinding} from 'draft-js'; -import classnames from 'classnames'; - -import Layout from '@theme/Layout'; import './css/example.css'; import './css/draft.css'; import './css/rich-editor.css'; -class RichEditorExample extends React.Component { - constructor(props) { - super(props); - this.state = {editorState: EditorState.createEmpty()}; - - this.focus = () => this.editor.focus(); - this.onChange = editorState => this.setState({editorState}); - - this.handleKeyCommand = this._handleKeyCommand.bind(this); - this.mapKeyToEditorCommand = this._mapKeyToEditorCommand.bind(this); - this.toggleBlockType = this._toggleBlockType.bind(this); - this.toggleInlineStyle = this._toggleInlineStyle.bind(this); - } - - _handleKeyCommand(command, editorState) { - const newState = RichUtils.handleKeyCommand(editorState, command); - if (newState) { - this.onChange(newState); - return true; - } - return false; - } +const {useState, useRef, useCallback} = React; - _mapKeyToEditorCommand(e) { - switch (e.keyCode) { - case 9: // TAB - const newEditorState = RichUtils.onTab( - e, - this.state.editorState, - 4 /* maxDepth */, - ); - if (newEditorState !== this.state.editorState) { - this.onChange(newEditorState); - } - return; - } - return getDefaultKeyBinding(e); - } +function RichEditorExample(props) { + const [editorState, setEditorState] = useState(EditorState.createEmpty()); + const editor = useRef(null); - _toggleBlockType(blockType) { - this.onChange(RichUtils.toggleBlockType(this.state.editorState, blockType)); - } + const focus = () => { + if (editor.current) editor.current.focus(); + }; - _toggleInlineStyle(inlineStyle) { - this.onChange( - RichUtils.toggleInlineStyle(this.state.editorState, inlineStyle), - ); - } + const handleKeyCommand = useCallback( + (command, editorState) => { + const newState = RichUtils.handleKeyCommand(editorState, command); + if (newState) { + setEditorState(newState); + return 'handled'; + } + return 'not-handled'; + }, + [editorState, setEditorState], + ); - render() { - const {editorState} = this.state; - - // If the user changes block type before entering any text, we can - // either style the placeholder or hide it. Let's just hide it now. - let className = 'RichEditor-editor'; - var contentState = editorState.getCurrentContent(); - if (!contentState.hasText()) { - if ( - contentState - .getBlockMap() - .first() - .getType() !== 'unstyled' - ) { - className += ' RichEditor-hidePlaceholder'; + const mapKeyToEditorCommand = useCallback( + e => { + switch (e.keyCode) { + case 9: // TAB + const newEditorState = RichUtils.onTab( + e, + editorState, + 4 /* maxDepth */, + ); + if (newEditorState !== editorState) { + setEditorState(newEditorState); + } + return null; } + return getDefaultKeyBinding(e); + }, + [editorState, setEditorState], + ); + + // If the user changes block type before entering any text, we can + // either style the placeholder or hide it. Let's just hide it now. + let className = 'RichEditor-editor'; + var contentState = editorState.getCurrentContent(); + if (!contentState.hasText()) { + if ( + contentState + .getBlockMap() + .first() + .getType() !== 'unstyled' + ) { + className += ' RichEditor-hidePlaceholder'; } + } - return ( -
- - + { + const newState = RichUtils.toggleBlockType(editorState, blockType); + setEditorState(newState); + }} + /> + { + const newState = RichUtils.toggleInlineStyle( + editorState, + inlineStyle, + ); + setEditorState(newState); + }} + /> +
+ -
- (this.editor = ref)} - spellCheck={true} - /> -
- ); - } +
+ ); } // Custom overrides for "code" style. @@ -132,27 +123,22 @@ function getBlockStyle(block) { } } -class StyleButton extends React.Component { - constructor() { - super(); - this.onToggle = e => { - e.preventDefault(); - this.props.onToggle(this.props.style); - }; +function StyleButton({onToggle, active, label, style}) { + let className = 'RichEditor-styleButton'; + if (active) { + className += ' RichEditor-activeButton'; } - render() { - let className = 'RichEditor-styleButton'; - if (this.props.active) { - className += ' RichEditor-activeButton'; - } - - return ( - - {this.props.label} - - ); - } + return ( + { + e.preventDefault(); + onToggle(style); + }}> + {label} + + ); } const BLOCK_TYPES = [ @@ -168,8 +154,7 @@ const BLOCK_TYPES = [ {label: 'Code Block', style: 'code-block'}, ]; -const BlockStyleControls = props => { - const {editorState} = props; +function BlockStyleControls({editorState, onToggle}) { const selection = editorState.getSelection(); const blockType = editorState .getCurrentContent() @@ -183,13 +168,13 @@ const BlockStyleControls = props => { key={type.label} active={type.style === blockType} label={type.label} - onToggle={props.onToggle} + onToggle={onToggle} style={type.style} /> ))} ); -}; +} const INLINE_STYLES = [ {label: 'Bold', style: 'BOLD'}, @@ -198,8 +183,8 @@ const INLINE_STYLES = [ {label: 'Monospace', style: 'CODE'}, ]; -const InlineStyleControls = props => { - const currentStyle = props.editorState.getCurrentInlineStyle(); +function InlineStyleControls({editorState, onToggle}) { + const currentStyle = editorState.getCurrentInlineStyle(); return (
{INLINE_STYLES.map(type => ( @@ -207,12 +192,12 @@ const InlineStyleControls = props => { key={type.label} active={currentStyle.has(type.style)} label={type.label} - onToggle={props.onToggle} + onToggle={onToggle} style={type.style} /> ))}
); -}; +} export default RichEditorExample;