From 8ade0dbb0216e3a9ad952fdaf501927a91306443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Jablo=C3=B1ski?= <43938777+GermanJablo@users.noreply.github.com> Date: Tue, 12 Nov 2024 14:37:52 -0300 Subject: [PATCH 1/3] change converters for heading, quote and paragraph --- .../src/utilities/lexical/converters/heading.ts | 9 +++++++-- .../src/utilities/lexical/converters/quote.ts | 8 +++++++- .../converters/html/converter/converters/paragraph.ts | 8 +++++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/packages/plugin-form-builder/src/utilities/lexical/converters/heading.ts b/packages/plugin-form-builder/src/utilities/lexical/converters/heading.ts index 681a17474a0..1ecd91218f5 100644 --- a/packages/plugin-form-builder/src/utilities/lexical/converters/heading.ts +++ b/packages/plugin-form-builder/src/utilities/lexical/converters/heading.ts @@ -13,8 +13,13 @@ export const HeadingHTMLConverter: HTMLConverter = { }, submissionData, }) - - return '<' + node?.tag + '>' + childrenText + '' + const style = [ + node.format ? `text-align: ${node.format};` : '', + node.indent > 0 ? `padding-inline-start: ${node.indent * 40}px;` : '', + ] + .filter(Boolean) + .join(' ') + return `<${node?.tag}${style ? ` style="${style}"` : ''}>${childrenText}` }, nodeTypes: ['heading'], } diff --git a/packages/plugin-form-builder/src/utilities/lexical/converters/quote.ts b/packages/plugin-form-builder/src/utilities/lexical/converters/quote.ts index 41d22d540eb..1fa73eb0099 100644 --- a/packages/plugin-form-builder/src/utilities/lexical/converters/quote.ts +++ b/packages/plugin-form-builder/src/utilities/lexical/converters/quote.ts @@ -13,8 +13,14 @@ export const QuoteHTMLConverter: HTMLConverter = { }, submissionData, }) + const style = [ + node.format ? `text-align: ${node.format};` : '', + node.indent > 0 ? `padding-inline-start: ${node.indent * 40}px;` : '', + ] + .filter(Boolean) + .join(' ') - return `
${childrenText}
` + return `${childrenText}` }, nodeTypes: ['quote'], } diff --git a/packages/richtext-lexical/src/features/converters/html/converter/converters/paragraph.ts b/packages/richtext-lexical/src/features/converters/html/converter/converters/paragraph.ts index 1f8ba4631e8..94697d1b9f3 100644 --- a/packages/richtext-lexical/src/features/converters/html/converter/converters/paragraph.ts +++ b/packages/richtext-lexical/src/features/converters/html/converter/converters/paragraph.ts @@ -30,7 +30,13 @@ export const ParagraphHTMLConverter: HTMLConverter = { req, showHiddenFields, }) - return `

${childrenText}

` + const style = [ + node.format ? `text-align: ${node.format};` : '', + node.indent > 0 ? `padding-inline-start: ${node.indent * 40}px;` : '', + ] + .filter(Boolean) + .join(' ') + return `${childrenText}

` }, nodeTypes: ['paragraph'], } From 5489cb11e8f3d02241d1f42af5ef73da62cfac58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Jablo=C3=B1ski?= <43938777+GermanJablo@users.noreply.github.com> Date: Tue, 12 Nov 2024 18:01:55 -0300 Subject: [PATCH 2/3] fix html conversion --- .../src/utilities/lexical/converters/heading.ts | 2 +- .../src/utilities/lexical/converters/quote.ts | 2 +- .../src/features/blockquote/server/index.ts | 8 +++++++- .../converters/html/converter/converters/paragraph.ts | 2 +- .../src/features/heading/server/index.ts | 9 +++++++-- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/plugin-form-builder/src/utilities/lexical/converters/heading.ts b/packages/plugin-form-builder/src/utilities/lexical/converters/heading.ts index 1ecd91218f5..c7b1a8a6e85 100644 --- a/packages/plugin-form-builder/src/utilities/lexical/converters/heading.ts +++ b/packages/plugin-form-builder/src/utilities/lexical/converters/heading.ts @@ -19,7 +19,7 @@ export const HeadingHTMLConverter: HTMLConverter = { ] .filter(Boolean) .join(' ') - return `<${node?.tag}${style ? ` style="${style}"` : ''}>${childrenText}` + return `<${node?.tag}${style ? ` style='${style}'` : ''}>${childrenText}` }, nodeTypes: ['heading'], } diff --git a/packages/plugin-form-builder/src/utilities/lexical/converters/quote.ts b/packages/plugin-form-builder/src/utilities/lexical/converters/quote.ts index 1fa73eb0099..af63bfaddb1 100644 --- a/packages/plugin-form-builder/src/utilities/lexical/converters/quote.ts +++ b/packages/plugin-form-builder/src/utilities/lexical/converters/quote.ts @@ -20,7 +20,7 @@ export const QuoteHTMLConverter: HTMLConverter = { .filter(Boolean) .join(' ') - return `${childrenText}` + return `${childrenText}` }, nodeTypes: ['quote'], } diff --git a/packages/richtext-lexical/src/features/blockquote/server/index.ts b/packages/richtext-lexical/src/features/blockquote/server/index.ts index 2248ef3c9b5..4f4ccfc1dfd 100644 --- a/packages/richtext-lexical/src/features/blockquote/server/index.ts +++ b/packages/richtext-lexical/src/features/blockquote/server/index.ts @@ -51,8 +51,14 @@ export const BlockquoteFeature = createServerFeature({ req, showHiddenFields, }) + const style = [ + node.format ? `text-align: ${node.format};` : '', + node.indent > 0 ? `padding-inline-start: ${node.indent * 40}px;` : '', + ] + .filter(Boolean) + .join(' ') - return `
${childrenText}
` + return `${childrenText}` }, nodeTypes: [QuoteNode.getType()], }, diff --git a/packages/richtext-lexical/src/features/converters/html/converter/converters/paragraph.ts b/packages/richtext-lexical/src/features/converters/html/converter/converters/paragraph.ts index 94697d1b9f3..723673aa182 100644 --- a/packages/richtext-lexical/src/features/converters/html/converter/converters/paragraph.ts +++ b/packages/richtext-lexical/src/features/converters/html/converter/converters/paragraph.ts @@ -36,7 +36,7 @@ export const ParagraphHTMLConverter: HTMLConverter = { ] .filter(Boolean) .join(' ') - return `${childrenText}

` + return `${childrenText}

` }, nodeTypes: ['paragraph'], } diff --git a/packages/richtext-lexical/src/features/heading/server/index.ts b/packages/richtext-lexical/src/features/heading/server/index.ts index 30e5cc4ff09..35ed46ada83 100644 --- a/packages/richtext-lexical/src/features/heading/server/index.ts +++ b/packages/richtext-lexical/src/features/heading/server/index.ts @@ -69,8 +69,13 @@ export const HeadingFeature = createServerFeature< req, showHiddenFields, }) - - return '<' + node?.tag + '>' + childrenText + '' + const style = [ + node.format ? `text-align: ${node.format};` : '', + node.indent > 0 ? `padding-inline-start: ${node.indent * 40}px;` : '', + ] + .filter(Boolean) + .join(' ') + return `<${node?.tag}${style ? ` style='${style}'` : ''}>${childrenText}` }, nodeTypes: [HeadingNode.getType()], }, From c1f2f0dcf289f4ebb7795d395f354945e8085744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Jablo=C3=B1ski?= <43938777+GermanJablo@users.noreply.github.com> Date: Wed, 13 Nov 2024 10:52:14 -0300 Subject: [PATCH 3/3] add test --- .../collections/Lexical/e2e/main/e2e.spec.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/fields/collections/Lexical/e2e/main/e2e.spec.ts b/test/fields/collections/Lexical/e2e/main/e2e.spec.ts index 12b4ab2de49..8793611d83d 100644 --- a/test/fields/collections/Lexical/e2e/main/e2e.spec.ts +++ b/test/fields/collections/Lexical/e2e/main/e2e.spec.ts @@ -954,6 +954,34 @@ describe('lexicalMain', () => { }) }) + // https://github.com/payloadcms/payload/issues/5146 + test('Preserve indent and text-align when converting Lexical <-> HTML', async () => { + await page.goto('http://localhost:3000/admin/collections/rich-text-fields?limit=10') + await page.getByLabel('Create new Rich Text Field').click() + await page.getByLabel('Title*').click() + await page.getByLabel('Title*').fill('Indent and Text-align') + await page.getByRole('paragraph').nth(1).click() + await context.grantPermissions(['clipboard-read', 'clipboard-write']) + const htmlContent = `

paragraph centered

Heading right

paragraph without indent

paragraph indent 1

heading indent 2

quote indent 3
` + await page.evaluate( + async ([htmlContent]) => { + const blob = new Blob([htmlContent], { type: 'text/html' }) + const clipboardItem = new ClipboardItem({ 'text/html': blob }) + await navigator.clipboard.write([clipboardItem]) + }, + [htmlContent], + ) + // eslint-disable-next-line playwright/no-conditional-in-test + const pasteKey = process.platform === 'darwin' ? 'Meta' : 'Control' + await page.keyboard.press(`${pasteKey}+v`) + await page.locator('#field-richText').click() + await page.locator('#field-richText').fill('asd') + await page.getByRole('button', { name: 'Save' }).click() + await page.getByRole('link', { name: 'API' }).click() + const htmlOutput = page.getByText(htmlContent) + await expect(htmlOutput).toBeVisible() + }) + describe('localization', () => { test.skip('ensure simple localized lexical field works', async () => { await navigateToLexicalFields(true, true)