From 5023e7694c5eadd21013c306035fb22c1781dd92 Mon Sep 17 00:00:00 2001 From: littlefrontender Date: Fri, 1 May 2026 11:13:35 +0400 Subject: [PATCH] feat: add test for serializing new ordered steps in markdownToBlocks and improve step insertion logic to inherit list style --- src/editor/blocks/step.tsx | 26 ++++++++++++++----- src/editor/customMarkdownConverter.test.ts | 30 ++++++++++++++++++++++ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/src/editor/blocks/step.tsx b/src/editor/blocks/step.tsx index 80b9e6b..8344461 100644 --- a/src/editor/blocks/step.tsx +++ b/src/editor/blocks/step.tsx @@ -108,11 +108,6 @@ export function addStepsBlock(editor: { insertBlocks: (blocks: any[], referenceId: string, placement: "before" | "after") => any[]; }): string | null { const allBlocks = editor.document; - const emptyStep = { - type: "testStep" as const, - props: { stepTitle: "", stepData: "", expectedResult: "" }, - children: [], - }; let stepsHeadingIndex = -1; for (let i = 0; i < allBlocks.length; i++) { @@ -142,7 +137,17 @@ export function addStepsBlock(editor: { if (isEmptyParagraph(b)) continue; break; } - const inserted = editor.insertBlocks([emptyStep], allBlocks[lastIndex].id, "after"); + const previousStep = allBlocks[lastIndex]; + const inheritedListStyle = + previousStep?.type === "testStep" + ? ((previousStep.props as any)?.listStyle ?? "bullet") + : "bullet"; + const emptyStep = { + type: "testStep" as const, + props: { stepTitle: "", stepData: "", expectedResult: "", listStyle: inheritedListStyle }, + children: [], + }; + const inserted = editor.insertBlocks([emptyStep], previousStep.id, "after"); return inserted?.[0]?.id ?? null; } @@ -153,6 +158,11 @@ export function addStepsBlock(editor: { content: [{ type: "text" as const, text: "Steps" }], children: [], }; + const emptyStep = { + type: "testStep" as const, + props: { stepTitle: "", stepData: "", expectedResult: "" }, + children: [], + }; const inserted = editor.insertBlocks([stepsHeading, emptyStep], lastBlock.id, "after"); return inserted?.[1]?.id ?? null; } @@ -399,6 +409,7 @@ export const stepBlock = createReactBlockSpec( if (next && isEmptyParagraph(next)) { editor.removeBlocks([next.id]); } + const currentListStyle = (block.props as any).listStyle ?? "bullet"; editor.insertBlocks( [ { @@ -407,6 +418,7 @@ export const stepBlock = createReactBlockSpec( stepTitle: "", stepData: "", expectedResult: "", + listStyle: currentListStyle, }, children: [], }, @@ -414,7 +426,7 @@ export const stepBlock = createReactBlockSpec( block.id, "after", ); - }, [editor, block.id]); + }, [editor, block.id, block.props]); const handleFieldFocus = useCallback(() => { const selection = editor.getSelection(); diff --git a/src/editor/customMarkdownConverter.test.ts b/src/editor/customMarkdownConverter.test.ts index c3fc7d7..fa4f713 100644 --- a/src/editor/customMarkdownConverter.test.ts +++ b/src/editor/customMarkdownConverter.test.ts @@ -1696,6 +1696,36 @@ describe("markdownToBlocks", () => { expect(stepBlocks[1].props).toMatchObject({ stepTitle: "Second step", listStyle: "ordered" }); }); + it("serializes a new ordered step appended to a numbered list as N.", () => { + const orderedSteps: CustomEditorBlock[] = [ + { + id: "s1", + type: "testStep", + props: { stepTitle: "First step", stepData: "", expectedResult: "", listStyle: "ordered" }, + content: undefined as any, + children: [], + } as any, + { + id: "s2", + type: "testStep", + props: { stepTitle: "Second step", stepData: "", expectedResult: "", listStyle: "ordered" }, + content: undefined as any, + children: [], + } as any, + { + id: "s3", + type: "testStep", + props: { stepTitle: "Newly added step", stepData: "", expectedResult: "", listStyle: "ordered" }, + content: undefined as any, + children: [], + } as any, + ]; + + expect(blocksToMarkdown(orderedSteps)).toBe( + ["1. First step", "2. Second step", "3. Newly added step"].join("\n"), + ); + }); + it("parses steps under an h4 'step' heading (lowercase)", () => { const markdown = ["#### step", "", "* Do something"].join("\n"); const blocks = markdownToBlocks(markdown);