fix undo/redo/cut
This commit is contained in:
parent
bb7ee3851c
commit
921a1369b2
1 changed files with 32 additions and 37 deletions
|
@ -10,7 +10,7 @@ import createMentionPlugin, {
|
||||||
import '@draft-js-plugins/mention/lib/plugin.css'
|
import '@draft-js-plugins/mention/lib/plugin.css'
|
||||||
import {ContentState, DraftHandleValue, EditorState, getDefaultKeyBinding} from 'draft-js'
|
import {ContentState, DraftHandleValue, EditorState, getDefaultKeyBinding} from 'draft-js'
|
||||||
import React, {
|
import React, {
|
||||||
ReactElement, useCallback, useEffect,
|
ReactElement, useCallback,
|
||||||
useMemo, useRef,
|
useMemo, useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
|
@ -46,24 +46,7 @@ const MarkdownEditorInput = (props: Props): ReactElement => {
|
||||||
return EditorState.moveSelectionToEnd(state)
|
return EditorState.moveSelectionToEnd(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
const [editorState, setEditorState] = useState(() => {
|
const [editorState, setEditorState] = useState(() => generateEditorState(initialText))
|
||||||
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 [isMentionPopoverOpen, setIsMentionPopoverOpen] = useState(false)
|
const [isMentionPopoverOpen, setIsMentionPopoverOpen] = useState(false)
|
||||||
const [isEmojiPopoverOpen, setIsEmojiPopoverOpen] = useState(false)
|
const [isEmojiPopoverOpen, setIsEmojiPopoverOpen] = useState(false)
|
||||||
|
@ -87,16 +70,13 @@ const MarkdownEditorInput = (props: Props): ReactElement => {
|
||||||
return {plugins, MentionSuggestions, EmojiSuggestions}
|
return {plugins, MentionSuggestions, EmojiSuggestions}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
const onEditorStateChange = useCallback((newEditorState: EditorState) => {
|
||||||
if (isEditing) {
|
// newEditorState.
|
||||||
if (initialText === '') {
|
const newText = newEditorState.getCurrentContent().getPlainText()
|
||||||
setEditorState(EditorState.createEmpty())
|
|
||||||
} else {
|
onChange && onChange(newText)
|
||||||
setEditorState(EditorState.moveSelectionToEnd(editorState))
|
setEditorState(newEditorState)
|
||||||
}
|
}, [onChange])
|
||||||
setTimeout(() => ref.current?.focus(), 200)
|
|
||||||
}
|
|
||||||
}, [isEditing, initialText])
|
|
||||||
|
|
||||||
const customKeyBindingFn = useCallback((e: React.KeyboardEvent) => {
|
const customKeyBindingFn = useCallback((e: React.KeyboardEvent) => {
|
||||||
if (isMentionPopoverOpen || isEmojiPopoverOpen) {
|
if (isMentionPopoverOpen || isEmojiPopoverOpen) {
|
||||||
|
@ -107,15 +87,37 @@ const MarkdownEditorInput = (props: Props): ReactElement => {
|
||||||
return 'editor-blur'
|
return 'editor-blur'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(getDefaultKeyBinding(e) === 'undo'){
|
||||||
|
return 'editor-undo'
|
||||||
|
}
|
||||||
|
|
||||||
|
if(getDefaultKeyBinding(e) === 'redo'){
|
||||||
|
return 'editor-redo'
|
||||||
|
}
|
||||||
|
|
||||||
return getDefaultKeyBinding(e as any)
|
return getDefaultKeyBinding(e as any)
|
||||||
}, [isEmojiPopoverOpen, isMentionPopoverOpen])
|
}, [isEmojiPopoverOpen, isMentionPopoverOpen])
|
||||||
|
|
||||||
const handleKeyCommand = useCallback((command: string): DraftHandleValue => {
|
const handleKeyCommand = useCallback((command: string, currentState: EditorState): DraftHandleValue => {
|
||||||
if (command === 'editor-blur') {
|
if (command === 'editor-blur') {
|
||||||
ref.current?.blur()
|
ref.current?.blur()
|
||||||
return 'handled'
|
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'
|
return 'not-handled'
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
@ -124,13 +126,6 @@ const MarkdownEditorInput = (props: Props): ReactElement => {
|
||||||
onBlur && onBlur(text)
|
onBlur && onBlur(text)
|
||||||
}, [editorState, onBlur])
|
}, [editorState, onBlur])
|
||||||
|
|
||||||
const onEditorStateChange = useCallback((newEditorState: EditorState) => {
|
|
||||||
const newText = newEditorState.getCurrentContent().getPlainText()
|
|
||||||
|
|
||||||
onChange && onChange(newText)
|
|
||||||
setEditorState(newEditorState)
|
|
||||||
}, [onChange])
|
|
||||||
|
|
||||||
const onMentionPopoverOpenChange = useCallback((open: boolean) => {
|
const onMentionPopoverOpenChange = useCallback((open: boolean) => {
|
||||||
setIsMentionPopoverOpen(open)
|
setIsMentionPopoverOpen(open)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
Loading…
Reference in a new issue