Skip to content

Commit

Permalink
fix(richtext-lexical): various issues for lexical sub-fields due to i…
Browse files Browse the repository at this point in the history
…ncorrectly generated client field schema map (#10276)

Fixes #9905,
#9660

Single lexical fields were represented file in the schema map (`path =>
field`). In the client schema map however, they were incorrectly
represented like this: `path => { fields: [field] } `
  • Loading branch information
AlessioGr authored Dec 31, 2024
1 parent 5188a9b commit 35df899
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 4 deletions.
4 changes: 4 additions & 0 deletions packages/richtext-lexical/src/field/rscEntry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export const RscEntryLexicalField: React.FC<
const path = args.path ?? (args.clientField as RichTextFieldClient).name
const schemaPath = args.schemaPath ?? path

if (!(args?.clientField as RichTextFieldClient)?.name) {
throw new Error('Initialized lexical RSC field without a field name')
}

const { clientFeatures, featureClientSchemaMap } = initLexicalFeatures({
clientFieldSchemaMap: args.clientFieldSchemaMap,
fieldSchemaMap: args.fieldSchemaMap,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
type ClientField,
type ClientFieldSchemaMap,
createClientFields,
type Field,
type FieldSchemaMap,
type Payload,
} from 'payload'
Expand Down Expand Up @@ -108,16 +109,25 @@ export const traverseFields = ({

// Now loop through them, convert each entry to a client field and add it to the client schema map
for (const [path, subField] of richTextFieldSchemaMap.entries()) {
// check if fields is the only key in the subField object
const isFieldsOnly = Object.keys(subField).length === 1 && 'fields' in subField

const clientFields = createClientFields({
defaultIDType: payload.config.db.defaultIDType,
disableAddingID: true,
fields: 'fields' in subField ? subField.fields : [subField],
fields: isFieldsOnly ? subField.fields : [subField as Field],
i18n,
importMap: payload.importMap,
})
clientSchemaMap.set(path, {
fields: clientFields,
})

clientSchemaMap.set(
path,
isFieldsOnly
? {
fields: clientFields,
}
: clientFields[0],
)
}
break
}
Expand Down
20 changes: 20 additions & 0 deletions test/fields/collections/Lexical/e2e/blocks/e2e.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1174,5 +1174,25 @@ describe('lexicalBlocks', () => {
expect(height2).toBe(74)
}).toPass()
})

test('ensure nested lexical field displays field label and description', async () => {
// Previously, we had the issue that nested lexical fields did not display the field label and description, as
// their client field configs were generated incorrectly on the server.
await page.goto('http://localhost:3000/admin/collections/LexicalInBlock?limit=10')
await page.locator('.cell-id a').first().click()
await page.waitForURL(`**/collections/LexicalInBlock/**`)

await expect(
page.locator('.lexical-block-blockInLexical .render-fields label.field-label'),
).toHaveText('My Label*')
await expect(
page.locator('.lexical-block-blockInLexical .render-fields .required'),
).toHaveText('*')
await expect(
page.locator(
'.lexical-block-blockInLexical .render-fields .field-description-lexicalInBlock',
),
).toHaveText('Some Description')
})
})
})
29 changes: 29 additions & 0 deletions test/fields/collections/LexicalInBlock/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,37 @@
import type { CollectionConfig } from 'payload'

import { BlocksFeature, lexicalEditor } from '@payloadcms/richtext-lexical'

export const LexicalInBlock: CollectionConfig = {
slug: 'LexicalInBlock',
fields: [
{
name: 'content',
type: 'richText',
editor: lexicalEditor({
features: [
BlocksFeature({
blocks: [
{
slug: 'blockInLexical',
fields: [
{
name: 'lexicalInBlock',
label: 'My Label',
type: 'richText',
required: true,
editor: lexicalEditor(),
admin: {
description: 'Some Description',
},
},
],
},
],
}),
],
}),
},
{
name: 'blocks',
type: 'blocks',
Expand Down
16 changes: 16 additions & 0 deletions test/fields/payload-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,21 @@ export interface User {
*/
export interface LexicalInBlock {
id: string;
content?: {
root: {
type: string;
children: {
type: string;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
} | null;
blocks?:
| {
lexical?: {
Expand Down Expand Up @@ -2041,6 +2056,7 @@ export interface UsersSelect<T extends boolean = true> {
* via the `definition` "LexicalInBlock_select".
*/
export interface LexicalInBlockSelect<T extends boolean = true> {
content?: T;
blocks?:
| T
| {
Expand Down
22 changes: 22 additions & 0 deletions test/fields/seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,28 @@ export const seed = async (_payload: Payload) => {
await _payload.create({
collection: 'LexicalInBlock',
data: {
content: {
root: {
children: [
{
format: '',
type: 'block',
version: 2,
fields: {
id: '6773773284be8978db7a498d',
lexicalInBlock: textToLexicalJSON({ text: 'text' }),
blockName: '',
blockType: 'blockInLexical',
},
},
],
direction: null,
format: '',
indent: 0,
type: 'root',
version: 1,
},
},
blocks: [
{
blockType: 'lexicalInBlock2',
Expand Down

0 comments on commit 35df899

Please sign in to comment.