From 91a04f9d0902a41b5572b5319437c350db990e54 Mon Sep 17 00:00:00 2001
From: Alessio Gravili
Date: Thu, 22 Aug 2024 17:35:25 -0400
Subject: [PATCH 1/2] feat(richtext-lexical): improve upload node types
---
.../features/upload/client/component/index.tsx | 6 ++++++
.../features/upload/server/nodes/UploadNode.tsx | 16 +++++++++-------
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/packages/richtext-lexical/src/features/upload/client/component/index.tsx b/packages/richtext-lexical/src/features/upload/client/component/index.tsx
index 0593a2037ce..8e9265f8858 100644
--- a/packages/richtext-lexical/src/features/upload/client/component/index.tsx
+++ b/packages/richtext-lexical/src/features/upload/client/component/index.tsx
@@ -86,6 +86,12 @@ const Component: React.FC = (props) => {
depth: editDepth,
})
+ if (typeof value === 'object') {
+ throw new Error(
+ 'Upload value should be a string or number. The Lexical Upload component should not receive the populated value object.',
+ )
+ }
+
const [DocumentDrawer, DocumentDrawerToggler, { closeDrawer }] = useDocumentDrawer({
id: value,
collectionSlug: relatedCollection.slug,
diff --git a/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx b/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx
index a425d109bb8..07cde2ca561 100644
--- a/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx
+++ b/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx
@@ -8,7 +8,7 @@ import type {
NodeKey,
Spread,
} from 'lexical'
-import type { CollectionSlug, JsonObject } from 'payload'
+import type { CollectionSlug, DataFromCollectionSlug, JsonObject } from 'payload'
import type { JSX } from 'react'
import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js'
@@ -16,12 +16,14 @@ import ObjectID from 'bson-objectid'
import { $applyNodeReplacement } from 'lexical'
import * as React from 'react'
-export type UploadData = {
- fields: JsonObject
- id: string
- relationTo: CollectionSlug
- value: number | string
-}
+export type UploadData = {
+ [TCollectionSlug in CollectionSlug]: {
+ fields: TUploadExtraFieldsData
+ id: string
+ relationTo: TCollectionSlug
+ value: DataFromCollectionSlug | number | string
+ }
+}[CollectionSlug]
export function isGoogleDocCheckboxImg(img: HTMLImageElement): boolean {
return (
From 78bbed64b0827c7680a931a4bcc3d5bee41bccd2 Mon Sep 17 00:00:00 2001
From: Alessio Gravili
Date: Thu, 22 Aug 2024 17:46:40 -0400
Subject: [PATCH 2/2] feat(richtext-lexical): improve relationship node types
---
.../client/components/RelationshipComponent.tsx | 16 +++++++++++-----
.../server/nodes/RelationshipNode.tsx | 10 ++++++----
.../features/upload/client/component/index.tsx | 12 ++++++------
.../features/upload/server/nodes/UploadNode.tsx | 2 ++
4 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/packages/richtext-lexical/src/features/relationship/client/components/RelationshipComponent.tsx b/packages/richtext-lexical/src/features/relationship/client/components/RelationshipComponent.tsx
index 53f0d026c41..9c4bbee54de 100644
--- a/packages/richtext-lexical/src/features/relationship/client/components/RelationshipComponent.tsx
+++ b/packages/richtext-lexical/src/features/relationship/client/components/RelationshipComponent.tsx
@@ -39,10 +39,16 @@ type Props = {
const Component: React.FC = (props) => {
const {
- data: { relationTo, value: id },
+ data: { relationTo, value },
nodeKey,
} = props
+ if (typeof value === 'object') {
+ throw new Error(
+ 'Relationship value should be a string or number. The Lexical Relationship component should not receive the populated value object.',
+ )
+ }
+
const relationshipElemRef = useRef(null)
const [editor] = useLexicalComposerContext()
@@ -63,12 +69,12 @@ const Component: React.FC = (props) => {
const { i18n, t } = useTranslation()
const [cacheBust, dispatchCacheBust] = useReducer((state) => state + 1, 0)
const [{ data }, { setParams }] = usePayloadAPI(
- `${serverURL}${api}/${relatedCollection.slug}/${id}`,
+ `${serverURL}${api}/${relatedCollection.slug}/${value}`,
{ initialParams },
)
const [DocumentDrawer, DocumentDrawerToggler, { closeDrawer }] = useDocumentDrawer({
- id,
+ id: value,
collectionSlug: relatedCollection.slug,
})
@@ -153,7 +159,7 @@ const Component: React.FC = (props) => {
- {data ? data[relatedCollection?.admin?.useAsTitle || 'id'] : id}
+ {data ? data[relatedCollection?.admin?.useAsTitle || 'id'] : value}
@@ -188,7 +194,7 @@ const Component: React.FC = (props) => {
)}
- {id && }
+ {!!value && }
)
}
diff --git a/packages/richtext-lexical/src/features/relationship/server/nodes/RelationshipNode.tsx b/packages/richtext-lexical/src/features/relationship/server/nodes/RelationshipNode.tsx
index 56db6c9978a..79ed8b6ec9f 100644
--- a/packages/richtext-lexical/src/features/relationship/server/nodes/RelationshipNode.tsx
+++ b/packages/richtext-lexical/src/features/relationship/server/nodes/RelationshipNode.tsx
@@ -10,15 +10,17 @@ import type {
NodeKey,
Spread,
} from 'lexical'
-import type { CollectionSlug } from 'payload'
+import type { CollectionSlug, DataFromCollectionSlug } from 'payload'
import type { JSX } from 'react'
import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode.js'
export type RelationshipData = {
- relationTo: CollectionSlug
- value: number | string
-}
+ [TCollectionSlug in CollectionSlug]: {
+ relationTo: TCollectionSlug
+ value: DataFromCollectionSlug | number | string
+ }
+}[CollectionSlug]
export type SerializedRelationshipNode = {
children?: never // required so that our typed editor state doesn't automatically add children
diff --git a/packages/richtext-lexical/src/features/upload/client/component/index.tsx b/packages/richtext-lexical/src/features/upload/client/component/index.tsx
index 8e9265f8858..6650e5cc6f2 100644
--- a/packages/richtext-lexical/src/features/upload/client/component/index.tsx
+++ b/packages/richtext-lexical/src/features/upload/client/component/index.tsx
@@ -57,6 +57,12 @@ const Component: React.FC = (props) => {
nodeKey,
} = props
+ if (typeof value === 'object') {
+ throw new Error(
+ 'Upload value should be a string or number. The Lexical Upload component should not receive the populated value object.',
+ )
+ }
+
const {
config: {
collections,
@@ -86,12 +92,6 @@ const Component: React.FC = (props) => {
depth: editDepth,
})
- if (typeof value === 'object') {
- throw new Error(
- 'Upload value should be a string or number. The Lexical Upload component should not receive the populated value object.',
- )
- }
-
const [DocumentDrawer, DocumentDrawerToggler, { closeDrawer }] = useDocumentDrawer({
id: value,
collectionSlug: relatedCollection.slug,
diff --git a/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx b/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx
index 07cde2ca561..a3cb8ce3948 100644
--- a/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx
+++ b/packages/richtext-lexical/src/features/upload/server/nodes/UploadNode.tsx
@@ -19,8 +19,10 @@ import * as React from 'react'
export type UploadData = {
[TCollectionSlug in CollectionSlug]: {
fields: TUploadExtraFieldsData
+ // Every lexical node that has sub-fields needs to have a unique ID. This is the ID of this upload node, not the ID of the linked upload document
id: string
relationTo: TCollectionSlug
+ // Value can be just the document ID, or the full, populated document
value: DataFromCollectionSlug | number | string
}
}[CollectionSlug]