Open dounai1306 opened 4 years ago
import React, {FunctionComponent, useCallback, useRef} from 'react'; import { makeStyles, WithStyles, createStyles, Theme, useTheme } from '@material-ui/core/styles'; import 'draft-js/dist/Draft.css'; import './RichEditor.css'; const Draft = require('draft-js'); const {Editor, EditorState, RichUtils, getDefaultKeyBinding, convertFromRaw,} = Draft; const styles = (theme: Theme) => createStyles({ root: { padding: '20px', }, editor: { background: '#fff', cursor: 'text', minHeight: 80, borderTop: '1px solid #dbdbdb', paddingTop: 10 }, }); const useStyles = makeStyles(styles); type Props = {} & Partial<WithStyles<Partial<typeof styles>>>; const Comp: FunctionComponent<Props> = props => { const classes = useStyles(props); const editorRef = useRef<any>('editor'); const [editorState, setEditorState] = React.useState( () => EditorState.createEmpty(), ); let className = 'RichEditor-editor'; let contentState = editorState.getCurrentContent(); if (!contentState.hasText()) { if (contentState.getBlockMap().first().getType() !== 'unstyled') { className += ' RichEditor-hidePlaceholder'; } } const handleKeyCommand = (command: any, editorState: any) => { const newState = RichUtils.handleKeyCommand(editorState, command); if (newState) { setEditorState(newState); return true; } return false; }; const mapKeyToEditorCommand = (e: any) => { if (e.keyCode === 9 /* TAB */) { const newEditorState = RichUtils.onTab( e, editorState, 4, /* maxDepth */ ); if (newEditorState !== editorState) { setEditorState(newEditorState); } return; } return getDefaultKeyBinding(e); }; const toggleInlineStyle = (inlineStyle: any) => { setEditorState( RichUtils.toggleInlineStyle( editorState, inlineStyle ) ); }; const toggleBlockType = (blockType: any) => { setEditorState( RichUtils.toggleBlockType( editorState, blockType ) ); }; return ( <div className={classes.root}> <div className={'RichEditor-root'}> <BlockStyleControls editorState={editorState} onToggle={toggleBlockType} /> <InlineStyleControls editorState={editorState} onToggle={toggleInlineStyle} /> <div className={classes.editor}> <Editor blockStyleFn={getBlockStyle} customStyleMap={styleMap} editorState={editorState} handleKeyCommand={handleKeyCommand} keyBindingFn={mapKeyToEditorCommand} onChange={setEditorState} placeholder="Enter some text..." ref={editorRef} spellCheck /> </div> </div> </div> ); }; // draft 配置 const getBlockStyle = (block: any) => { switch (block.getType()) { case 'blockquote': return 'RichEditor-blockquote'; default: return null; } }; const styleMap = { CODE: { backgroundColor: 'rgba(0, 0, 0, 0.05)', fontFamily: '"Inconsolata", "Menlo", "Consolas", monospace', fontSize: 16, padding: 2, }, }; const INLINE_STYLES = [ {label: 'B', style: 'BOLD'}, {label: 'I', style: 'ITALIC'}, {label: 'U', style: 'UNDERLINE'}, {label: 'M', style: 'CODE'}, ]; const InlineStyleControls = (props: any) => { const currentStyle = props.editorState.getCurrentInlineStyle(); return ( <div className="RichEditor-controls"> {INLINE_STYLES.map((type: any) => <StyleButton key={type.label} active={currentStyle.has(type.style)} label={type.label} onToggle={props.onToggle} style={type.style} /> )} </div> ); }; const StyleButton = (props: any) => { let className = 'RichEditor-styleButton'; if (props.active) { className += ' RichEditor-activeButton'; } const onToggle = (e: any) => { e.preventDefault(); props.onToggle(props.style); }; return ( <span className={className} onMouseDown={onToggle}>{props.label}</span> ) }; const BLOCK_TYPES = [ {label: 'H1', style: 'header-one'}, {label: 'H2', style: 'header-two'}, {label: 'H3', style: 'header-three'}, {label: 'H4', style: 'header-four'}, {label: 'H5', style: 'header-five'}, {label: 'H6', style: 'header-six'}, {label: 'Blockquote', style: 'blockquote'}, {label: 'UL', style: 'unordered-list-item'}, {label: 'OL', style: 'ordered-list-item'}, {label: 'Code', style: 'code-block'}, ]; const BlockStyleControls = (props: any) => { const {editorState} = props; const selection = editorState.getSelection(); const blockType = editorState .getCurrentContent() .getBlockForKey(selection.getStartKey()) .getType(); return ( <div className="RichEditor-controls"> {BLOCK_TYPES.map((type: any) => <StyleButton key={type.label} active={type.style === blockType} label={type.label} onToggle={props.onToggle} style={type.style} /> )} </div> ); }; export default Comp;
https://codepen.io/dounai1306/pen/Vweowmb