fix undo/redo/cut

This commit is contained in:
kyeongsoosoo 2022-04-19 01:37:06 +09:00
parent bb7ee3851c
commit 921a1369b2

View file

@ -10,7 +10,7 @@ import createMentionPlugin, {
import '@draft-js-plugins/mention/lib/plugin.css'
import {ContentState, DraftHandleValue, EditorState, getDefaultKeyBinding} from 'draft-js'
import React, {
ReactElement, useCallback, useEffect,
ReactElement, useCallback,
useMemo, useRef,
useState,
} from 'react'
@ -46,24 +46,7 @@ const MarkdownEditorInput = (props: Props): ReactElement => {
return EditorState.moveSelectionToEnd(state)
}
const [editorState, setEditorState] = useState(() => {
return generateEditorState(initialText)
})
const [initialTextCache, setInitialTextCache] = useState<string | undefined>(initialText)
// avoiding stale closure
useEffect(() => {
// only change editor state when initialText actually changes from one defined value to another.
// This is needed to make the mentions plugin work. For some reason, if we don't check
// for this if condition here, mentions don't work. I suspect it's because without
// the in condition, we're changing editor state twice during component initialization
// and for some reason it causes mentions to not show up.
if (initialText && initialText !== initialTextCache) {
setEditorState(generateEditorState(initialText || ''))
setInitialTextCache(initialText)
}
}, [initialText])
const [editorState, setEditorState] = useState(() => generateEditorState(initialText))
const [isMentionPopoverOpen, setIsMentionPopoverOpen] = useState(false)
const [isEmojiPopoverOpen, setIsEmojiPopoverOpen] = useState(false)
@ -87,16 +70,13 @@ const MarkdownEditorInput = (props: Props): ReactElement => {
return {plugins, MentionSuggestions, EmojiSuggestions}
}, [])
useEffect(() => {
if (isEditing) {
if (initialText === '') {
setEditorState(EditorState.createEmpty())
} else {
setEditorState(EditorState.moveSelectionToEnd(editorState))
}
setTimeout(() => ref.current?.focus(), 200)
}
}, [isEditing, initialText])
const onEditorStateChange = useCallback((newEditorState: EditorState) => {
// newEditorState.
const newText = newEditorState.getCurrentContent().getPlainText()
onChange && onChange(newText)
setEditorState(newEditorState)
}, [onChange])
const customKeyBindingFn = useCallback((e: React.KeyboardEvent) => {
if (isMentionPopoverOpen || isEmojiPopoverOpen) {
@ -107,14 +87,36 @@ const MarkdownEditorInput = (props: Props): ReactElement => {
return 'editor-blur'
}
if(getDefaultKeyBinding(e) === 'undo'){
return 'editor-undo'
}
if(getDefaultKeyBinding(e) === 'redo'){
return 'editor-redo'
}
return getDefaultKeyBinding(e as any)
}, [isEmojiPopoverOpen, isMentionPopoverOpen])
const handleKeyCommand = useCallback((command: string): DraftHandleValue => {
const handleKeyCommand = useCallback((command: string, currentState: EditorState): DraftHandleValue => {
if (command === 'editor-blur') {
ref.current?.blur()
return 'handled'
}
if(command === 'editor-redo'){
const selectionRemovedState = EditorState.redo(currentState)
onEditorStateChange(EditorState.redo(selectionRemovedState))
return 'handled'
}
if(command === 'editor-undo'){
const selectionRemovedState = EditorState.undo(currentState)
onEditorStateChange(EditorState.undo(selectionRemovedState))
return 'handled'
}
return 'not-handled'
}, [])
@ -124,13 +126,6 @@ const MarkdownEditorInput = (props: Props): ReactElement => {
onBlur && onBlur(text)
}, [editorState, onBlur])
const onEditorStateChange = useCallback((newEditorState: EditorState) => {
const newText = newEditorState.getCurrentContent().getPlainText()
onChange && onChange(newText)
setEditorState(newEditorState)
}, [onChange])
const onMentionPopoverOpenChange = useCallback((open: boolean) => {
setIsMentionPopoverOpen(open)
}, [])