Merge pull request #3805 from payloadcms/fix/lexical-use-client

fix(richtext-lexical): missing use client markers required for next.js compatibility
This commit is contained in:
Alessio Gravili
2023-10-21 23:25:09 +02:00
committed by GitHub
47 changed files with 138 additions and 129 deletions

View File

@@ -1,3 +1,4 @@
'use client'
import type { SerializedEditorState } from 'lexical'
import { Error, FieldDescription, Label, useField, withCondition } from 'payload/components/forms'

View File

@@ -1,13 +1,13 @@
import type { SerializedHeadingNode, SerializedQuoteNode } from '@lexical/rich-text'
import type { SerializedQuoteNode } from '@lexical/rich-text'
import { $createQuoteNode, HeadingNode, QuoteNode } from '@lexical/rich-text'
import { $createQuoteNode, QuoteNode } from '@lexical/rich-text'
import { $setBlocksType } from '@lexical/selection'
import { $getSelection, $isRangeSelection } from 'lexical'
import type { HTMLConverter } from '../converters/html/converter/types'
import type { FeatureProvider } from '../types'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import { BlockquoteIcon } from '../../lexical/ui/icons/Blockquote'
import { TextDropdownSectionWithEntries } from '../common/floatingSelectToolbarTextDropdownSection'
import { convertLexicalNodesToHTML } from '../converters/html/converter'
@@ -26,7 +26,6 @@ export const BlockQuoteFeature = (): FeatureProvider => {
key: 'blockquote',
label: `Blockquote`,
onClick: ({ editor }) => {
//setHeading(editor, headingSize)
editor.update(() => {
const selection = $getSelection()
if ($isRangeSelection(selection)) {

View File

@@ -1,3 +1,4 @@
'use client'
import { type ElementFormatType } from 'lexical'
import { Form, buildInitialState, useFormSubmitted } from 'payload/components/forms'
import React, { useEffect, useMemo } from 'react'

View File

@@ -1,3 +1,4 @@
'use client'
import { useModal } from '@faceless-ui/modal'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import {

View File

@@ -5,7 +5,7 @@ import { formatLabels, getTranslation } from 'payload/utilities'
import type { FeatureProvider } from '../types'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import { BlockIcon } from '../../lexical/ui/icons/Block'
import './index.scss'
import { BlockNode } from './nodes/BlocksNode'

View File

@@ -1,3 +1,4 @@
'use client'
import type { SerializedDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode'
import type {
DOMConversionMap,

View File

@@ -1,3 +1,4 @@
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { $insertNodeToNearestRoot, mergeRegister } from '@lexical/utils'
import { COMMAND_PRIORITY_EDITOR, type LexicalCommand, createCommand } from 'lexical'

View File

@@ -8,7 +8,7 @@ import { $getSelection, $isRangeSelection, DEPRECATED_$isGridSelection } from 'l
import type { HTMLConverter } from '../converters/html/converter/types'
import type { FeatureProvider } from '../types'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import { H1Icon } from '../../lexical/ui/icons/H1'
import { H2Icon } from '../../lexical/ui/icons/H2'
import { H3Icon } from '../../lexical/ui/icons/H3'

View File

@@ -2,7 +2,6 @@ import type { i18n } from 'i18next'
import type { SanitizedConfig } from 'payload/config'
import type { Field } from 'payload/types'
import LexicalClickableLinkPlugin from '@lexical/react/LexicalClickableLinkPlugin'
import { $findMatchingParent } from '@lexical/utils'
import { $getSelection, $isRangeSelection } from 'lexical'
import { withMergedProps } from 'payload/utilities'
@@ -20,6 +19,7 @@ import './index.scss'
import { AutoLinkNode } from './nodes/AutoLinkNode'
import { $isLinkNode, LinkNode, TOGGLE_LINK_COMMAND } from './nodes/LinkNode'
import { AutoLinkPlugin } from './plugins/autoLink'
import { ClickableLinkPlugin } from './plugins/clickableLink'
import { FloatingLinkEditorPlugin } from './plugins/floatingLinkEditor'
import { TOGGLE_LINK_WITH_MODAL_COMMAND } from './plugins/floatingLinkEditor/LinkEditor'
import { LinkPlugin } from './plugins/link'
@@ -39,7 +39,7 @@ export const LinkFeature = (props: LinkFeatureProps): FeatureProvider => {
FeaturesSectionWithEntries([
{
ChildComponent: LinkIcon,
isActive: ({ editor, selection }) => {
isActive: ({ selection }) => {
if ($isRangeSelection(selection)) {
const selectedNode = getSelectedNode(selection)
const linkParent = $findMatchingParent(selectedNode, $isLinkNode)
@@ -142,7 +142,7 @@ export const LinkFeature = (props: LinkFeatureProps): FeatureProvider => {
position: 'normal',
},
{
Component: LexicalClickableLinkPlugin,
Component: ClickableLinkPlugin,
position: 'normal',
},
{

View File

@@ -1,11 +1,4 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
'use client'
import type { ElementNode, LexicalEditor, LexicalNode } from 'lexical'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'

View File

@@ -0,0 +1,7 @@
'use client'
import LexicalClickableLinkPlugin from '@lexical/react/LexicalClickableLinkPlugin'
import React from 'react'
export function ClickableLinkPlugin() {
return <LexicalClickableLinkPlugin />
}

View File

@@ -1,3 +1,4 @@
'use client'
import type { LexicalCommand } from 'lexical'
import type { Data, Fields } from 'payload/types'

View File

@@ -1,3 +1,4 @@
'use client'
import * as React from 'react'
import { createPortal } from 'react-dom'

View File

@@ -1,11 +1,4 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { mergeRegister } from '@lexical/utils'
import {

View File

@@ -3,7 +3,7 @@ import { $createParagraphNode, $getSelection, $isRangeSelection } from 'lexical'
import type { FeatureProvider } from '../types'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import { TextIcon } from '../../lexical/ui/icons/Text'
import { TextDropdownSectionWithEntries } from '../common/floatingSelectToolbarTextDropdownSection'

View File

@@ -1,3 +1,4 @@
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import {
$getNodeByKey,

View File

@@ -1,6 +1,6 @@
import type { FeatureProvider } from '../types'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import { RelationshipIcon } from '../../lexical/ui/icons/Relationship'
import { INSERT_RELATIONSHIP_WITH_DRAWER_COMMAND } from './drawer'
import './index.scss'
@@ -34,7 +34,7 @@ export const RelationshipFeature = (): FeatureProvider => {
new SlashMenuOption('Relationship', {
Icon: RelationshipIcon,
keywords: ['relationship', 'relation', 'rel'],
onSelect: ({ editor, queryString }) => {
onSelect: ({ editor }) => {
// dispatch INSERT_RELATIONSHIP_WITH_DRAWER_COMMAND
editor.dispatchCommand(INSERT_RELATIONSHIP_WITH_DRAWER_COMMAND, {
replace: false,

View File

@@ -1,3 +1,4 @@
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection'
import { $getNodeByKey, type ElementFormatType } from 'lexical'

View File

@@ -1,3 +1,4 @@
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { $insertNodeToNearestRoot } from '@lexical/utils'
import { COMMAND_PRIORITY_EDITOR, type LexicalCommand, createCommand } from 'lexical'

View File

@@ -1,3 +1,4 @@
'use client'
import type { SanitizedCollectionConfig } from 'payload/types'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'

View File

@@ -1,3 +1,4 @@
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import {
$getNodeByKey,

View File

@@ -6,7 +6,7 @@ import type { HTMLConverter } from '../converters/html/converter/types'
import type { FeatureProvider } from '../types'
import type { SerializedUploadNode } from './nodes/UploadNode'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import { SlashMenuOption } from '../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import { UploadIcon } from '../../lexical/ui/icons/Upload'
import { INSERT_UPLOAD_WITH_DRAWER_COMMAND } from './drawer'
import './index.scss'

View File

@@ -1,3 +1,4 @@
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { $insertNodeToNearestRoot, mergeRegister } from '@lexical/utils'
import { COMMAND_PRIORITY_EDITOR, type LexicalCommand, createCommand } from 'lexical'

View File

@@ -1,3 +1,4 @@
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { TreeView } from '@lexical/react/LexicalTreeView'
import * as React from 'react'

View File

@@ -9,7 +9,7 @@ import './index.scss'
export const IndentFeature = (): FeatureProvider => {
return {
feature: ({ resolvedFeatures, unsanitizedEditorConfig }) => {
feature: () => {
return {
floatingSelectToolbar: {
sections: [

View File

@@ -1,18 +1,18 @@
import { INSERT_CHECK_LIST_COMMAND, ListItemNode, ListNode } from '@lexical/list'
import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin'
import type { FeatureProvider } from '../../types'
import { SlashMenuOption } from '../../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import { SlashMenuOption } from '../../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import { ChecklistIcon } from '../../../lexical/ui/icons/Checklist'
import { ListHTMLConverter, ListItemHTMLConverter } from '../htmlConverter'
import { CHECK_LIST } from './markdownTransformers'
import { LexicalCheckListPlugin } from './plugin'
// 345
// carbs 7
export const CheckListFeature = (): FeatureProvider => {
return {
feature: ({ featureProviderMap, resolvedFeatures, unsanitizedEditorConfig }) => {
feature: ({ featureProviderMap }) => {
return {
markdownTransformers: [CHECK_LIST],
nodes:
@@ -36,7 +36,7 @@ export const CheckListFeature = (): FeatureProvider => {
],
plugins: [
{
Component: CheckListPlugin,
Component: LexicalCheckListPlugin,
position: 'normal',
},
],

View File

@@ -0,0 +1,7 @@
'use client'
import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin'
import React from 'react'
export function LexicalCheckListPlugin() {
return <CheckListPlugin />
}

View File

@@ -1,11 +1,11 @@
import { INSERT_ORDERED_LIST_COMMAND, ListItemNode, ListNode } from '@lexical/list'
import { ListPlugin } from '@lexical/react/LexicalListPlugin'
import type { FeatureProvider } from '../../types'
import { SlashMenuOption } from '../../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import { SlashMenuOption } from '../../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import { OrderedListIcon } from '../../../lexical/ui/icons/OrderedList'
import { ListHTMLConverter, ListItemHTMLConverter } from '../htmlConverter'
import { LexicalListPlugin } from '../plugin'
import { ORDERED_LIST } from './markdownTransformer'
export const OrderedListFeature = (): FeatureProvider => {
@@ -35,7 +35,7 @@ export const OrderedListFeature = (): FeatureProvider => {
? []
: [
{
Component: ListPlugin,
Component: LexicalListPlugin,
position: 'normal',
},
],

View File

@@ -1,11 +1,11 @@
import { INSERT_UNORDERED_LIST_COMMAND, ListItemNode, ListNode } from '@lexical/list'
import { ListPlugin } from '@lexical/react/LexicalListPlugin'
import type { FeatureProvider } from '../../types'
import { SlashMenuOption } from '../../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import { SlashMenuOption } from '../../../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import { UnorderedListIcon } from '../../../lexical/ui/icons/UnorderedList'
import { ListHTMLConverter, ListItemHTMLConverter } from '../htmlConverter'
import { LexicalListPlugin } from '../plugin'
import { UNORDERED_LIST } from './markdownTransformer'
export const UnoderedListFeature = (): FeatureProvider => {
@@ -31,7 +31,7 @@ export const UnoderedListFeature = (): FeatureProvider => {
],
plugins: [
{
Component: ListPlugin,
Component: LexicalListPlugin,
position: 'normal',
},
],

View File

@@ -0,0 +1,7 @@
'use client'
import { ListPlugin } from '@lexical/react/LexicalListPlugin'
import React from 'react'
export function LexicalListPlugin() {
return <ListPlugin />
}

View File

@@ -8,7 +8,7 @@ import type React from 'react'
import type { AdapterProps } from '../../types'
import type { EditorConfig } from '../lexical/config/types'
import type { FloatingToolbarSection } from '../lexical/plugins/FloatingSelectToolbar/types'
import type { SlashMenuGroup } from '../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
import type { SlashMenuGroup } from '../lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
import type { HTMLConverter } from './converters/html/converter/types'
export type PopulationPromise<T extends SerializedLexicalNode = SerializedLexicalNode> = ({

View File

@@ -1,3 +1,4 @@
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import LexicalErrorBoundary from '@lexical/react/LexicalErrorBoundary'
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'

View File

@@ -1,3 +1,4 @@
'use client'
import type { InitialConfigType } from '@lexical/react/LexicalComposer'
import type { EditorState, SerializedEditorState } from 'lexical'
import type { LexicalEditor } from 'lexical'

View File

@@ -1,3 +1,4 @@
'use client'
import * as React from 'react'
import { createContext, useContext, useEffect, useMemo, useState } from 'react'

View File

@@ -1,3 +1,4 @@
'use client'
import React, { useCallback, useEffect, useState } from 'react'
const baseClass = 'floating-select-toolbar-popup__button'

View File

@@ -1,3 +1,4 @@
'use client'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { mergeRegister } from '@lexical/utils'
import { $getSelection } from 'lexical'

View File

@@ -1,3 +1,4 @@
'use client'
import React from 'react'
const baseClass = 'floating-select-toolbar-popup__dropdown'

View File

@@ -1,3 +1,4 @@
'use client'
import type { LexicalEditor } from 'lexical'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'

View File

@@ -1,11 +1,4 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
'use client'
import { MarkdownShortcutPlugin as LexicalMarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin'
import * as React from 'react'

View File

@@ -1,4 +1,4 @@
import type { i18n } from 'i18next'
'use client'
import type { LexicalCommand, LexicalEditor, TextNode } from 'lexical'
import type { MutableRefObject, ReactPortal } from 'react'
@@ -17,6 +17,9 @@ import {
} from 'lexical'
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
import type { SlashMenuOption } from './types'
import type { SlashMenuGroup } from './types'
export type MenuTextMatch = {
leadOffset: number
matchingString: string
@@ -30,56 +33,6 @@ export type MenuResolution = {
export const PUNCTUATION = '\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%\'"~=<>_:;'
export class SlashMenuGroup {
options: Array<SlashMenuOption>
title: string
}
export class SlashMenuOption {
Icon: React.FC
displayName?: ({ i18n }: { i18n: i18n }) => string
// Icon for display
key: string
// TBD
keyboardShortcut?: string
// For extra searching.
keywords: Array<string>
// What happens when you select this option?
onSelect: ({ editor, queryString }: { editor: LexicalEditor; queryString: string }) => void
ref?: MutableRefObject<HTMLElement | null>
// What shows up in the editor
title: string
constructor(
title: string,
options: {
Icon: React.FC
displayName?: ({ i18n }: { i18n: i18n }) => string
keyboardShortcut?: string
keywords?: Array<string>
onSelect: ({ editor, queryString }: { editor: LexicalEditor; queryString: string }) => void
},
) {
this.key = title
this.ref = { current: null }
this.setRefElement = this.setRefElement.bind(this)
this.title = title
this.displayName = options.displayName
this.keywords = options.keywords || []
this.Icon = options.Icon
this.keyboardShortcut = options.keyboardShortcut
this.onSelect = options.onSelect.bind(this)
}
setRefElement(element: HTMLElement | null) {
this.ref = { current: element }
}
}
export type MenuRenderFn = (
anchorElementRef: MutableRefObject<HTMLElement | null>,
itemProps: {

View File

@@ -1,3 +1,4 @@
'use client'
import type {
LexicalCommand,
LexicalEditor,
@@ -18,14 +19,8 @@ import {
import { useCallback, useEffect, useState } from 'react'
import * as React from 'react'
import type {
MenuRenderFn,
MenuResolution,
MenuTextMatch,
SlashMenuGroup,
SlashMenuOption,
TriggerFn,
} from './LexicalMenu'
import type { MenuRenderFn, MenuResolution, MenuTextMatch, TriggerFn } from './LexicalMenu'
import type { SlashMenuGroup, SlashMenuOption } from './types'
import { LexicalMenu, useMenuAnchorRef } from './LexicalMenu'

View File

@@ -0,0 +1,53 @@
import type { i18n } from 'i18next'
import type { LexicalEditor } from 'lexical'
import type { MutableRefObject } from 'react'
export class SlashMenuOption {
Icon: React.FC
displayName?: ({ i18n }: { i18n: i18n }) => string
// Icon for display
key: string
// TBD
keyboardShortcut?: string
// For extra searching.
keywords: Array<string>
// What happens when you select this option?
onSelect: ({ editor, queryString }: { editor: LexicalEditor; queryString: string }) => void
ref?: MutableRefObject<HTMLElement | null>
// What shows up in the editor
title: string
constructor(
title: string,
options: {
Icon: React.FC
displayName?: ({ i18n }: { i18n: i18n }) => string
keyboardShortcut?: string
keywords?: Array<string>
onSelect: ({ editor, queryString }: { editor: LexicalEditor; queryString: string }) => void
},
) {
this.key = title
this.ref = { current: null }
this.setRefElement = this.setRefElement.bind(this)
this.title = title
this.displayName = options.displayName
this.keywords = options.keywords || []
this.Icon = options.Icon
this.keyboardShortcut = options.keyboardShortcut
this.onSelect = options.onSelect.bind(this)
}
setRefElement(element: HTMLElement | null) {
this.ref = { current: element }
}
}
export class SlashMenuGroup {
options: Array<SlashMenuOption>
title: string
}

View File

@@ -1,3 +1,4 @@
'use client'
import type { TextNode } from 'lexical'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
@@ -6,8 +7,7 @@ import * as React from 'react'
import * as ReactDOM from 'react-dom'
import { useTranslation } from 'react-i18next'
import type { SlashMenuGroup } from './LexicalTypeaheadMenuPlugin/LexicalMenu'
import type { SlashMenuOption } from './LexicalTypeaheadMenuPlugin/LexicalMenu'
import type { SlashMenuGroup, SlashMenuOption } from './LexicalTypeaheadMenuPlugin/types'
import { useEditorConfigContext } from '../../config/EditorConfigProvider'
import {

View File

@@ -1,10 +1,4 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
'use client'
import type { ParagraphNode } from 'lexical'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'

View File

@@ -1,10 +1,4 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
'use client'
import type { LexicalEditor } from 'lexical'
import type { DragEvent as ReactDragEvent } from 'react'

View File

@@ -246,16 +246,16 @@ export {
type FloatingToolbarSection,
type FloatingToolbarSectionEntry,
} from './field/lexical/plugins/FloatingSelectToolbar/types'
export {
SlashMenuGroup,
SlashMenuOption,
} from './field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/LexicalMenu'
export { ENABLE_SLASH_MENU_COMMAND } from './field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index'
// export SanitizedEditorConfig
export type { EditorConfig, SanitizedEditorConfig }
export type { AdapterProps }
export { RichTextCell }
export { RichTextField }
export { ENABLE_SLASH_MENU_COMMAND } from './field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/index'
export {
SlashMenuGroup,
SlashMenuOption,
} from './field/lexical/plugins/SlashMenu/LexicalTypeaheadMenuPlugin/types'
export { CAN_USE_DOM } from './field/lexical/utils/canUseDOM'
export { cloneDeep } from './field/lexical/utils/cloneDeep'
export { getDOMRangeRect } from './field/lexical/utils/getDOMRangeRect'