feat(richtext-lexical)!: upgrade lexical from 0.17.0 to 0.18.0, make tables more reliable (#8444)

This PR

- Introduces multiline markdown transformers / mdx support
- Introduce `shouldMergeAdjacentLines` option in
`$convertFromMarkdownString`. If true, merges adjacent lines as per
commonmark spec. This would allow to close:
https://github.com/payloadcms/payload/issues/8049
- Many new features and bug fixes!
- Ports over changes from the lexical playground. Most notably:
  - add support for enabling table row stripping
  - make table resizing & table cell selection more reliable

**BREAKING**: This upgrades lexical from 0.17.0 to 0.18.0. If you have
any lexical packages installed in your project, please update them
accordingly. Additionally, if you depend on the lexical APIs, please
consult their changelog, as lexical may introduce breaking changes:
https://github.com/facebook/lexical/releases/tag/v0.18.0

---------

Co-authored-by: Alessio Gravili <alessio@gravili.de>
This commit is contained in:
Germán Jabloñski
2024-09-28 14:10:44 -03:00
committed by GitHub
parent 613d3b090e
commit 8b44676b0d
16 changed files with 317 additions and 338 deletions

View File

@@ -99,7 +99,7 @@
"prettier --write",
"eslint --cache --fix"
],
"templates/website/**/*": "sh -c \"cd templates/website; pnpm install --ignore-workspace; pnpm run lint --fix\"",
"templates/website/**/*": "sh -c \"cd templates/website; pnpm install --no-frozen-lockfile --ignore-workspace; pnpm run lint --fix\"",
"tsconfig.json": "node scripts/reset-tsconfig.js"
},
"devDependencies": {

View File

@@ -52,22 +52,22 @@
"translateNewKeys": "node --no-deprecation --import @swc-node/register/esm-register scripts/translateNewKeys.ts"
},
"dependencies": {
"@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",
"@lexical/headless": "0.18.0",
"@lexical/link": "0.18.0",
"@lexical/list": "0.18.0",
"@lexical/mark": "0.18.0",
"@lexical/markdown": "0.18.0",
"@lexical/react": "0.18.0",
"@lexical/rich-text": "0.18.0",
"@lexical/selection": "0.18.0",
"@lexical/utils": "0.18.0",
"@payloadcms/translations": "workspace:*",
"@payloadcms/ui": "workspace:*",
"@types/uuid": "10.0.0",
"bson-objectid": "2.0.4",
"dequal": "2.0.3",
"escape-html": "1.0.3",
"lexical": "0.17.0",
"lexical": "0.18.0",
"react-error-boundary": "4.0.13",
"uuid": "10.0.0"
},
@@ -77,7 +77,7 @@
"@babel/preset-env": "^7.24.5",
"@babel/preset-react": "^7.24.1",
"@babel/preset-typescript": "^7.24.1",
"@lexical/eslint-plugin": "0.17.0",
"@lexical/eslint-plugin": "0.18.0",
"@payloadcms/eslint-config": "workspace:*",
"@types/escape-html": "1.0.4",
"@types/json-schema": "7.0.15",
@@ -95,18 +95,18 @@
"peerDependencies": {
"@faceless-ui/modal": "3.0.0-beta.2",
"@faceless-ui/scroll-info": "2.0.0-beta.0",
"@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",
"@lexical/headless": "0.18.0",
"@lexical/link": "0.18.0",
"@lexical/list": "0.18.0",
"@lexical/mark": "0.18.0",
"@lexical/markdown": "0.18.0",
"@lexical/react": "0.18.0",
"@lexical/rich-text": "0.18.0",
"@lexical/selection": "0.18.0",
"@lexical/table": "0.18.0",
"@lexical/utils": "0.18.0",
"@payloadcms/next": "workspace:*",
"lexical": "0.17.0",
"lexical": "0.18.0",
"payload": "workspace:*",
"react": "^19.0.0 || ^19.0.0-rc-5dcb0097-20240918",
"react-dom": "^19.0.0 || ^19.0.0-rc-5dcb0097-20240918"

View File

@@ -56,17 +56,20 @@ export const InlineBlockComponent: React.FC<Props> = (props) => {
const $onDelete = useCallback(
(event: KeyboardEvent) => {
if (isSelected && $isNodeSelection($getSelection())) {
const deleteSelection = $getSelection()
if (isSelected && $isNodeSelection(deleteSelection)) {
event.preventDefault()
const node = $getNodeByKey(nodeKey)
if ($isInlineBlockNode(node)) {
node.remove()
return true
}
editor.update(() => {
deleteSelection.getNodes().forEach((node) => {
if ($isInlineBlockNode(node)) {
node.remove()
}
})
})
}
return false
},
[isSelected, nodeKey],
[editor, isSelected],
)
const onClick = useCallback(
(payload: MouseEvent) => {

View File

@@ -58,47 +58,6 @@ function computeSelectionCount(selection: TableSelection): {
}
}
// This is important when merging cells as there is no good way to re-merge weird shapes (a result
// of selecting merged cells and non-merged)
function isTableSelectionRectangular(selection: TableSelection): boolean {
const nodes = selection.getNodes()
const currentRows: Array<number> = []
let currentRow: null | TableRowNode = null
let expectedColumns: null | number = null
let currentColumns = 0
for (let i = 0; i < nodes.length; i++) {
const node = nodes[i]
if ($isTableCellNode(node)) {
const row = node.getParentOrThrow()
if (!$isTableRowNode(row)) {
throw new Error('Expected CellNode to have a RowNode parent')
}
if (currentRow !== row) {
if (expectedColumns !== null && currentColumns !== expectedColumns) {
return false
}
if (currentRow !== null) {
expectedColumns = currentColumns
}
currentRow = row
currentColumns = 0
}
const colSpan = node.__colSpan
for (let j = 0; j < colSpan; j++) {
if (currentRows[currentColumns + j] === undefined) {
currentRows[currentColumns + j] = 0
}
currentRows[currentColumns + j] += node.__rowSpan
}
currentColumns += colSpan
}
}
return (
(expectedColumns === null || currentColumns === expectedColumns) &&
currentRows.every((v) => v === currentRows[0])
)
}
function $canUnmerge(): boolean {
const selection = $getSelection()
if (
@@ -183,10 +142,8 @@ function TableActionMenu({
if ($isTableSelection(selection)) {
const currentSelectionCounts = computeSelectionCount(selection)
updateSelectionCounts(computeSelectionCount(selection))
setCanMergeCells(
isTableSelectionRectangular(selection) &&
(currentSelectionCounts.columns > 1 || currentSelectionCounts.rows > 1),
)
setCanMergeCells(currentSelectionCounts.columns > 1 || currentSelectionCounts.rows > 1)
}
// Unmerge cell
setCanUnmergeCell($canUnmerge())
@@ -252,9 +209,9 @@ function TableActionMenu({
throw new Error('Expected to find tableElement in DOM')
}
const tableSelection = getTableObserverFromTableElement(tableElement)
if (tableSelection !== null) {
tableSelection.clearHighlight()
const tableObserver = getTableObserverFromTableElement(tableElement)
if (tableObserver !== null) {
tableObserver.clearHighlight()
}
tableNode.markDirty()
@@ -374,12 +331,13 @@ function TableActionMenu({
throw new Error('Expected table row')
}
const newStyle = tableCellNode.getHeaderStyles() ^ TableCellHeaderStates.ROW
tableRow.getChildren().forEach((tableCell) => {
if (!$isTableCellNode(tableCell)) {
throw new Error('Expected table cell')
}
tableCell.toggleHeaderStyle(TableCellHeaderStates.ROW)
tableCell.setHeaderStyles(newStyle, TableCellHeaderStates.ROW)
})
clearTableSelection()
@@ -400,6 +358,7 @@ function TableActionMenu({
throw new Error('Expected table cell to be inside of table row.')
}
const newStyle = tableCellNode.getHeaderStyles() ^ TableCellHeaderStates.COLUMN
for (let r = 0; r < tableRows.length; r++) {
const tableRow = tableRows[r]
@@ -419,7 +378,20 @@ function TableActionMenu({
throw new Error('Expected table cell')
}
tableCell.toggleHeaderStyle(TableCellHeaderStates.COLUMN)
tableCell.setHeaderStyles(newStyle, TableCellHeaderStates.COLUMN)
}
clearTableSelection()
onClose()
})
}, [editor, tableCellNode, clearTableSelection, onClose])
const toggleRowStriping = useCallback(() => {
editor.update(() => {
if (tableCellNode.isAttached()) {
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode)
if (tableNode) {
tableNode.setRowStriping(!tableNode.getRowStriping())
}
}
clearTableSelection()
@@ -470,6 +442,14 @@ function TableActionMenu({
</React.Fragment>
) : null}
<button
className="item"
data-test-id="table-row-striping"
onClick={() => toggleRowStriping()}
type="button"
>
<span className="text">Toggle Row Striping</span>
</button>
<button
className="item"
data-test-id="table-insert-row-above"

View File

@@ -1,6 +1,6 @@
'use client'
import type { TableCellNode, TableDOMCell, TableMapType, TableMapValueType } from '@lexical/table'
import type { TableCellNode, TableDOMCell, TableMapType } from '@lexical/table'
import type { LexicalEditor } from 'lexical'
import type { JSX, MouseEventHandler } from 'react'
@@ -13,6 +13,7 @@ import {
$isTableCellNode,
$isTableRowNode,
getDOMCellFromTarget,
TableNode,
} from '@lexical/table'
import { calculateZoomLevel } from '@lexical/utils'
import { $getNearestNodeFromDOMNode } from 'lexical'
@@ -32,7 +33,7 @@ type MousePosition = {
type MouseDraggingDirection = 'bottom' | 'right'
const MIN_ROW_HEIGHT = 33
const MIN_COLUMN_WIDTH = 50
const MIN_COLUMN_WIDTH = 92
function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {
const targetRef = useRef<HTMLElement | null>(null)
@@ -59,6 +60,20 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {
return (event.buttons & 1) === 1
}
useEffect(() => {
return editor.registerNodeTransform(TableNode, (tableNode) => {
if (tableNode.getColWidths()) {
return tableNode
}
const numColumns = tableNode.getColumnCount()
const columnWidth = MIN_COLUMN_WIDTH
tableNode.setColWidths(Array(numColumns).fill(columnWidth))
return tableNode
})
}, [editor])
useEffect(() => {
const onMouseMove = (event: MouseEvent) => {
setTimeout(() => {
@@ -119,13 +134,12 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {
}
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)
rootElement?.addEventListener('mousemove', onMouseMove)
rootElement?.addEventListener('mousedown', onMouseDown)
rootElement?.addEventListener('mouseup', onMouseUp)
})
return () => {
@@ -155,7 +169,8 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode)
const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode)
const tableRowIndex =
$getTableRowIndexFromTableCellNode(tableCellNode) + tableCellNode.getRowSpan() - 1
const tableRows = tableNode.getChildren()
@@ -186,27 +201,6 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {
[activeCell, editor],
)
const getCellNodeWidth = (
cell: TableCellNode,
activeEditor: LexicalEditor,
): number | undefined => {
const width = cell.getWidth()
if (width !== undefined) {
return width
}
const domCellNode = activeEditor.getElementByKey(cell.getKey())
if (domCellNode == null) {
return undefined
}
const computedStyle = getComputedStyle(domCellNode)
return (
domCellNode.clientWidth -
parseFloat(computedStyle.paddingLeft) -
parseFloat(computedStyle.paddingRight)
)
}
const getCellNodeHeight = (
cell: TableCellNode,
activeEditor: LexicalEditor,
@@ -244,21 +238,18 @@ function TableCellResizer({ editor }: { editor: LexicalEditor }): JSX.Element {
throw new Error('TableCellResizer: Table column not found.')
}
for (let row = 0; row < tableMap.length; row++) {
const cell: TableMapValueType = tableMap[row][columnIndex]
if (
cell.startRow === row &&
(columnIndex === tableMap[row].length - 1 ||
tableMap[row][columnIndex].cell !== tableMap[row][columnIndex + 1].cell)
) {
const width = getCellNodeWidth(cell.cell, editor)
if (width === undefined) {
continue
}
const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH)
cell.cell.setWidth(newWidth)
}
const colWidths = tableNode.getColWidths()
if (!colWidths) {
return
}
const width = colWidths[columnIndex]
if (width === undefined) {
return
}
const newColWidths = [...colWidths]
const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH)
newColWidths[columnIndex] = newWidth
tableNode.setColWidths(newColWidths)
},
{ tag: 'skip-scroll-into-view' },
)

View File

@@ -8,7 +8,7 @@
overflow-y: scroll;
overflow-x: scroll;
table-layout: fixed;
width: max-content;
width: fit-content;
margin: 0 25px 30px 0;
::selection {
@@ -20,13 +20,16 @@
}
}
&__tableRowStriping tr:nth-child(even) {
background-color: var(--theme-elevation-100);
}
&__tableSelected {
outline: 2px solid rgb(60, 132, 244);
}
&__tableCell {
border: 1px solid var(--theme-elevation-200);
min-width: 75px;
vertical-align: top;
text-align: start;
padding: 6px 8px;

View File

@@ -118,7 +118,7 @@ export const TablePlugin: PluginComponent = () => {
COMMAND_PRIORITY_EDITOR,
),
)
}, [cellContext, editor, toggleModal])
}, [cellContext, drawerSlug, editor, toggleModal])
return (
<React.Fragment>

View File

@@ -6,7 +6,6 @@ import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext
import { useLexicalNodeSelection } from '@lexical/react/useLexicalNodeSelection.js'
import { addClassNamesToElement, mergeRegister, removeClassNamesFromElement } from '@lexical/utils'
import {
$getNodeByKey,
$getSelection,
$isNodeSelection,
CLICK_COMMAND,
@@ -31,17 +30,20 @@ export function HorizontalRuleComponent({ nodeKey }: { nodeKey: NodeKey }) {
const $onDelete = useCallback(
(event: KeyboardEvent) => {
if (isSelected && $isNodeSelection($getSelection())) {
const deleteSelection = $getSelection()
if (isSelected && $isNodeSelection(deleteSelection)) {
event.preventDefault()
const node = $getNodeByKey(nodeKey)
if ($isHorizontalRuleNode(node)) {
node.remove()
return true
}
editor.update(() => {
deleteSelection.getNodes().forEach((node) => {
if ($isHorizontalRuleNode(node)) {
node.remove()
}
})
})
}
return false
},
[isSelected, nodeKey],
[editor, isSelected],
)
useEffect(() => {

View File

@@ -99,18 +99,21 @@ const Component: React.FC<Props> = (props) => {
const $onDelete = useCallback(
(payload: KeyboardEvent) => {
if (isSelected && $isNodeSelection($getSelection())) {
const deleteSelection = $getSelection()
if (isSelected && $isNodeSelection(deleteSelection)) {
const event: KeyboardEvent = payload
event.preventDefault()
const node = $getNodeByKey(nodeKey!)
if ($isRelationshipNode(node)) {
node.remove()
return true
}
editor.update(() => {
deleteSelection.getNodes().forEach((node) => {
if ($isRelationshipNode(node)) {
node.remove()
}
})
})
}
return false
},
[isSelected, nodeKey],
[editor, isSelected],
)
const onClick = useCallback(
(payload: MouseEvent) => {

View File

@@ -126,17 +126,20 @@ const Component: React.FC<ElementProps> = (props) => {
const $onDelete = useCallback(
(event: KeyboardEvent) => {
if (isSelected && $isNodeSelection($getSelection())) {
const deleteSelection = $getSelection()
if (isSelected && $isNodeSelection(deleteSelection)) {
event.preventDefault()
const node = $getNodeByKey(nodeKey)
if ($isUploadNode(node)) {
node.remove()
return true
}
editor.update(() => {
deleteSelection.getNodes().forEach((node) => {
if ($isUploadNode(node)) {
node.remove()
}
})
})
}
return false
},
[isSelected, nodeKey],
[editor, isSelected],
)
useEffect(() => {

View File

@@ -61,7 +61,7 @@ export function lexicalEditor(props?: LexicalEditorProps): LexicalRichTextAdapte
'@lexical/selection',
'@lexical/utils',
],
targetVersion: '0.17.0',
targetVersion: '0.18.0',
},
],
})

View File

@@ -92,6 +92,7 @@ export const LexicalEditorTheme: EditorThemeClasses = {
tableCellSelected: 'LexicalEditorTheme__tableCellSelected',
tableCellSortedIndicator: 'LexicalEditorTheme__tableCellSortedIndicator',
tableResizeRuler: 'LexicalEditorTheme__tableCellResizeRuler',
tableRowStriping: 'LexicalEditorTheme__tableRowStriping',
tableSelected: 'LexicalEditorTheme__tableSelected',
text: {
bold: 'LexicalEditorTheme__textBold',

View File

@@ -1,11 +1,2 @@
'use client'
import * as facelessUIImport from '@faceless-ui/scroll-info'
const { ScrollInfoProvider } =
facelessUIImport && 'ScrollInfoProvider' in facelessUIImport
? facelessUIImport
: { ScrollInfoProvider: undefined }
const { useScrollInfo } =
facelessUIImport && 'useScrollInfo' in facelessUIImport
? facelessUIImport
: { useScrollInfo: undefined }
export { ScrollInfoProvider, useScrollInfo }
export { ScrollInfoProvider, useScrollInfo } from '@faceless-ui/scroll-info'

354
pnpm-lock.yaml generated
View File

@@ -1229,35 +1229,35 @@ importers:
specifier: 2.0.0-beta.0
version: 2.0.0-beta.0(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)
'@lexical/headless':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@lexical/link':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@lexical/list':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@lexical/mark':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@lexical/markdown':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@lexical/react':
specifier: 0.17.0
version: 0.17.0(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)(yjs@13.6.18)
specifier: 0.18.0
version: 0.18.0(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)(yjs@13.6.18)
'@lexical/rich-text':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@lexical/selection':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@lexical/table':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@lexical/utils':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@payloadcms/next':
specifier: workspace:*
version: link:../next
@@ -1280,8 +1280,8 @@ importers:
specifier: 1.0.3
version: 1.0.3
lexical:
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
react:
specifier: 19.0.0-rc-5dcb0097-20240918
version: 19.0.0-rc-5dcb0097-20240918
@@ -1311,8 +1311,8 @@ importers:
specifier: ^7.24.1
version: 7.24.7(@babel/core@7.25.2)
'@lexical/eslint-plugin':
specifier: 0.17.0
version: 0.17.0(eslint@9.9.1(jiti@1.21.6))
specifier: 0.18.0
version: 0.18.0(eslint@9.9.1(jiti@1.21.6))
'@payloadcms/eslint-config':
specifier: workspace:*
version: link:../eslint-config
@@ -1643,11 +1643,11 @@ importers:
specifier: ^3.614.0
version: 3.629.0
'@lexical/headless':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@lexical/markdown':
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
'@payloadcms/db-mongodb':
specifier: workspace:*
version: link:../packages/db-mongodb
@@ -1781,8 +1781,8 @@ importers:
specifier: 4.0.0
version: 4.0.0
lexical:
specifier: 0.17.0
version: 0.17.0
specifier: 0.18.0
version: 0.18.0
next:
specifier: 15.0.0-canary.160
version: 15.0.0-canary.160(@playwright/test@1.46.0)(babel-plugin-macros@3.1.0)(babel-plugin-react-compiler@0.0.0-experimental-24ec0eb-20240918)(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)(sass@1.77.4)
@@ -3594,82 +3594,82 @@ packages:
'@juggle/resize-observer@3.4.0':
resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
'@lexical/clipboard@0.17.0':
resolution: {integrity: sha512-wYtC6VJhuSxUZc69VTU+vBgzB4HQqhve2hLrr3v+3tR2aimx3KnKphCCP1TexCntxpEnOTPXafEgpOW/EVQE+Q==}
'@lexical/clipboard@0.18.0':
resolution: {integrity: sha512-ybc+hx14wj0n2ZjdOkLcZ02MRB3UprXjpLDXlByFIuVcZpUxVcp3NzA0UBPOKXYKvdt0bmgjnAsFWM5OSbwS0w==}
'@lexical/code@0.17.0':
resolution: {integrity: sha512-8zrgHzf27aYySfUVeSKw8YP/LkRlXHSwD03BKlkSZAb4HX/WC60SGmdXUhtyTIBucqe0pnuGsRYfR9euD0/tfw==}
'@lexical/code@0.18.0':
resolution: {integrity: sha512-VB8fRHIrB8QTqyZUvGBMVWP2tpKe3ArOjPdWAqgrS8MVFldqUhuTHcW+XJFkVxcEBYCXynNT29YRYtQhfQ+vDQ==}
'@lexical/devtools-core@0.17.0':
resolution: {integrity: sha512-0ftqWsoCb96oTc8Ok+uvjGAXZpsN9oc6ml3d46BdufdZyxHXC4qU3YVoPfLkgAHzH+4fQlNypu7u3Ym3dZ2rJg==}
'@lexical/devtools-core@0.18.0':
resolution: {integrity: sha512-gVgtEkLwGjz1frOmDpFJzDPFxPgAcC9n5ZaaZWHo5GLcptnQmkuLm1t+UInQWujXhFmcyJzfiqDaMJ8EIcb2Ww==}
peerDependencies:
react: 19.0.0-rc-5dcb0097-20240918
react-dom: 19.0.0-rc-5dcb0097-20240918
'@lexical/dragon@0.17.0':
resolution: {integrity: sha512-XSsrHVwhjBIVF9VN9MFm6Go8fquj5H/jlYuyNzemHq0tOli8NaoSovGc5q0LwXr88RPsuIt1jluazR7Q1+kxTQ==}
'@lexical/dragon@0.18.0':
resolution: {integrity: sha512-toD/y2/TgtG+eFVKXf65kDk/Mv02FwgmcGH18nyAabZnO1TLBaMYPkGFdTTZ8hVmQxqIu9nZuLWUbdIBMs8UWw==}
'@lexical/eslint-plugin@0.17.0':
resolution: {integrity: sha512-O6RyQBXAdi90jlthWwfOuxYG4zqzWkpNwsX1V6N8t5iH80Te04LsnfG+hIB/5V8rxm8WPkTjMrqAX3UEZy5Shg==}
'@lexical/eslint-plugin@0.18.0':
resolution: {integrity: sha512-i9tveFKOq6Bk5CFt7qoPJlxG16bbLApxfXevvs+PDfxiNCCTkcV/DB85rGAs6LMM0FMyEbIYbmaWpq0wOZ3FSA==}
peerDependencies:
eslint: '>=7.31.0 || ^8.0.0'
'@lexical/hashtag@0.17.0':
resolution: {integrity: sha512-E6nSoz9haB6JypQtYxG5OYr36AHgam/FBMu77OWNl1KsJbkP8nInm+P22QFsNnEvs4Hk6/0FJ5g42+lTEnGmIg==}
'@lexical/hashtag@0.18.0':
resolution: {integrity: sha512-bm+Sv7keguVYbUY0ngd+iAv2Owd3dePzdVkzkmw9Al8GPXkE5ll8fjq6Xjw2u3OVhf+9pTnesIo/AS7H+h0exw==}
'@lexical/headless@0.17.0':
resolution: {integrity: sha512-yKvXcq2F6S1lwDLcwv+bHht/al1LcFmidPT3rjISRxLX+/YjUcUT8MmvV773Du4piV4rFPbVlBPFBZfHJkDxXw==}
'@lexical/headless@0.18.0':
resolution: {integrity: sha512-GPUL7rTSYer+/g37blFbJ5MXDPCgMf1wT87Wr+IF7PdUb1D68NwePQxFBBTWMlT/wjm4YU1Qzcv5Izxldif5YQ==}
'@lexical/history@0.17.0':
resolution: {integrity: sha512-SfeUKAXf9pZpqee9rMOTt33V0J0p/AS9TZLT9Un9dU6wAaHfv6NFax1ND0JoG1a9YkTc539mufxVLNjsNRc0ag==}
'@lexical/history@0.18.0':
resolution: {integrity: sha512-c87J4ke1Sae03coElJay2Ikac/4OcA2OmhtNbt2gAi/XBtcsP4mPuz1yZfZf9XIe+weekObgjinvZekQ2AFw0g==}
'@lexical/html@0.17.0':
resolution: {integrity: sha512-sI458CEP/j+Gd2YEo1+vTax31ZAjdq5jmRJMgSKxzKlkVYAUY9eH5u3Y3awPLwLVXJHiIopMX02GeZytibuTiw==}
'@lexical/html@0.18.0':
resolution: {integrity: sha512-8lhba1DFnnobXgYm4Rk5Gr2tZedD4Gl6A/NKCt7whO/CET63vT3UnK2ggcVVgtIJG530Cv0bdZoJbJu5DauI5w==}
'@lexical/link@0.17.0':
resolution: {integrity: sha512-Kux6yvPit6y0ksPpwimv3seVrXAsggkqB6oT6oAVBaDpYuygVEwNDqg/rCTtB3mHQ4eeuU33mdK7MSXZ34bZRQ==}
'@lexical/link@0.18.0':
resolution: {integrity: sha512-GCYcbNTSTwJk0lr+GMc8nn6Meq44BZs3QL2d1B0skpZAspd8yI53sRS6HDy5P+jW5P0dzyZr/XJAU4U+7zsEEg==}
'@lexical/list@0.17.0':
resolution: {integrity: sha512-anDuSUykTv+lqyCwl1m+sThrB15OKCa00Eo68/d2HQSHDD3KNWgSx709dcR17bD9oT204yOhMJbQGywuzcEyGQ==}
'@lexical/list@0.18.0':
resolution: {integrity: sha512-DEWs9Scbg3+STZeE2O0OoG8SWnKnxQccObBzyeHRjn4GAN6JA7lgcAzfrdgp0fNWTbMM/ku876MmXKGnqhvg9Q==}
'@lexical/mark@0.17.0':
resolution: {integrity: sha512-Ynqh9KHXUcB9qLOTGC9s+bbWtawOwRStkeIeAugTqrwckyYWeDaePpyJ6IhBBJy1E1CfpiZn71NDeP+FuRjnXQ==}
'@lexical/mark@0.18.0':
resolution: {integrity: sha512-QA4YWfTP5WWnCnoH/RmfcsSZyhhd7oeFWDpfP7S8Bbmhz6kiPwGcsVr+uRQBBT56AqEX167xX2rX8JR6FiYZqA==}
'@lexical/markdown@0.17.0':
resolution: {integrity: sha512-6IuJ2l5p/Ma+VBUIStIRXwTC01GEzx21gvqqywuqBUzAOiMr1oRM+DGsQgrzZrcjX+LzUlZ5ZgjuWtK8XKVAZw==}
'@lexical/markdown@0.18.0':
resolution: {integrity: sha512-uSWwcK8eJw5C+waEhU5WoX8W+JxNZbKuFnZwsn5nsp+iQgqMj4qY6g0yJub4sq8vvh6jjl4vVXhXTq2up9aykw==}
'@lexical/offset@0.17.0':
resolution: {integrity: sha512-onE6SD2mIAwBLTT5v5fVBVtRg/NpQj+o10vTWJ1ImvEUERpSoCyHMTy3IMoSMuCRwuOG9C0cFEret2u+QS8Icw==}
'@lexical/offset@0.18.0':
resolution: {integrity: sha512-KGlboyLSxQAH5PMOlJmyvHlbYXZneVnKiHpfyBV5IUX5kuyB/eZbQEYcJP9saekfQ5Xb1FWXWmsZEo+sWtrrZA==}
'@lexical/overflow@0.17.0':
resolution: {integrity: sha512-dh+nQAmeobKvZFodWyzNh1ZjX043Patk/1Lwct9XmtAGMUdXL+tB0bbguWVcDfY8OYu1CTQGfbdq2oMEJYzwsg==}
'@lexical/overflow@0.18.0':
resolution: {integrity: sha512-3ATTwttVgZtVLq60ZUWbpbXBbpuMa3PZD5CxSP3nulviL+2I4phvacV4WUN+8wMeq+PGmuarl+cYfrFL02ii3g==}
'@lexical/plain-text@0.17.0':
resolution: {integrity: sha512-AEk+3ttbRyRi7m9UbU1CdLUtGsXh4FFZkBC12twV3U82lZHOdHocLlTutP+lcbYlGjeq6UF43NxOSGzsYEunsA==}
'@lexical/plain-text@0.18.0':
resolution: {integrity: sha512-L6yQpiwW0ZacY1oNwvRBxSuW2TZaUcveZLheJc8JzGcZoVxzII/CAbLZG8691VbNuKsbOURiNXZIsgwujKmo4Q==}
'@lexical/react@0.17.0':
resolution: {integrity: sha512-HZ3joq+5g2++2vo/6scTd60Y2bsu8ya8EUdopyudnmGZGKAcAPue9pLOlBaEpsYZ7vqTuGjiPgtEBfFzDy9rlg==}
'@lexical/react@0.18.0':
resolution: {integrity: sha512-DLvIbTsjvFIFqm+9zvAjEwuZHAbSxzZf1AGqf1lLctlL/Ran0f+8EZOv5jttELTe7xISZ2+xSXTLRfyxhNwGXQ==}
peerDependencies:
react: 19.0.0-rc-5dcb0097-20240918
react-dom: 19.0.0-rc-5dcb0097-20240918
'@lexical/rich-text@0.17.0':
resolution: {integrity: sha512-XJc8gQBSwppCkESQaNcGtyTaPXZaeCQDcUVpnDjDK0vM/ZZN8TErxbujwbSqA3kO2dBds9N8WxNboSwuncMBcQ==}
'@lexical/rich-text@0.18.0':
resolution: {integrity: sha512-xMANCB7WueMsmWK8qxik5FZN4ApyaHWHQILS9r4FTbdv/DlNepsR7Pt8kg2317xZ56NAueQLIdyyKYXG1nBrHw==}
'@lexical/selection@0.17.0':
resolution: {integrity: sha512-UTjlvyhFY/lmHtBaIaVRwYnRfO9gR4I32+PT7vHQr4v3VfcgS63YEGSgEZy3Gh1pfeJqaZATN58+jCuMAQXlWQ==}
'@lexical/selection@0.18.0':
resolution: {integrity: sha512-mJoMhmxeZLfM9K2JMYETs9u179IkHQUlgtYG5GZJHjKx2iUn+9KvJ9RVssq+Lusi7C/N42wWPGNHDPdUvFtxXg==}
'@lexical/table@0.17.0':
resolution: {integrity: sha512-RQF7IG0rGL2/bPaPFUIMgDA3QMdDflvXSnE7Udgbj9yMqSKhYkaERVfNyoLckDUSuusGJd6XV+qum6JWn0nSNA==}
'@lexical/table@0.18.0':
resolution: {integrity: sha512-TeTAnuFAAgVjm1QE8adRB3GFWN+DUUiS4vzGq+ynPRCtNdpmW27NmTkRMyxKsetUtt7nIFfj4DvLvor4RwqIpA==}
'@lexical/text@0.17.0':
resolution: {integrity: sha512-kFH0V6yjW8YswmoY7vHT4zHFDflGfamuUxTPHROpdnq/JMjHeaVwtmFBdrP0gknaC8XMRXdr3EsemQ7cbOoDPA==}
'@lexical/text@0.18.0':
resolution: {integrity: sha512-MTHSBeq3K0+lqSsP5oysBMnY4tPVhB8kAa2xBnEc3dYgXFxEEvJwZahbHNX93EPObtJkxXfUuI63Al4G3lYK8A==}
'@lexical/utils@0.17.0':
resolution: {integrity: sha512-B/n0rRGDmdMrqi2qnprLt6SntC6jb4JItLmPl8zDDdg7/HxMdLq3F93vogeiXQJn0mlNqgiENWHvLAy5K2C2uQ==}
'@lexical/utils@0.18.0':
resolution: {integrity: sha512-4s9dVpBZjqIaA/1q2GtfWFjKsv2Wqhjer0Zw2mcl1TIVN0zreXxcTKN316QppAWmSQJxVGvkWHjjaZJwl6/TSw==}
'@lexical/yjs@0.17.0':
resolution: {integrity: sha512-xJv3frcK/jskssLbzdY4yfBaM7+LWaZD4YjYkJ/bvRDTey2w+McF+SvsJ/yBA8YF1oaL3rT+0aIQJ7rfH+AxjA==}
'@lexical/yjs@0.18.0':
resolution: {integrity: sha512-rl7Rl9XIb3ygQEEHOFtACdXs3BE+UUUmdyNqB6kK9A6IRGz+w4Azp+qzt8It/t+c0oaSYHpAtcLNXg1amJz+kA==}
peerDependencies:
yjs: '>=13.5.22'
@@ -7144,8 +7144,8 @@ packages:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
lexical@0.17.0:
resolution: {integrity: sha512-cCFmANO5rIf34NF0go/hxp5S3V5Z8G2Rsa1FJy50qF2WM5EJNJ/MqN75TApjfgMkfrbO6gau3X12nCqwsT7aDg==}
lexical@0.18.0:
resolution: {integrity: sha512-3K/B0RpzjoW+Wj2E455wWXxkqxqK8UgdIiuqkOqdOsoSSo5mCkHOU6eVw7Nlmlr1MFvAMzGmz4RPn8NZaLQ2Mw==}
lib0@0.2.97:
resolution: {integrity: sha512-Q4d1ekgvufi9FiHkkL46AhecfNjznSL9MRNoJRQ76gBHS9OqU2ArfQK0FvBpuxgWeJeNI0LVgAYMIpsGeX4gYg==}
@@ -11999,157 +11999,159 @@ snapshots:
'@juggle/resize-observer@3.4.0': {}
'@lexical/clipboard@0.17.0':
'@lexical/clipboard@0.18.0':
dependencies:
'@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/html': 0.18.0
'@lexical/list': 0.18.0
'@lexical/selection': 0.18.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/code@0.17.0':
'@lexical/code@0.18.0':
dependencies:
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
prismjs: 1.29.0
'@lexical/devtools-core@0.17.0(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)':
'@lexical/devtools-core@0.18.0(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)':
dependencies:
'@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
'@lexical/html': 0.18.0
'@lexical/link': 0.18.0
'@lexical/mark': 0.18.0
'@lexical/table': 0.18.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
react: 19.0.0-rc-5dcb0097-20240918
react-dom: 19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918)
'@lexical/dragon@0.17.0':
'@lexical/dragon@0.18.0':
dependencies:
lexical: 0.17.0
lexical: 0.18.0
'@lexical/eslint-plugin@0.17.0(eslint@9.9.1(jiti@1.21.6))':
'@lexical/eslint-plugin@0.18.0(eslint@9.9.1(jiti@1.21.6))':
dependencies:
eslint: 9.9.1(jiti@1.21.6)
'@lexical/hashtag@0.17.0':
'@lexical/hashtag@0.18.0':
dependencies:
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/headless@0.17.0':
'@lexical/headless@0.18.0':
dependencies:
lexical: 0.17.0
lexical: 0.18.0
'@lexical/history@0.17.0':
'@lexical/history@0.18.0':
dependencies:
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/html@0.17.0':
'@lexical/html@0.18.0':
dependencies:
'@lexical/selection': 0.17.0
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/selection': 0.18.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/link@0.17.0':
'@lexical/link@0.18.0':
dependencies:
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/list@0.17.0':
'@lexical/list@0.18.0':
dependencies:
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/mark@0.17.0':
'@lexical/mark@0.18.0':
dependencies:
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/markdown@0.17.0':
'@lexical/markdown@0.18.0':
dependencies:
'@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/code': 0.18.0
'@lexical/link': 0.18.0
'@lexical/list': 0.18.0
'@lexical/rich-text': 0.18.0
'@lexical/text': 0.18.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/offset@0.17.0':
'@lexical/offset@0.18.0':
dependencies:
lexical: 0.17.0
lexical: 0.18.0
'@lexical/overflow@0.17.0':
'@lexical/overflow@0.18.0':
dependencies:
lexical: 0.17.0
lexical: 0.18.0
'@lexical/plain-text@0.17.0':
'@lexical/plain-text@0.18.0':
dependencies:
'@lexical/clipboard': 0.17.0
'@lexical/selection': 0.17.0
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/clipboard': 0.18.0
'@lexical/selection': 0.18.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/react@0.17.0(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)(yjs@13.6.18)':
'@lexical/react@0.18.0(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)(yjs@13.6.18)':
dependencies:
'@lexical/clipboard': 0.17.0
'@lexical/code': 0.17.0
'@lexical/devtools-core': 0.17.0(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)
'@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
'@lexical/clipboard': 0.18.0
'@lexical/code': 0.18.0
'@lexical/devtools-core': 0.18.0(react-dom@19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918))(react@19.0.0-rc-5dcb0097-20240918)
'@lexical/dragon': 0.18.0
'@lexical/hashtag': 0.18.0
'@lexical/history': 0.18.0
'@lexical/link': 0.18.0
'@lexical/list': 0.18.0
'@lexical/mark': 0.18.0
'@lexical/markdown': 0.18.0
'@lexical/overflow': 0.18.0
'@lexical/plain-text': 0.18.0
'@lexical/rich-text': 0.18.0
'@lexical/selection': 0.18.0
'@lexical/table': 0.18.0
'@lexical/text': 0.18.0
'@lexical/utils': 0.18.0
'@lexical/yjs': 0.18.0(yjs@13.6.18)
lexical: 0.18.0
react: 19.0.0-rc-5dcb0097-20240918
react-dom: 19.0.0-rc-5dcb0097-20240918(react@19.0.0-rc-5dcb0097-20240918)
react-error-boundary: 3.1.4(react@19.0.0-rc-5dcb0097-20240918)
transitivePeerDependencies:
- yjs
'@lexical/rich-text@0.17.0':
'@lexical/rich-text@0.18.0':
dependencies:
'@lexical/clipboard': 0.17.0
'@lexical/selection': 0.17.0
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/clipboard': 0.18.0
'@lexical/selection': 0.18.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/selection@0.17.0':
'@lexical/selection@0.18.0':
dependencies:
lexical: 0.17.0
lexical: 0.18.0
'@lexical/table@0.17.0':
'@lexical/table@0.18.0':
dependencies:
'@lexical/utils': 0.17.0
lexical: 0.17.0
'@lexical/clipboard': 0.18.0
'@lexical/utils': 0.18.0
lexical: 0.18.0
'@lexical/text@0.17.0':
'@lexical/text@0.18.0':
dependencies:
lexical: 0.17.0
lexical: 0.18.0
'@lexical/utils@0.17.0':
'@lexical/utils@0.18.0':
dependencies:
'@lexical/list': 0.17.0
'@lexical/selection': 0.17.0
'@lexical/table': 0.17.0
lexical: 0.17.0
'@lexical/list': 0.18.0
'@lexical/selection': 0.18.0
'@lexical/table': 0.18.0
lexical: 0.18.0
'@lexical/yjs@0.17.0(yjs@13.6.18)':
'@lexical/yjs@0.18.0(yjs@13.6.18)':
dependencies:
'@lexical/offset': 0.17.0
lexical: 0.17.0
'@lexical/offset': 0.18.0
'@lexical/selection': 0.18.0
lexical: 0.18.0
yjs: 13.6.18
'@libsql/client@0.6.2(bufferutil@4.0.8)(utf-8-validate@6.0.4)':
@@ -16409,7 +16411,7 @@ snapshots:
prelude-ls: 1.2.1
type-check: 0.4.0
lexical@0.17.0: {}
lexical@0.18.0: {}
lib0@0.2.97:
dependencies:

View File

@@ -39,7 +39,7 @@
"geist": "^1.3.0",
"graphql": "^16.8.2",
"jsonwebtoken": "9.0.2",
"lexical": "0.17.0",
"lexical": "0.18.0",
"lucide-react": "^0.378.0",
"next": "15.0.0-canary.160",
"payload": "beta",

View File

@@ -23,8 +23,8 @@
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.614.0",
"@lexical/headless": "0.17.0",
"@lexical/markdown": "0.17.0",
"@lexical/headless": "0.18.0",
"@lexical/markdown": "0.18.0",
"@payloadcms/db-mongodb": "workspace:*",
"@payloadcms/db-postgres": "workspace:*",
"@payloadcms/db-sqlite": "workspace:*",
@@ -69,7 +69,7 @@
"file-type": "19.3.0",
"http-status": "1.6.2",
"jwt-decode": "4.0.0",
"lexical": "0.17.0",
"lexical": "0.18.0",
"next": "15.0.0-canary.160",
"payload": "workspace:*",
"qs-esm": "7.0.2",