From f441a025a75cc4d5be00333eeb60e19dffaf586d Mon Sep 17 00:00:00 2001 From: Tomas Date: Tue, 16 Jun 2026 19:51:24 +0000 Subject: [PATCH] Fix nested block SDTs in layout adapter --- .../tests/src/sdt-metadata.test.ts | 49 +++++++++++++++++++ .../sdt/structured-content-block.ts | 4 ++ 2 files changed, 53 insertions(+) diff --git a/packages/layout-engine/tests/src/sdt-metadata.test.ts b/packages/layout-engine/tests/src/sdt-metadata.test.ts index d5213d5bef..5439417f93 100644 --- a/packages/layout-engine/tests/src/sdt-metadata.test.ts +++ b/packages/layout-engine/tests/src/sdt-metadata.test.ts @@ -127,6 +127,55 @@ describe('SDT metadata integration', () => { }); }); + it('preserves nested block structuredContent content and metadata', () => { + const nestedBlockDoc = { + type: 'doc', + content: [ + { + type: 'structuredContentBlock', + attrs: { + id: 'outer-block-sdt', + tag: 'outer_block', + alias: 'Outer Block', + }, + content: [ + { + type: 'paragraph', + content: [{ type: 'text', text: 'Outer paragraph' }], + }, + { + type: 'structuredContentBlock', + attrs: { + id: 'inner-block-sdt', + tag: 'inner_block', + alias: 'Inner Block', + }, + content: [ + { + type: 'paragraph', + content: [{ type: 'text', text: 'Inner paragraph' }], + }, + ], + }, + ], + }, + ], + }; + const { blocks: nestedBlocks } = toFlowBlocks(nestedBlockDoc); + const innerParagraph = nestedBlocks.find( + (block) => block.kind === 'paragraph' && block.runs?.some((run) => run.text === 'Inner paragraph'), + ); + + expect(innerParagraph).toBeDefined(); + expect(innerParagraph?.attrs?.sdt).toMatchObject({ + type: 'structuredContent', + scope: 'block', + id: 'inner-block-sdt', + tag: 'inner_block', + alias: 'Inner Block', + }); + }); + it('handles nested structuredContent (inline within inline)', () => { const nestedBlock = summary.find((b) => b.blockId === '2-paragraph'); const outerRun = nestedBlock?.runMetadata.find((r) => r.metadata?.id === 'nested-outer'); diff --git a/packages/super-editor/src/editors/v1/core/layout-adapter/sdt/structured-content-block.ts b/packages/super-editor/src/editors/v1/core/layout-adapter/sdt/structured-content-block.ts index 4fb2c5f7f7..68d1046c5f 100644 --- a/packages/super-editor/src/editors/v1/core/layout-adapter/sdt/structured-content-block.ts +++ b/packages/super-editor/src/editors/v1/core/layout-adapter/sdt/structured-content-block.ts @@ -232,6 +232,10 @@ export function handleStructuredContentBlockNode(node: PMNode, context: NodeHand // inside this content control is likewise transparent here; render its entry // paragraphs without advancing currentParagraphIndex, since // findParagraphsWithSectPr does not recurse structuredContentBlock. + if (child.type === 'structuredContentBlock') { + handleStructuredContentBlockNode(child, context); + return; + } if ( Array.isArray(child.content) && (child.type === 'documentPartObject' ||