feat(text-editor): add onFormSubmission callback#7831
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the TextEditor component API/behaviour by removing the legacy cancel/save toolbar buttons, repurposing onSave to trigger on parent form submission, and adding a second onSave argument containing HTML with inline styles for portability.
Changes:
- Removed
onCancelsupport (props, UI, locale keys, docs, and tests) and removed the legacy save button UI. - Added a
SavePluginthat listens for parent<form>submit events and callsonSave(formattedValues, htmlWithInlineStyles). - Added
generateHTMLWithInlineStylespost-processing + updated Storybook/docs/tests to reflect the newonSavesignature and behaviour.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/locales/pt-pt.ts | Removes legacy TextEditor save/cancel locale keys. |
| src/locales/locale.ts | Removes legacy TextEditor save/cancel locale keys from the locale interface. |
| src/locales/fr-fr.ts | Removes legacy TextEditor save/cancel locale keys. |
| src/locales/fr-ca.ts | Removes legacy TextEditor save/cancel locale keys. |
| src/locales/es-es.ts | Removes legacy TextEditor save/cancel locale keys. |
| src/locales/en-gb.ts | Removes legacy TextEditor save/cancel locale keys. |
| src/locales/de-de.ts | Removes legacy TextEditor save/cancel locale keys. |
| src/components/text-editor/text-editor.test.tsx | Updates unit tests for new onSave form-submit semantics and removes old cancel/save button tests. |
| src/components/text-editor/text-editor.stories.tsx | Updates Storybook OnSave to submit via a form and display inline-styled HTML output. |
| src/components/text-editor/text-editor.pw.tsx | Removes Playwright tests tied to legacy save/cancel toolbar buttons. |
| src/components/text-editor/text-editor.mdx | Updates docs for new onSave behaviour/signature and removes translation keys for legacy buttons. |
| src/components/text-editor/text-editor.component.tsx | Removes legacy deprecations + toolbar wiring and mounts new SavePlugin. |
| src/components/text-editor/text-editor-test.stories.tsx | Removes onCancel usage in test stories. |
| src/components/text-editor/components.test-pw.tsx | Removes Playwright fixture components that relied on legacy save/cancel buttons. |
| src/components/text-editor/internal/utils/interfaces.types.ts | Removes onCancel, changes onSave signature, removes SaveButtonProps. |
| src/components/text-editor/internal/utils/helpers.ts | Adds generateHTMLWithInlineStyles helper and exports it. |
| src/components/text-editor/internal/utils/helpers.test.ts | Adds tests for generateHTMLWithInlineStyles. |
| src/components/text-editor/internal/ui/Toolbar/toolbar.style.ts | Removes CommandButtons styling used by legacy buttons. |
| src/components/text-editor/internal/ui/Toolbar/toolbar.component.tsx | Removes legacy save/cancel button rendering. |
| src/components/text-editor/internal/ui/Toolbar/buttons/save.component.tsx | Deletes legacy Save button component. |
| src/components/text-editor/internal/ui/Toolbar/buttons/index.ts | Removes Save button export. |
| src/components/text-editor/internal/ui/Toolbar/buttons/buttons.test.tsx | Deletes tests specific to legacy Save button behaviour. |
| src/components/text-editor/internal/ui/ContentEditor/content-editor.test.tsx | Adds coverage for a blur-related branch. |
| src/components/text-editor/internal/plugins/index.ts | Exports new SavePlugin. |
| src/components/text-editor/internal/plugins/SavePlugin/save.plugin.tsx | Implements new form-submit listener logic that calls onSave with two args. |
| src/components/text-editor/internal/plugins/SavePlugin/save.plugin.test.tsx | Adds unit tests for SavePlugin event wiring and callback behaviour. |
| src/components/text-editor/internal/plugins/SavePlugin/index.ts | Barrel exports for SavePlugin. |
| skills/carbon-react/components/text-editor.md | Updates generated/skills documentation for new onSave behaviour and signature. |
Comments suppressed due to low confidence (1)
src/components/text-editor/text-editor.pw.tsx:510
- Playwright coverage for the new onSave behaviour appears to have been removed without replacement. Since onSave now fires on parent form submission (and must ignore internal dialog forms), it would be good to add/update a Playwright test that wraps TextEditor in a form with a submit button and asserts the callback is triggered (and not triggered by the hyperlink dialog save).
test.describe("Functionality tests", () => {
test.describe("onBlur", () => {
test("fires when the editor loses focus", async ({ mount, page }) => {
let currentValue = false;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| import Logger from "../../../../__internal__/utils/logger"; | ||
|
|
||
| const fontFamily = "font-family: 'Sage UI', sans-serif;"; | ||
| const linkStyles = `color: #007e45ff; cursor: pointer; text-decoration: underline; ${fontFamily}`; |
There was a problem hiding this comment.
The new inline link color uses 8-digit hex (#007e45ff). Because this HTML output is explicitly intended to be portable for email/external consumers, prefer a more broadly supported representation (e.g. 6-digit hex #007e45 or rgb/rgba), ideally sourced from an existing theme/token rather than a hard-coded literal.
| const linkStyles = `color: #007e45ff; cursor: pointer; text-decoration: underline; ${fontFamily}`; | |
| const linkStyles = `color: #007e45; cursor: pointer; text-decoration: underline; ${fontFamily}`; |
|
|
||
| If the `onSave` property is not provided, the `Save` button will not be displayed. | ||
| 1. **`formattedValues`**: An object containing the serialized editor content: | ||
| - `htmlString`: A HTML representation of the editor content, as a string. |
There was a problem hiding this comment.
In this onSave docs section, "A HTML representation" is grammatically incorrect; it should be "An HTML representation" (also helps keep wording consistent for public docs).
| - `htmlString`: A HTML representation of the editor content, as a string. | |
| - `htmlString`: An HTML representation of the editor content, as a string. |
| To handle the content of the editor when a form containing the editor is submitted, you can set the `onSave` property to a function. The callback function returns two parameters: | ||
|
|
||
| 1. **`formattedValues`**: An object containing the serialized editor content: | ||
| - `htmlString`: A HTML representation of the editor content, as a string. |
There was a problem hiding this comment.
The onSave docs here say "A HTML representation"; this should be "An HTML representation".
| - `htmlString`: A HTML representation of the editor content, as a string. | |
| - `htmlString`: An HTML representation of the editor content, as a string. |
| * <TextEditor labelText="..." onSave={(values, html) => console.log(values, html)}> | ||
| * <SavePlugin onSave={handleSave} /> | ||
| * </TextEditor> |
There was a problem hiding this comment.
The JSDoc @example here suggests consumers render as a child of , but SavePlugin is an internal plugin that TextEditor mounts itself. This example is misleading; either remove it or replace it with an example that shows TextEditor inside a parent
| * <TextEditor labelText="..." onSave={(values, html) => console.log(values, html)}> | |
| * <SavePlugin onSave={handleSave} /> | |
| * </TextEditor> | |
| * <form onSubmit={handleSubmit}> | |
| * <TextEditor | |
| * labelText="..." | |
| * onSave={(values, html) => { | |
| * console.log(values, html); | |
| * }} | |
| * /> | |
| * </form> |
a762b63 to
f8235e6
Compare
|
|
||
| The callback receives an object containing: | ||
|
|
||
| 1. **`formattedValues`**: An object containing the serialized editor content: |
There was a problem hiding this comment.
suggestion: use British English
| 1. **`formattedValues`**: An object containing the serialized editor content: | |
| 1. **`formattedValues`**: An object containing the serialised editor content: |
| return form; | ||
| }; | ||
|
|
||
| describe("FormSubmissionPlugin", () => { |
There was a problem hiding this comment.
comment(non-blocking): describe and it blocks should be written in continuous prose
| }); | ||
| }); | ||
|
|
||
| describe("generateHTMLWithInlineStyles", () => { |
There was a problem hiding this comment.
comment(non-blocking): describe and it blocks should be written in continuous prose
| }; | ||
|
|
||
| /** | ||
| * Post-processes HTML serialized from the Lexical editor, converting class-based |
There was a problem hiding this comment.
suggestion: use British English
| * Post-processes HTML serialized from the Lexical editor, converting class-based | |
| * Post-processes HTML serialised from the Lexical editor, converting class-based |
|
|
||
| The callback receives an object containing: | ||
|
|
||
| 1. **`formattedValues`**: An object containing the serialized editor content: |
There was a problem hiding this comment.
suggestion: use British English
| 1. **`formattedValues`**: An object containing the serialized editor content: | |
| 1. **`formattedValues`**: An object containing the serialised editor content: |
Adds a new onFormSubmission callback that is triggered when the parent form is submitted. This callback provides access to the editor's content in multiple formats, including htmlStringWithInlineStyles - HTML content with Lexical class names converted to inline styles. This is a separate callback from onSave and is designed specifically for form submission workflows. The HTML with inline styles is useful when editor content needs to be used in contexts where stylesheets are not available, such as PDF generation or email templates. fix #7737
a3b6850
|
🎉 This PR is included in version 158.39.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
fix #7737
Proposed behaviour
Adds a new
onFormSubmissioncallback that is triggered when the parent form is submitted. This callback provides access to the editor's content in multiple formats, including htmlStringWithInlineStyles - HTML content with Lexical class names converted to inline styles.This is a separate callback from
onSaveand is designed specifically for form submission workflows. The HTML with inline styles is useful when editor content needs to be used in contexts where stylesheets are not available, such as PDF generation or email templates.Current behaviour
Currently, there is no
onFormSubmissioncallback, also there is no mechanism for consumers to access inline HTML from the editor with inline css for external consumption.Checklist
d.tsfile added or updated if requiredQA
Additional context
Testing instructions
Trigger the
onFormSubmissionbehaviour on theonFormSubmissionstory withinTextEditor, assert the inline styles is correct