From a97f47cb59721e958e96cf5213f97d358d97eac7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Gurruchaga?= Date: Sun, 17 May 2026 03:55:55 -0400 Subject: [PATCH] Fix frontmatter property spaces --- .../src/features/editor/Editor.test.tsx | 35 +++++++++++++++++++ .../editor/FrontmatterPanel.helpers.test.ts | 14 ++++++++ .../src/features/editor/FrontmatterPanel.tsx | 16 ++++++--- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/apps/desktop/src/features/editor/Editor.test.tsx b/apps/desktop/src/features/editor/Editor.test.tsx index 22628c4b..9fe9174b 100644 --- a/apps/desktop/src/features/editor/Editor.test.tsx +++ b/apps/desktop/src/features/editor/Editor.test.tsx @@ -416,6 +416,41 @@ describe("Editor", () => { expect(screen.getAllByDisplayValue("Updated title")).toHaveLength(2); }); + it("allows inserting spaces while editing text properties", async () => { + setEditorTabs([ + { + id: "tab-1", + noteId: "notes/current", + title: "Frontmatter title", + content: "---\ntitle: Frontmatter title\n---\nBody", + }, + ]); + + renderComponent(); + + await act(async () => { + fireEvent.click(screen.getByRole("button", { name: "Properties" })); + }); + + const view = getEditorView(); + const propertyInput = screen.getAllByDisplayValue( + "Frontmatter title", + )[1]; + + await act(async () => { + fireEvent.change(propertyInput, { + target: { value: "Frontmatter title " }, + }); + }); + + expect((propertyInput as HTMLInputElement).value).toBe( + "Frontmatter title ", + ); + expect(view.state.doc.toString()).toContain( + 'title: "Frontmatter title "', + ); + }); + it("does not underline markdown headings in source mode", async () => { setEditorTabs([ { diff --git a/apps/desktop/src/features/editor/FrontmatterPanel.helpers.test.ts b/apps/desktop/src/features/editor/FrontmatterPanel.helpers.test.ts index a36f34dc..0ab48c59 100644 --- a/apps/desktop/src/features/editor/FrontmatterPanel.helpers.test.ts +++ b/apps/desktop/src/features/editor/FrontmatterPanel.helpers.test.ts @@ -38,4 +38,18 @@ tags: --- `); }); + + it("preserves a trailing space while text properties are being edited", () => { + const raw = serializeFrontmatterRaw([ + { key: "title", value: "Roadmap " }, + ]); + + expect(raw).toBe(`--- +title: "Roadmap " +--- +`); + expect(parseFrontmatterRaw(raw ?? "")).toEqual([ + { key: "title", value: "Roadmap " }, + ]); + }); }); diff --git a/apps/desktop/src/features/editor/FrontmatterPanel.tsx b/apps/desktop/src/features/editor/FrontmatterPanel.tsx index 070c3497..019336fe 100644 --- a/apps/desktop/src/features/editor/FrontmatterPanel.tsx +++ b/apps/desktop/src/features/editor/FrontmatterPanel.tsx @@ -78,14 +78,15 @@ export function serializeFrontmatterRaw( key: key.trim(), value: Array.isArray(value) ? value.map((item) => item.trim()).filter(Boolean) - : typeof value === "string" - ? value.trim() - : value, + : value, })) .filter(({ key, value }) => { if (!key) return false; if (Array.isArray(value)) return value.length > 0; - return value !== null && value !== ""; + return ( + value !== null && + (typeof value !== "string" || value.trim() !== "") + ); }); if (!cleaned.length) return null; @@ -104,7 +105,12 @@ export function serializeFrontmatterRaw( function quoteYaml(value: string): string { if (!value) return '""'; - if (/^[A-Za-z0-9 _./:@#%+,-]+$/.test(value)) return value; + if ( + value.trim() === value && + /^[A-Za-z0-9 _./:@#%+,-]+$/.test(value) + ) { + return value; + } return JSON.stringify(value); }