fix(richtext-lexical): restore selection (#10129)
Fix #9964 Now we make sure that the node for the previous selection exists before restoring it to avoid a runtime error. I also optimized the performance of a function in the client feature. In the future, we should centralize the insertion of all decorator blocks in one place. There are several things to improve. For example, currently an additional paragraph is inserted (in addition to the one for the selection we delete).
This commit is contained in:
@@ -59,15 +59,11 @@ export const UploadPlugin: PluginComponent<UploadFeaturePropsClient> = ({ client
|
|||||||
const { focus } = selection
|
const { focus } = selection
|
||||||
const focusNode = focus.getNode()
|
const focusNode = focus.getNode()
|
||||||
|
|
||||||
// First, delete currently selected node if it's an empty paragraph and if there are sufficient
|
// Delete the node it it's an empty paragraph and it has at least one sibling, so that we don't "trap" the user
|
||||||
// paragraph nodes (more than 1) left in the parent node, so that we don't "trap" the user
|
|
||||||
if (
|
if (
|
||||||
$isParagraphNode(focusNode) &&
|
$isParagraphNode(focusNode) &&
|
||||||
focusNode.getTextContentSize() === 0 &&
|
!focusNode.__first &&
|
||||||
focusNode
|
(focusNode.__prev || focusNode.__next)
|
||||||
.getParentOrThrow()
|
|
||||||
.getChildren()
|
|
||||||
.filter((node) => $isParagraphNode(node)).length > 1
|
|
||||||
) {
|
) {
|
||||||
focusNode.remove()
|
focusNode.remove()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,14 @@ import type { BaseSelection } from 'lexical'
|
|||||||
|
|
||||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
|
||||||
import { useListDrawer, useModal } from '@payloadcms/ui'
|
import { useListDrawer, useModal } from '@payloadcms/ui'
|
||||||
import { $getPreviousSelection, $getSelection, $setSelection } from 'lexical'
|
import {
|
||||||
|
$getNodeByKey,
|
||||||
|
$getPreviousSelection,
|
||||||
|
$getRoot,
|
||||||
|
$getSelection,
|
||||||
|
$isRangeSelection,
|
||||||
|
$setSelection,
|
||||||
|
} from 'lexical'
|
||||||
import { useCallback, useEffect, useState } from 'react'
|
import { useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,7 +56,16 @@ export const useLexicalListDrawer = (
|
|||||||
if (selectionState) {
|
if (selectionState) {
|
||||||
editor.update(
|
editor.update(
|
||||||
() => {
|
() => {
|
||||||
|
if ($isRangeSelection(selectionState)) {
|
||||||
|
const { anchor, focus } = selectionState
|
||||||
|
if ($getNodeByKey(anchor.key) && $getNodeByKey(focus.key)) {
|
||||||
$setSelection(selectionState.clone())
|
$setSelection(selectionState.clone())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// not ideal, but better than losing the selection. Try to set the selection
|
||||||
|
// in a valid place if you remove selected nodes!
|
||||||
|
$getRoot().selectEnd()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{ discrete: true, skipTransforms: true },
|
{ discrete: true, skipTransforms: true },
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user