diff --git a/packages/richtext-lexical/package.json b/packages/richtext-lexical/package.json index 227b829d0..d3a29a4fe 100644 --- a/packages/richtext-lexical/package.json +++ b/packages/richtext-lexical/package.json @@ -41,24 +41,24 @@ "translateNewKeys": "tsx scripts/translateNewKeys.ts" }, "dependencies": { - "@lexical/headless": "0.16.1", - "@lexical/link": "0.16.1", - "@lexical/list": "0.16.1", - "@lexical/mark": "0.16.1", - "@lexical/markdown": "0.16.1", - "@lexical/react": "0.16.1", - "@lexical/rich-text": "0.16.1", - "@lexical/selection": "0.16.1", - "@lexical/utils": "0.16.1", + "@lexical/headless": "0.17.0", + "@lexical/link": "0.17.0", + "@lexical/list": "0.17.0", + "@lexical/mark": "0.17.0", + "@lexical/markdown": "0.17.0", + "@lexical/react": "0.17.0", + "@lexical/rich-text": "0.17.0", + "@lexical/selection": "0.17.0", + "@lexical/utils": "0.17.0", "@types/uuid": "10.0.0", "bson-objectid": "2.0.4", "dequal": "2.0.3", - "lexical": "0.16.1", + "lexical": "0.17.0", "react-error-boundary": "4.0.13", "uuid": "10.0.0" }, "devDependencies": { - "@lexical/eslint-plugin": " 0.16.1", + "@lexical/eslint-plugin": "0.17.0", "@payloadcms/eslint-config": "workspace:*", "@payloadcms/next": "workspace:*", "@payloadcms/translations": "workspace:*", @@ -75,20 +75,20 @@ "peerDependencies": { "@faceless-ui/modal": "3.0.0-beta.2", "@faceless-ui/scroll-info": "2.0.0-beta.0", - "@lexical/headless": "0.16.1", - "@lexical/link": "0.16.1", - "@lexical/list": "0.16.1", - "@lexical/mark": "0.16.1", - "@lexical/markdown": "0.16.1", - "@lexical/react": "0.16.1", - "@lexical/rich-text": "0.16.1", - "@lexical/selection": "0.16.1", - "@lexical/table": "0.16.1", - "@lexical/utils": "0.16.1", + "@lexical/headless": "0.17.0", + "@lexical/link": "0.17.0", + "@lexical/list": "0.17.0", + "@lexical/mark": "0.17.0", + "@lexical/markdown": "0.17.0", + "@lexical/react": "0.17.0", + "@lexical/rich-text": "0.17.0", + "@lexical/selection": "0.17.0", + "@lexical/table": "0.17.0", + "@lexical/utils": "0.17.0", "@payloadcms/next": "workspace:*", "@payloadcms/translations": "workspace:*", "@payloadcms/ui": "workspace:*", - "lexical": "0.16.1", + "lexical": "0.17.0", "payload": "workspace:*", "react": "^19.0.0 || ^19.0.0-rc-6230622a1a-20240610", "react-dom": "^19.0.0 || ^19.0.0-rc-6230622a1a-20240610" diff --git a/packages/richtext-lexical/src/features/experimental_table/feature.client.ts b/packages/richtext-lexical/src/features/experimental_table/feature.client.ts index 02aa36d65..6bafdcc36 100644 --- a/packages/richtext-lexical/src/features/experimental_table/feature.client.ts +++ b/packages/richtext-lexical/src/features/experimental_table/feature.client.ts @@ -8,6 +8,7 @@ import { slashMenuBasicGroupWithItems } from '../shared/slashMenu/basicGroup.js' import { toolbarAddDropdownGroupWithItems } from '../shared/toolbar/addDropdownGroup.js' import { TableActionMenuPlugin } from './plugins/TableActionMenuPlugin/index.js' import { TableCellResizerPlugin } from './plugins/TableCellResizerPlugin/index.js' +import { TableHoverActionsPlugin } from './plugins/TableHoverActionsPlugin/index.js' import { OPEN_TABLE_DRAWER_COMMAND, TableContext, @@ -29,6 +30,10 @@ export const TableFeatureClient = createClientFeature({ Component: TableActionMenuPlugin, position: 'floatingAnchorElem', }, + { + Component: TableHoverActionsPlugin, + position: 'floatingAnchorElem', + }, ], providers: [TableContext], slashMenu: { diff --git a/packages/richtext-lexical/src/features/experimental_table/feature.server.ts b/packages/richtext-lexical/src/features/experimental_table/feature.server.ts index 85915c85b..11c98824a 100644 --- a/packages/richtext-lexical/src/features/experimental_table/feature.server.ts +++ b/packages/richtext-lexical/src/features/experimental_table/feature.server.ts @@ -6,6 +6,8 @@ import { sanitizeFields } from 'payload' // eslint-disable-next-line payload/no-imports-from-exports-dir import { TableFeatureClient } from '../../exports/client/index.js' import { createServerFeature } from '../../utilities/createServerFeature.js' +import { convertLexicalNodesToHTML } from '../converters/html/converter/index.js' +import { createNode } from '../typeUtilities.js' const fields: Field[] = [ { @@ -41,15 +43,75 @@ export const EXPERIMENTAL_TableFeature = createServerFeature({ return schemaMap }, nodes: [ - { + createNode({ + converters: { + html: { + converter: async ({ converters, node, parent, req }) => { + const childrenText = await convertLexicalNodesToHTML({ + converters, + lexicalNodes: node.children, + parent: { + ...node, + parent, + }, + req, + }) + return `${childrenText}
` + }, + nodeTypes: [TableNode.getType()], + }, + }, node: TableNode, - }, - { + }), + createNode({ + converters: { + html: { + converter: async ({ converters, node, parent, req }) => { + const childrenText = await convertLexicalNodesToHTML({ + converters, + lexicalNodes: node.children, + parent: { + ...node, + parent, + }, + req, + }) + + const tagName = node.headerState > 0 ? 'th' : 'td' + const headerStateClass = `lexical-table-cell-header-${node.headerState}` + const backgroundColor = node.backgroundColor + ? `background-color: ${node.backgroundColor};` + : '' + const colSpan = node.colSpan > 1 ? `colspan="${node.colSpan}"` : '' + const rowSpan = node.rowSpan > 1 ? `rowspan="${node.rowSpan}"` : '' + + return `<${tagName} class="lexical-table-cell ${headerStateClass}" style="border: 1px solid #ccc; padding: 8px; ${backgroundColor}" ${colSpan} ${rowSpan}>${childrenText}` + }, + nodeTypes: [TableCellNode.getType()], + }, + }, node: TableCellNode, - }, - { + }), + createNode({ + converters: { + html: { + converter: async ({ converters, node, parent, req }) => { + const childrenText = await convertLexicalNodesToHTML({ + converters, + lexicalNodes: node.children, + parent: { + ...node, + parent, + }, + req, + }) + return `${childrenText}` + }, + nodeTypes: [TableRowNode.getType()], + }, + }, node: TableRowNode, - }, + }), ], } }, diff --git a/packages/richtext-lexical/src/features/experimental_table/plugins/TableActionMenuPlugin/index.tsx b/packages/richtext-lexical/src/features/experimental_table/plugins/TableActionMenuPlugin/index.tsx index a01aa0ea2..c715a3100 100644 --- a/packages/richtext-lexical/src/features/experimental_table/plugins/TableActionMenuPlugin/index.tsx +++ b/packages/richtext-lexical/src/features/experimental_table/plugins/TableActionMenuPlugin/index.tsx @@ -160,15 +160,19 @@ function TableActionMenu({ const { y } = useScrollInfo() useEffect(() => { - return editor.registerMutationListener(TableCellNode, (nodeMutations) => { - const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === 'updated' + return editor.registerMutationListener( + TableCellNode, + (nodeMutations) => { + const nodeUpdated = nodeMutations.get(tableCellNode.getKey()) === 'updated' - if (nodeUpdated) { - editor.getEditorState().read(() => { - updateTableCellNode(tableCellNode.getLatest()) - }) - } - }) + if (nodeUpdated) { + editor.getEditorState().read(() => { + updateTableCellNode(tableCellNode.getLatest()) + }) + } + }, + { skipInitialization: true }, + ) }, [editor, tableCellNode]) useEffect(() => { diff --git a/packages/richtext-lexical/src/features/experimental_table/plugins/TableCellResizerPlugin/index.scss b/packages/richtext-lexical/src/features/experimental_table/plugins/TableCellResizerPlugin/index.scss deleted file mode 100644 index a238b9a2c..000000000 --- a/packages/richtext-lexical/src/features/experimental_table/plugins/TableCellResizerPlugin/index.scss +++ /dev/null @@ -1,3 +0,0 @@ -.TableCellResizer__resizer { - position: absolute; -} diff --git a/packages/richtext-lexical/src/features/experimental_table/plugins/TableCellResizerPlugin/index.tsx b/packages/richtext-lexical/src/features/experimental_table/plugins/TableCellResizerPlugin/index.tsx index 6bf90c1d3..899520ee4 100644 --- a/packages/richtext-lexical/src/features/experimental_table/plugins/TableCellResizerPlugin/index.tsx +++ b/packages/richtext-lexical/src/features/experimental_table/plugins/TableCellResizerPlugin/index.tsx @@ -20,9 +20,9 @@ import * as React from 'react' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { createPortal } from 'react-dom' -import type { PluginComponent, PluginComponentWithAnchor } from '../../../typesClient.js' +import type { PluginComponent } from '../../../typesClient.js' -import './index.scss' +import { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js' type MousePosition = { x: number @@ -38,6 +38,7 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element { const targetRef = useRef(null) const resizerRef = useRef(null) const tableRectRef = useRef(null) + const editorConfig = useEditorConfigContext() const mouseStartPosRef = useRef(null) const [mouseCurrentPos, updateMouseCurrentPos] = useState(null) @@ -117,14 +118,18 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element { }, 0) } - document.addEventListener('mousemove', onMouseMove) - document.addEventListener('mousedown', onMouseDown) - document.addEventListener('mouseup', onMouseUp) + const removeRootListener = editor.registerRootListener((rootElement, prevRootElement) => { + rootElement?.addEventListener('mousemove', onMouseMove) + rootElement?.addEventListener('mousedown', onMouseDown) + rootElement?.addEventListener('mouseup', onMouseUp) + + prevRootElement?.removeEventListener('mousemove', onMouseMove) + prevRootElement?.removeEventListener('mousedown', onMouseDown) + prevRootElement?.removeEventListener('mouseup', onMouseUp) + }) return () => { - document.removeEventListener('mousemove', onMouseMove) - document.removeEventListener('mousedown', onMouseDown) - document.removeEventListener('mouseup', onMouseUp) + removeRootListener() } }, [activeCell, draggingDirection, editor, resetState]) @@ -378,12 +383,12 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element { {activeCell != null && !isMouseDown && (
diff --git a/packages/richtext-lexical/src/features/experimental_table/plugins/TableHoverActionsPlugin/index.tsx b/packages/richtext-lexical/src/features/experimental_table/plugins/TableHoverActionsPlugin/index.tsx new file mode 100644 index 000000000..23de437ad --- /dev/null +++ b/packages/richtext-lexical/src/features/experimental_table/plugins/TableHoverActionsPlugin/index.tsx @@ -0,0 +1,243 @@ +/** + * 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. + * + */ + +import type { TableCellNode, TableRowNode } from '@lexical/table' +import type { EditorConfig, NodeKey } from 'lexical' +import type { JSX } from 'react' + +import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' +import { + $getTableColumnIndexFromTableCellNode, + $getTableRowIndexFromTableCellNode, + $insertTableColumn__EXPERIMENTAL, + $insertTableRow__EXPERIMENTAL, + $isTableCellNode, + $isTableNode, + TableNode, +} from '@lexical/table' +import { $findMatchingParent, mergeRegister } from '@lexical/utils' +import { $getNearestNodeFromDOMNode } from 'lexical' +import { useEffect, useRef, useState } from 'react' +import * as React from 'react' +import { createPortal } from 'react-dom' + +import { useEditorConfigContext } from '../../../../lexical/config/client/EditorConfigProvider.js' +import { useDebounce } from '../../utils/useDebounce.js' + +const BUTTON_WIDTH_PX = 20 + +function TableHoverActionsContainer({ anchorElem }: { anchorElem: HTMLElement }): JSX.Element { + const [editor] = useLexicalComposerContext() + const editorConfig = useEditorConfigContext() + const [isShownRow, setShownRow] = useState(false) + const [isShownColumn, setShownColumn] = useState(false) + const [shouldListenMouseMove, setShouldListenMouseMove] = useState(false) + const [position, setPosition] = useState({}) + const codeSetRef = useRef>(new Set()) + const tableDOMNodeRef = useRef(null) + + const debouncedOnMouseMove = useDebounce( + (event: MouseEvent) => { + const { isOutside, tableDOMNode } = getMouseInfo(event, editorConfig.editorConfig?.lexical) + + if (isOutside) { + setShownRow(false) + setShownColumn(false) + return + } + + if (!tableDOMNode) { + return + } + + tableDOMNodeRef.current = tableDOMNode + + let hoveredRowNode: TableCellNode | null = null + let hoveredColumnNode: TableCellNode | null = null + let tableDOMElement: HTMLElement | null = null + + editor.update(() => { + const maybeTableCell = $getNearestNodeFromDOMNode(tableDOMNode) + + if ($isTableCellNode(maybeTableCell)) { + const table = $findMatchingParent(maybeTableCell, (node) => $isTableNode(node)) + if (!$isTableNode(table)) { + return + } + + tableDOMElement = editor.getElementByKey(table?.getKey()) + + if (tableDOMElement) { + const rowCount = table.getChildrenSize() + const colCount = + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + ((table as TableNode).getChildAtIndex(0) as TableRowNode)?.getChildrenSize() + + const rowIndex = $getTableRowIndexFromTableCellNode(maybeTableCell) + const colIndex = $getTableColumnIndexFromTableCellNode(maybeTableCell) + + if (rowIndex === rowCount - 1) { + hoveredRowNode = maybeTableCell + } else if (colIndex === colCount - 1) { + hoveredColumnNode = maybeTableCell + } + } + } + }) + + if (tableDOMElement) { + const { + bottom: tableElemBottom, + height: tableElemHeight, + right: tableElemRight, + width: tableElemWidth, + x: tableElemX, + y: tableElemY, + } = (tableDOMElement as HTMLTableElement).getBoundingClientRect() + + const { left: editorElemLeft, y: editorElemY } = anchorElem.getBoundingClientRect() + + if (hoveredRowNode) { + setShownColumn(false) + setShownRow(true) + setPosition({ + height: BUTTON_WIDTH_PX, + left: tableElemX - editorElemLeft, + top: tableElemBottom - editorElemY + 5, + width: tableElemWidth, + }) + } else if (hoveredColumnNode) { + setShownColumn(true) + setShownRow(false) + setPosition({ + height: tableElemHeight, + left: tableElemRight - editorElemLeft + 5, + top: tableElemY - editorElemY, + width: BUTTON_WIDTH_PX, + }) + } + } + }, + 50, + 250, + ) + + useEffect(() => { + if (!shouldListenMouseMove) { + return + } + + document.addEventListener('mousemove', debouncedOnMouseMove) + + return () => { + setShownRow(false) + setShownColumn(false) + + document.removeEventListener('mousemove', debouncedOnMouseMove) + } + }, [shouldListenMouseMove, debouncedOnMouseMove]) + + useEffect(() => { + return mergeRegister( + editor.registerMutationListener( + TableNode, + (mutations) => { + editor.getEditorState().read(() => { + for (const [key, type] of mutations) { + switch (type) { + case 'created': + codeSetRef.current.add(key) + setShouldListenMouseMove(codeSetRef.current.size > 0) + break + + case 'destroyed': + codeSetRef.current.delete(key) + setShouldListenMouseMove(codeSetRef.current.size > 0) + break + + default: + break + } + } + }) + }, + { skipInitialization: false }, + ), + ) + }, [editor]) + + const insertAction = (insertRow: boolean) => { + editor.update(() => { + if (tableDOMNodeRef.current) { + const maybeTableNode = $getNearestNodeFromDOMNode(tableDOMNodeRef.current) + maybeTableNode?.selectEnd() + if (insertRow) { + $insertTableRow__EXPERIMENTAL() + setShownRow(false) + } else { + $insertTableColumn__EXPERIMENTAL() + setShownColumn(false) + } + } + }) + } + + return ( + <> + {isShownRow && ( +
} - placeholder={

{t('lexical:general:placeholder')}

} /> + const { t } = useTranslation<{}, string>() + + return ( + {t('lexical:general:placeholder')}

} + /> + ) } diff --git a/packages/richtext-lexical/src/populateGraphQL/defaultValue.ts b/packages/richtext-lexical/src/populateGraphQL/defaultValue.ts index 57a98f00a..7e8d7010f 100644 --- a/packages/richtext-lexical/src/populateGraphQL/defaultValue.ts +++ b/packages/richtext-lexical/src/populateGraphQL/defaultValue.ts @@ -21,6 +21,7 @@ export const defaultRichTextValue: SerializedEditorState = { format: '', indent: 0, textFormat: 0, + textStyle: '', version: 1, } as SerializedParagraphNode, ], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b25574077..9357d66ce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1177,35 +1177,35 @@ importers: specifier: 2.0.0-beta.0 version: 2.0.0-beta.0(react-dom@19.0.0-rc-fb9a90fa48-20240614)(react@19.0.0-rc-fb9a90fa48-20240614) '@lexical/headless': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@lexical/link': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@lexical/list': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@lexical/mark': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@lexical/markdown': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@lexical/react': - specifier: 0.16.1 - version: 0.16.1(react-dom@19.0.0-rc-fb9a90fa48-20240614)(react@19.0.0-rc-fb9a90fa48-20240614)(yjs@13.6.18) + specifier: 0.17.0 + version: 0.17.0(react-dom@19.0.0-rc-fb9a90fa48-20240614)(react@19.0.0-rc-fb9a90fa48-20240614)(yjs@13.6.18) '@lexical/rich-text': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@lexical/selection': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@lexical/table': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@lexical/utils': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@types/uuid': specifier: 10.0.0 version: 10.0.0 @@ -1216,8 +1216,8 @@ importers: specifier: 2.0.3 version: 2.0.3 lexical: - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 react: specifier: ^19.0.0-rc-6230622a1a-20240610 version: 19.0.0-rc-fb9a90fa48-20240614 @@ -1232,8 +1232,8 @@ importers: version: 10.0.0 devDependencies: '@lexical/eslint-plugin': - specifier: ' 0.16.1' - version: 0.16.1(eslint@9.6.0) + specifier: 0.17.0 + version: 0.17.0(eslint@9.6.0) '@payloadcms/eslint-config': specifier: workspace:* version: link:../eslint-config @@ -1555,11 +1555,11 @@ importers: specifier: ^3.525.0 version: 3.614.0 '@lexical/headless': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@lexical/markdown': - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 '@payloadcms/db-mongodb': specifier: workspace:* version: link:../packages/db-mongodb @@ -1690,8 +1690,8 @@ importers: specifier: 4.0.0 version: 4.0.0 lexical: - specifier: 0.16.1 - version: 0.16.1 + specifier: 0.17.0 + version: 0.17.0 payload: specifier: workspace:* version: link:../packages/payload @@ -5693,154 +5693,154 @@ packages: resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} dev: false - /@lexical/clipboard@0.16.1: - resolution: {integrity: sha512-0dWs/SwKS5KPpuf6fUVVt9vSCl6HAqcDGhSITw/okv0rrIlXTUT6WhVsMJtXfFxTyVvwMeOecJHvQH3i/jRQtA==} + /@lexical/clipboard@0.17.0: + resolution: {integrity: sha512-wYtC6VJhuSxUZc69VTU+vBgzB4HQqhve2hLrr3v+3tR2aimx3KnKphCCP1TexCntxpEnOTPXafEgpOW/EVQE+Q==} dependencies: - '@lexical/html': 0.16.1 - '@lexical/list': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/html': 0.17.0 + '@lexical/list': 0.17.0 + '@lexical/selection': 0.17.0 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 - /@lexical/code@0.16.1: - resolution: {integrity: sha512-pOC28rRZ2XkmI2nIJm50DbKaCJtk5D0o7r6nORYp4i0z+lxt5Sf2m82DL9ksUHJRqKy87pwJDpoWvJ2SAI0ohw==} + /@lexical/code@0.17.0: + resolution: {integrity: sha512-8zrgHzf27aYySfUVeSKw8YP/LkRlXHSwD03BKlkSZAb4HX/WC60SGmdXUhtyTIBucqe0pnuGsRYfR9euD0/tfw==} dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 prismjs: 1.29.0 - /@lexical/devtools-core@0.16.1(react-dom@19.0.0-rc-fb9a90fa48-20240614)(react@19.0.0-rc-fb9a90fa48-20240614): - resolution: {integrity: sha512-8CvGERGL7ySDVGLU+YPeq+JupIXsOFlXa3EuJ88koLKqXxYenwMleZgGqayFp6lCP78xqPKnATVeoOZUt/NabQ==} + /@lexical/devtools-core@0.17.0(react-dom@19.0.0-rc-fb9a90fa48-20240614)(react@19.0.0-rc-fb9a90fa48-20240614): + resolution: {integrity: sha512-0ftqWsoCb96oTc8Ok+uvjGAXZpsN9oc6ml3d46BdufdZyxHXC4qU3YVoPfLkgAHzH+4fQlNypu7u3Ym3dZ2rJg==} peerDependencies: react: ^19.0.0-rc-6230622a1a-20240610 react-dom: ^19.0.0-rc-6230622a1a-20240610 dependencies: - '@lexical/html': 0.16.1 - '@lexical/link': 0.16.1 - '@lexical/mark': 0.16.1 - '@lexical/table': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/html': 0.17.0 + '@lexical/link': 0.17.0 + '@lexical/mark': 0.17.0 + '@lexical/table': 0.17.0 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 react: 19.0.0-rc-fb9a90fa48-20240614 react-dom: 19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614) dev: false - /@lexical/dragon@0.16.1: - resolution: {integrity: sha512-Rvd60GIYN5kpjjBumS34EnNbBaNsoseI0AlzOdtIV302jiHPCLH0noe9kxzu9nZy+MZmjZy8Dx2zTbQT2mueRw==} + /@lexical/dragon@0.17.0: + resolution: {integrity: sha512-XSsrHVwhjBIVF9VN9MFm6Go8fquj5H/jlYuyNzemHq0tOli8NaoSovGc5q0LwXr88RPsuIt1jluazR7Q1+kxTQ==} dependencies: - lexical: 0.16.1 + lexical: 0.17.0 dev: false - /@lexical/eslint-plugin@0.16.1(eslint@9.6.0): - resolution: {integrity: sha512-C68eSFBAJ5H8vDae46l9iPUYYw6btC4ZAOr2vMdri8tuN4Aid5c2skDv/Ruiyk12SWsgzz9jHiyo5Fsa1ESLdg==} + /@lexical/eslint-plugin@0.17.0(eslint@9.6.0): + resolution: {integrity: sha512-O6RyQBXAdi90jlthWwfOuxYG4zqzWkpNwsX1V6N8t5iH80Te04LsnfG+hIB/5V8rxm8WPkTjMrqAX3UEZy5Shg==} peerDependencies: eslint: '>=7.31.0 || ^8.0.0' dependencies: eslint: 9.6.0 dev: true - /@lexical/hashtag@0.16.1: - resolution: {integrity: sha512-G+YOxStAKs3q1utqm9KR4D4lCkwIH52Rctm4RgaVTI+4lvTaybeDRGFV75P/pI/qlF7/FvAYHTYEzCjtC3GNMQ==} + /@lexical/hashtag@0.17.0: + resolution: {integrity: sha512-E6nSoz9haB6JypQtYxG5OYr36AHgam/FBMu77OWNl1KsJbkP8nInm+P22QFsNnEvs4Hk6/0FJ5g42+lTEnGmIg==} dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 dev: false - /@lexical/headless@0.16.1: - resolution: {integrity: sha512-L00TQk9vD1o7c25QMNdwD7MvkmQYP/jebG2M8GbX/3KSjHag2QB8MwcFlccSGXBhmbVm1X1Zo7z7urxY//3atw==} + /@lexical/headless@0.17.0: + resolution: {integrity: sha512-yKvXcq2F6S1lwDLcwv+bHht/al1LcFmidPT3rjISRxLX+/YjUcUT8MmvV773Du4piV4rFPbVlBPFBZfHJkDxXw==} dependencies: - lexical: 0.16.1 + lexical: 0.17.0 - /@lexical/history@0.16.1: - resolution: {integrity: sha512-WQhScx0TJeKSQAnEkRpIaWdUXqirrNrom2MxbBUc/32zEUMm9FzV7nRGknvUabEFUo7vZq6xTZpOExQJqHInQA==} + /@lexical/history@0.17.0: + resolution: {integrity: sha512-SfeUKAXf9pZpqee9rMOTt33V0J0p/AS9TZLT9Un9dU6wAaHfv6NFax1ND0JoG1a9YkTc539mufxVLNjsNRc0ag==} dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 dev: false - /@lexical/html@0.16.1: - resolution: {integrity: sha512-vbtAdCvQ3PaAqa5mFmtmrvbiAvjCu1iXBAJ0bsHqFXCF2Sba5LwHVe8dUAOTpfEZEMbiHfjul6b5fj4vNPGF2A==} + /@lexical/html@0.17.0: + resolution: {integrity: sha512-sI458CEP/j+Gd2YEo1+vTax31ZAjdq5jmRJMgSKxzKlkVYAUY9eH5u3Y3awPLwLVXJHiIopMX02GeZytibuTiw==} dependencies: - '@lexical/selection': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/selection': 0.17.0 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 - /@lexical/link@0.16.1: - resolution: {integrity: sha512-zG36gEnEqbIe6tK/MhXi7wn/XMY/zdivnPcOY5WyC3derkEezeLSSIFsC1u5UNeK5pbpNMSy4LDpLhi1Ww4Y5w==} + /@lexical/link@0.17.0: + resolution: {integrity: sha512-Kux6yvPit6y0ksPpwimv3seVrXAsggkqB6oT6oAVBaDpYuygVEwNDqg/rCTtB3mHQ4eeuU33mdK7MSXZ34bZRQ==} dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 - /@lexical/list@0.16.1: - resolution: {integrity: sha512-i9YhLAh5N6YO9dP+R1SIL9WEdCKeTiQQYVUzj84vDvX5DIBxMPUjTmMn3LXu9T+QO3h1s2L/vJusZASrl45eAw==} + /@lexical/list@0.17.0: + resolution: {integrity: sha512-anDuSUykTv+lqyCwl1m+sThrB15OKCa00Eo68/d2HQSHDD3KNWgSx709dcR17bD9oT204yOhMJbQGywuzcEyGQ==} dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 - /@lexical/mark@0.16.1: - resolution: {integrity: sha512-CZRGMLcxn5D+jzf1XnH+Z+uUugmpg1mBwTbGybCPm8UWpBrKDHkrscfMgWz62iRWz0cdVjM5+0zWpNElxFTRjQ==} + /@lexical/mark@0.17.0: + resolution: {integrity: sha512-Ynqh9KHXUcB9qLOTGC9s+bbWtawOwRStkeIeAugTqrwckyYWeDaePpyJ6IhBBJy1E1CfpiZn71NDeP+FuRjnXQ==} dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 dev: false - /@lexical/markdown@0.16.1: - resolution: {integrity: sha512-0sBLttMvfQO/hVaIqpHdvDowpgV2CoRuWo2CNwvRLZPPWvPVjL4Nkb73wmi8zAZsAOTbX2aw+g4m/+k5oJqNig==} + /@lexical/markdown@0.17.0: + resolution: {integrity: sha512-6IuJ2l5p/Ma+VBUIStIRXwTC01GEzx21gvqqywuqBUzAOiMr1oRM+DGsQgrzZrcjX+LzUlZ5ZgjuWtK8XKVAZw==} dependencies: - '@lexical/code': 0.16.1 - '@lexical/link': 0.16.1 - '@lexical/list': 0.16.1 - '@lexical/rich-text': 0.16.1 - '@lexical/text': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/code': 0.17.0 + '@lexical/link': 0.17.0 + '@lexical/list': 0.17.0 + '@lexical/rich-text': 0.17.0 + '@lexical/text': 0.17.0 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 - /@lexical/offset@0.16.1: - resolution: {integrity: sha512-/i2J04lQmFeydUZIF8tKXLQTXiJDTQ6GRnkfv1OpxU4amc0rwGa7+qAz/PuF1n58rP6InpLmSHxgY5JztXa2jw==} + /@lexical/offset@0.17.0: + resolution: {integrity: sha512-onE6SD2mIAwBLTT5v5fVBVtRg/NpQj+o10vTWJ1ImvEUERpSoCyHMTy3IMoSMuCRwuOG9C0cFEret2u+QS8Icw==} dependencies: - lexical: 0.16.1 + lexical: 0.17.0 dev: false - /@lexical/overflow@0.16.1: - resolution: {integrity: sha512-xh5YpoxwA7K4wgMQF/Sjl8sdjaxqesLCtH5ZrcMsaPlmucDIEEs+i8xxk+kDUTEY7y+3FvRxs4lGNgX8RVWkvQ==} + /@lexical/overflow@0.17.0: + resolution: {integrity: sha512-dh+nQAmeobKvZFodWyzNh1ZjX043Patk/1Lwct9XmtAGMUdXL+tB0bbguWVcDfY8OYu1CTQGfbdq2oMEJYzwsg==} dependencies: - lexical: 0.16.1 + lexical: 0.17.0 dev: false - /@lexical/plain-text@0.16.1: - resolution: {integrity: sha512-GjY4ylrBZIaAVIF8IFnmW0XGyHAuRmWA6gKB8iTTlsjgFrCHFIYC74EeJSp309O0Hflg9rRBnKoX1TYruFHVwA==} + /@lexical/plain-text@0.17.0: + resolution: {integrity: sha512-AEk+3ttbRyRi7m9UbU1CdLUtGsXh4FFZkBC12twV3U82lZHOdHocLlTutP+lcbYlGjeq6UF43NxOSGzsYEunsA==} dependencies: - '@lexical/clipboard': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/clipboard': 0.17.0 + '@lexical/selection': 0.17.0 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 dev: false - /@lexical/react@0.16.1(react-dom@19.0.0-rc-fb9a90fa48-20240614)(react@19.0.0-rc-fb9a90fa48-20240614)(yjs@13.6.18): - resolution: {integrity: sha512-SsGgLt9iKfrrMRy9lFb6ROVPUYOgv6b+mCn9Al+TLqs/gBReDBi3msA7m526nrtBUKYUnjHdQ1QXIJzuKgOxcg==} + /@lexical/react@0.17.0(react-dom@19.0.0-rc-fb9a90fa48-20240614)(react@19.0.0-rc-fb9a90fa48-20240614)(yjs@13.6.18): + resolution: {integrity: sha512-HZ3joq+5g2++2vo/6scTd60Y2bsu8ya8EUdopyudnmGZGKAcAPue9pLOlBaEpsYZ7vqTuGjiPgtEBfFzDy9rlg==} peerDependencies: react: ^19.0.0-rc-6230622a1a-20240610 react-dom: ^19.0.0-rc-6230622a1a-20240610 dependencies: - '@lexical/clipboard': 0.16.1 - '@lexical/code': 0.16.1 - '@lexical/devtools-core': 0.16.1(react-dom@19.0.0-rc-fb9a90fa48-20240614)(react@19.0.0-rc-fb9a90fa48-20240614) - '@lexical/dragon': 0.16.1 - '@lexical/hashtag': 0.16.1 - '@lexical/history': 0.16.1 - '@lexical/link': 0.16.1 - '@lexical/list': 0.16.1 - '@lexical/mark': 0.16.1 - '@lexical/markdown': 0.16.1 - '@lexical/overflow': 0.16.1 - '@lexical/plain-text': 0.16.1 - '@lexical/rich-text': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/table': 0.16.1 - '@lexical/text': 0.16.1 - '@lexical/utils': 0.16.1 - '@lexical/yjs': 0.16.1(yjs@13.6.18) - lexical: 0.16.1 + '@lexical/clipboard': 0.17.0 + '@lexical/code': 0.17.0 + '@lexical/devtools-core': 0.17.0(react-dom@19.0.0-rc-fb9a90fa48-20240614)(react@19.0.0-rc-fb9a90fa48-20240614) + '@lexical/dragon': 0.17.0 + '@lexical/hashtag': 0.17.0 + '@lexical/history': 0.17.0 + '@lexical/link': 0.17.0 + '@lexical/list': 0.17.0 + '@lexical/mark': 0.17.0 + '@lexical/markdown': 0.17.0 + '@lexical/overflow': 0.17.0 + '@lexical/plain-text': 0.17.0 + '@lexical/rich-text': 0.17.0 + '@lexical/selection': 0.17.0 + '@lexical/table': 0.17.0 + '@lexical/text': 0.17.0 + '@lexical/utils': 0.17.0 + '@lexical/yjs': 0.17.0(yjs@13.6.18) + lexical: 0.17.0 react: 19.0.0-rc-fb9a90fa48-20240614 react-dom: 19.0.0-rc-fb9a90fa48-20240614(react@19.0.0-rc-fb9a90fa48-20240614) react-error-boundary: 3.1.4(react@19.0.0-rc-fb9a90fa48-20240614) @@ -5848,45 +5848,45 @@ packages: - yjs dev: false - /@lexical/rich-text@0.16.1: - resolution: {integrity: sha512-4uEVXJur7tdSbqbmsToCW4YVm0AMh4y9LK077Yq2O9hSuA5dqpI8UbTDnxZN2D7RfahNvwlqp8eZKFB1yeiJGQ==} + /@lexical/rich-text@0.17.0: + resolution: {integrity: sha512-XJc8gQBSwppCkESQaNcGtyTaPXZaeCQDcUVpnDjDK0vM/ZZN8TErxbujwbSqA3kO2dBds9N8WxNboSwuncMBcQ==} dependencies: - '@lexical/clipboard': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/clipboard': 0.17.0 + '@lexical/selection': 0.17.0 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 - /@lexical/selection@0.16.1: - resolution: {integrity: sha512-+nK3RvXtyQvQDq7AZ46JpphmM33pwuulwiRfeXR5T9iFQTtgWOEjsAi/KKX7vGm70BxACfiSxy5QCOgBWFwVJg==} + /@lexical/selection@0.17.0: + resolution: {integrity: sha512-UTjlvyhFY/lmHtBaIaVRwYnRfO9gR4I32+PT7vHQr4v3VfcgS63YEGSgEZy3Gh1pfeJqaZATN58+jCuMAQXlWQ==} dependencies: - lexical: 0.16.1 + lexical: 0.17.0 - /@lexical/table@0.16.1: - resolution: {integrity: sha512-GWb0/MM1sVXpi1p2HWWOBldZXASMQ4c6WRNYnRmq7J/aB5N66HqQgJGKp3m66Kz4k1JjhmZfPs7F018qIBhnFQ==} + /@lexical/table@0.17.0: + resolution: {integrity: sha512-RQF7IG0rGL2/bPaPFUIMgDA3QMdDflvXSnE7Udgbj9yMqSKhYkaERVfNyoLckDUSuusGJd6XV+qum6JWn0nSNA==} dependencies: - '@lexical/utils': 0.16.1 - lexical: 0.16.1 + '@lexical/utils': 0.17.0 + lexical: 0.17.0 - /@lexical/text@0.16.1: - resolution: {integrity: sha512-Os/nKQegORTrKKN6vL3/FMVszyzyqaotlisPynvTaHTUC+yY4uyjM2hlF93i5a2ixxyiPLF9bDroxUP96TMPXg==} + /@lexical/text@0.17.0: + resolution: {integrity: sha512-kFH0V6yjW8YswmoY7vHT4zHFDflGfamuUxTPHROpdnq/JMjHeaVwtmFBdrP0gknaC8XMRXdr3EsemQ7cbOoDPA==} dependencies: - lexical: 0.16.1 + lexical: 0.17.0 - /@lexical/utils@0.16.1: - resolution: {integrity: sha512-BVyJxDQi/rIxFTDjf2zE7rMDKSuEaeJ4dybHRa/hRERt85gavGByQawSLeQlTjLaYLVsy+x7wCcqh2fNhlLf0g==} + /@lexical/utils@0.17.0: + resolution: {integrity: sha512-B/n0rRGDmdMrqi2qnprLt6SntC6jb4JItLmPl8zDDdg7/HxMdLq3F93vogeiXQJn0mlNqgiENWHvLAy5K2C2uQ==} dependencies: - '@lexical/list': 0.16.1 - '@lexical/selection': 0.16.1 - '@lexical/table': 0.16.1 - lexical: 0.16.1 + '@lexical/list': 0.17.0 + '@lexical/selection': 0.17.0 + '@lexical/table': 0.17.0 + lexical: 0.17.0 - /@lexical/yjs@0.16.1(yjs@13.6.18): - resolution: {integrity: sha512-QHw1bmzB/IypIV1tRWMH4hhwE1xX7wV+HxbzBS8oJAkoU5AYXM/kyp/sQicgqiwVfpai1Px7zatOoUDFgbyzHQ==} + /@lexical/yjs@0.17.0(yjs@13.6.18): + resolution: {integrity: sha512-xJv3frcK/jskssLbzdY4yfBaM7+LWaZD4YjYkJ/bvRDTey2w+McF+SvsJ/yBA8YF1oaL3rT+0aIQJ7rfH+AxjA==} peerDependencies: yjs: '>=13.5.22' dependencies: - '@lexical/offset': 0.16.1 - lexical: 0.16.1 + '@lexical/offset': 0.17.0 + lexical: 0.17.0 yjs: 13.6.18 dev: false @@ -12284,8 +12284,8 @@ packages: prelude-ls: 1.2.1 type-check: 0.4.0 - /lexical@0.16.1: - resolution: {integrity: sha512-+R05d3+N945OY8pTUjTqQrWoApjC+ctzvjnmNETtx9WmVAaiW0tQVG+AYLt5pDGY8dQXtd4RPorvnxBTECt9SA==} + /lexical@0.17.0: + resolution: {integrity: sha512-cCFmANO5rIf34NF0go/hxp5S3V5Z8G2Rsa1FJy50qF2WM5EJNJ/MqN75TApjfgMkfrbO6gau3X12nCqwsT7aDg==} /lib0@0.2.94: resolution: {integrity: sha512-hZ3p54jL4Wpu7IOg26uC7dnEWiMyNlUrb9KoG7+xYs45WkQwpVvKFndVq2+pqLYKe1u8Fp3+zAfZHVvTK34PvQ==} diff --git a/test/fields/payload-types.ts b/test/fields/payload-types.ts index 85031f46d..b661b4f45 100644 --- a/test/fields/payload-types.ts +++ b/test/fields/payload-types.ts @@ -594,6 +594,19 @@ export interface BlockField { blockType: 'text'; }[] | null; + blocksWithLocalizedArray?: + | { + array?: + | { + text?: string | null; + id?: string | null; + }[] + | null; + id?: string | null; + blockName?: string | null; + blockType: 'localizedArray'; + }[] + | null; blocksWithSimilarConfigs?: | ( | { diff --git a/test/package.json b/test/package.json index c59229b08..b8e3a3190 100644 --- a/test/package.json +++ b/test/package.json @@ -23,8 +23,8 @@ }, "devDependencies": { "@aws-sdk/client-s3": "^3.525.0", - "@lexical/headless": "0.16.1", - "@lexical/markdown": "0.16.1", + "@lexical/headless": "0.17.0", + "@lexical/markdown": "0.17.0", "@payloadcms/db-mongodb": "workspace:*", "@payloadcms/db-postgres": "workspace:*", "@payloadcms/db-sqlite": "workspace:*", @@ -68,7 +68,7 @@ "file-type": "17.1.6", "http-status": "1.6.2", "jwt-decode": "4.0.0", - "lexical": "0.16.1", + "lexical": "0.17.0", "payload": "workspace:*", "qs-esm": "7.0.2", "server-only": "^0.0.1",