fix(richtext-lexical): lexical editor behind a drawer was incorrectly registered as parent editor of lexical editor within drawer (#10502)
Fixes https://github.com/payloadcms/payload/issues/10462 This behavior caused the fixed toolbar of the lexical editor within the drawer to trigger overlap behavior of the fixed toolbar belonging to the lexical editor behind the drawer. Editors within drawers should be treated as separate, instead of being able to form parent-child relationships between editors behind or in nested drawers
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import type { InitialConfigType } from '@lexical/react/LexicalComposer.js'
|
import type { InitialConfigType } from '@lexical/react/LexicalComposer.js'
|
||||||
import type { EditorState, LexicalEditor, SerializedEditorState } from 'lexical'
|
import type { EditorState, LexicalEditor, SerializedEditorState } from 'lexical'
|
||||||
import type { ClientField } from 'payload'
|
|
||||||
|
|
||||||
import { LexicalComposer } from '@lexical/react/LexicalComposer.js'
|
import { LexicalComposer } from '@lexical/react/LexicalComposer.js'
|
||||||
|
import { useEditDepth } from '@payloadcms/ui'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
|
|
||||||
@@ -53,6 +53,8 @@ export const LexicalProvider: React.FC<LexicalProviderProps> = (props) => {
|
|||||||
|
|
||||||
const parentContext = useEditorConfigContext()
|
const parentContext = useEditorConfigContext()
|
||||||
|
|
||||||
|
const editDepth = useEditDepth()
|
||||||
|
|
||||||
const editorContainerRef = React.useRef<HTMLDivElement>(null)
|
const editorContainerRef = React.useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
// useMemo for the initialConfig that depends on readOnly and value
|
// useMemo for the initialConfig that depends on readOnly and value
|
||||||
@@ -102,7 +104,10 @@ export const LexicalProvider: React.FC<LexicalProviderProps> = (props) => {
|
|||||||
editorConfig={editorConfig}
|
editorConfig={editorConfig}
|
||||||
editorContainerRef={editorContainerRef}
|
editorContainerRef={editorContainerRef}
|
||||||
fieldProps={fieldProps}
|
fieldProps={fieldProps}
|
||||||
parentContext={parentContext}
|
/**
|
||||||
|
* Parent editor is not truly the parent editor, if the current editor is part of a drawer and the parent editor is the main editor.
|
||||||
|
*/
|
||||||
|
parentContext={parentContext?.editDepth === editDepth ? parentContext : undefined}
|
||||||
>
|
>
|
||||||
<NestProviders providers={editorConfig.features.providers}>
|
<NestProviders providers={editorConfig.features.providers}>
|
||||||
<LexicalEditorComponent
|
<LexicalEditorComponent
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import type { LexicalEditor } from 'lexical'
|
|||||||
import type { MarkRequired } from 'ts-essentials'
|
import type { MarkRequired } from 'ts-essentials'
|
||||||
|
|
||||||
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext.js'
|
||||||
|
import { useEditDepth } from '@payloadcms/ui'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { createContext, useContext, useMemo, useRef, useState } from 'react'
|
import { createContext, useContext, useMemo, useRef, useState } from 'react'
|
||||||
|
|
||||||
@@ -21,9 +22,9 @@ export interface EditorConfigContextType {
|
|||||||
blurEditor: (editorContext: EditorConfigContextType) => void
|
blurEditor: (editorContext: EditorConfigContextType) => void
|
||||||
childrenEditors: React.RefObject<Map<string, EditorConfigContextType>>
|
childrenEditors: React.RefObject<Map<string, EditorConfigContextType>>
|
||||||
createdInlineBlock?: InlineBlockNode
|
createdInlineBlock?: InlineBlockNode
|
||||||
|
editDepth: number
|
||||||
editor: LexicalEditor
|
editor: LexicalEditor
|
||||||
editorConfig: SanitizedClientEditorConfig
|
editorConfig: SanitizedClientEditorConfig
|
||||||
|
|
||||||
editorContainerRef: React.RefObject<HTMLDivElement>
|
editorContainerRef: React.RefObject<HTMLDivElement>
|
||||||
fieldProps: MarkRequired<LexicalRichTextFieldProps, 'path' | 'schemaPath'>
|
fieldProps: MarkRequired<LexicalRichTextFieldProps, 'path' | 'schemaPath'>
|
||||||
focusedEditor: EditorConfigContextType | null
|
focusedEditor: EditorConfigContextType | null
|
||||||
@@ -59,13 +60,15 @@ export const EditorConfigProvider = ({
|
|||||||
}): React.ReactNode => {
|
}): React.ReactNode => {
|
||||||
const [editor] = useLexicalComposerContext()
|
const [editor] = useLexicalComposerContext()
|
||||||
// State to store the UUID
|
// State to store the UUID
|
||||||
const [uuid] = useState(generateQuickGuid())
|
const [uuid] = useState(() => generateQuickGuid())
|
||||||
|
|
||||||
const childrenEditors = useRef<Map<string, EditorConfigContextType>>(new Map())
|
const childrenEditors = useRef<Map<string, EditorConfigContextType>>(new Map())
|
||||||
const [focusedEditor, setFocusedEditor] = useState<EditorConfigContextType | null>(null)
|
const [focusedEditor, setFocusedEditor] = useState<EditorConfigContextType | null>(null)
|
||||||
const focusHistory = useRef<Set<string>>(new Set())
|
const focusHistory = useRef<Set<string>>(new Set())
|
||||||
const [createdInlineBlock, setCreatedInlineBlock] = useState<InlineBlockNode>()
|
const [createdInlineBlock, setCreatedInlineBlock] = useState<InlineBlockNode>()
|
||||||
|
|
||||||
|
const editDepth = useEditDepth()
|
||||||
|
|
||||||
const editorContext = useMemo(
|
const editorContext = useMemo(
|
||||||
() =>
|
() =>
|
||||||
({
|
({
|
||||||
@@ -75,6 +78,7 @@ export const EditorConfigProvider = ({
|
|||||||
},
|
},
|
||||||
childrenEditors,
|
childrenEditors,
|
||||||
createdInlineBlock,
|
createdInlineBlock,
|
||||||
|
editDepth,
|
||||||
editor,
|
editor,
|
||||||
editorConfig,
|
editorConfig,
|
||||||
editorContainerRef,
|
editorContainerRef,
|
||||||
@@ -128,6 +132,7 @@ export const EditorConfigProvider = ({
|
|||||||
childrenEditors,
|
childrenEditors,
|
||||||
editorConfig,
|
editorConfig,
|
||||||
editorContainerRef,
|
editorContainerRef,
|
||||||
|
editDepth,
|
||||||
fieldProps,
|
fieldProps,
|
||||||
focusedEditor,
|
focusedEditor,
|
||||||
parentContext,
|
parentContext,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import type { CollectionConfig } from 'payload'
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
defaultEditorFeatures,
|
defaultEditorFeatures,
|
||||||
|
FixedToolbarFeature,
|
||||||
lexicalEditor,
|
lexicalEditor,
|
||||||
RelationshipFeature,
|
RelationshipFeature,
|
||||||
} from '@payloadcms/richtext-lexical'
|
} from '@payloadcms/richtext-lexical'
|
||||||
@@ -30,7 +31,7 @@ export const LexicalRelationshipsFields: CollectionConfig = {
|
|||||||
name: 'richText2',
|
name: 'richText2',
|
||||||
type: 'richText',
|
type: 'richText',
|
||||||
editor: lexicalEditor({
|
editor: lexicalEditor({
|
||||||
features: [...defaultEditorFeatures, RelationshipFeature()],
|
features: [...defaultEditorFeatures, RelationshipFeature(), FixedToolbarFeature()],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user