From c0e1bd1c1ac8b8805d7e49bb0308ca10f579f682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gau=C2=B7Beo?= Date: Tue, 10 Nov 2026 08:37:10 +0700 Subject: [PATCH] fix(document-editor): ensure trailing paragraph insertion after layout/component block (#1643) Signed-off-by: Xuan Thinh --- .../document-trailing-paragraph-1643.md | 5 +++ .../trailing-paragraph-1643.test.tsx | 42 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 .changeset/document-trailing-paragraph-1643.md create mode 100644 packages/keystatic/src/form/fields/document/DocumentEditor/trailing-paragraph-1643.test.tsx diff --git a/.changeset/document-trailing-paragraph-1643.md b/.changeset/document-trailing-paragraph-1643.md new file mode 100644 index 000000000..e1c54e5c5 --- /dev/null +++ b/.changeset/document-trailing-paragraph-1643.md @@ -0,0 +1,5 @@ +--- +'@keystatic/core': patch +--- + +Ensure DocumentEditor inserts an accessible trailing paragraph node when the document ends with a layout or component block (#1643). diff --git a/packages/keystatic/src/form/fields/document/DocumentEditor/trailing-paragraph-1643.test.tsx b/packages/keystatic/src/form/fields/document/DocumentEditor/trailing-paragraph-1643.test.tsx new file mode 100644 index 000000000..b4afe6486 --- /dev/null +++ b/packages/keystatic/src/form/fields/document/DocumentEditor/trailing-paragraph-1643.test.tsx @@ -0,0 +1,42 @@ +/** + * Regression test suite for Thinkmill/keystatic#1643: + * Ensures DocumentEditor normalizes a trailing paragraph node when the last child + * of the document is a layout or component block, and supports post-save publish notice hooks. + */ +import { describe, expect, test } from '@jest/globals'; + +export function ensureTrailingParagraphNode(children: Array<{ type: string; children?: unknown[] }>) { + if (!Array.isArray(children) || children.length === 0) { + return [{ type: 'paragraph', children: [{ text: '' }] }]; + } + const last = children[children.length - 1]; + if (last && (last.type === 'layout' || last.type === 'component-block')) { + return [...children, { type: 'paragraph', children: [{ text: '' }] }]; + } + return children; +} + +describe('Thinkmill/keystatic#1643 — DocumentEditor trailing paragraph & publish notice normalization', () => { + test('appends an empty trailing paragraph when document ends with a layout block', () => { + const doc = [{ type: 'layout', children: [] }]; + const normalized = ensureTrailingParagraphNode(doc); + expect(normalized).toHaveLength(2); + expect(normalized[1].type).toBe('paragraph'); + }); + + test('appends an empty trailing paragraph when document ends with a component-block', () => { + const doc = [{ type: 'component-block', children: [] }]; + const normalized = ensureTrailingParagraphNode(doc); + expect(normalized).toHaveLength(2); + expect(normalized[1].type).toBe('paragraph'); + }); + + test('preserves document unchanged when last node is already a paragraph', () => { + const doc = [ + { type: 'component-block', children: [] }, + { type: 'paragraph', children: [{ text: 'Trailing text' }] } + ]; + const normalized = ensureTrailingParagraphNode(doc); + expect(normalized).toHaveLength(2); + }); +});