From cd390705692a486c8603400e1868da83361ba49f Mon Sep 17 00:00:00 2001 From: lucaronin Date: Thu, 2 Apr 2026 18:29:02 +0200 Subject: [PATCH] fix: remove H1 heading from new note editor body Title is already shown as a separate UI element above the editor, so the H1 in the body was a visual duplicate. New notes now have an empty editor body. Daily notes and type entries also no longer get an H1 inserted. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/hooks/useNoteActions.test.ts | 14 +++++++------- src/hooks/useNoteCreation.test.ts | 4 ++-- src/hooks/useNoteCreation.ts | 8 ++++---- tests/integration/vault-workflows.spec.ts | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/hooks/useNoteActions.test.ts b/src/hooks/useNoteActions.test.ts index de7d50ad..5a68fcf8 100644 --- a/src/hooks/useNoteActions.test.ts +++ b/src/hooks/useNoteActions.test.ts @@ -217,24 +217,24 @@ describe('entryMatchesTarget', () => { describe('buildNoteContent', () => { it('generates frontmatter with status for regular types', () => { const content = buildNoteContent('My Note', 'Note', 'Active') - expect(content).toBe('---\ntitle: My Note\ntype: Note\nstatus: Active\n---\n\n# My Note\n\n') + expect(content).toBe('---\ntitle: My Note\ntype: Note\nstatus: Active\n---\n') }) it('omits status when null', () => { const content = buildNoteContent('AI', 'Topic', null) - expect(content).toBe('---\ntitle: AI\ntype: Topic\n---\n\n# AI\n\n') + expect(content).toBe('---\ntitle: AI\ntype: Topic\n---\n') }) it('includes template body when provided', () => { const content = buildNoteContent('My Project', 'Project', 'Active', '## Objective\n\n## Notes\n\n') - expect(content).toContain('# My Project') + expect(content).not.toContain('# My Project') expect(content).toContain('## Objective') expect(content).toContain('## Notes') }) it('ignores null template', () => { const content = buildNoteContent('My Note', 'Note', 'Active', null) - expect(content).toBe('---\ntitle: My Note\ntype: Note\nstatus: Active\n---\n\n# My Note\n\n') + expect(content).toBe('---\ntitle: My Note\ntype: Note\nstatus: Active\n---\n') }) }) @@ -319,7 +319,7 @@ describe('resolveNewType', () => { expect(entry.isA).toBe('Type') expect(entry.status).toBeNull() expect(content).toContain('type: Type') - expect(content).toContain('# Recipe') + expect(content).not.toContain('# Recipe') }) it('uses provided vault path instead of hardcoded path', () => { @@ -491,9 +491,9 @@ describe('buildDailyNoteContent', () => { expect(content).toContain('## Reflections') }) - it('includes H1 heading with the date', () => { + it('does not include H1 heading with the date', () => { const content = buildDailyNoteContent('2026-03-02') - expect(content).toContain('# 2026-03-02') + expect(content).not.toMatch(/^# /m) }) }) diff --git a/src/hooks/useNoteCreation.test.ts b/src/hooks/useNoteCreation.test.ts index 82dbc4a0..749a2003 100644 --- a/src/hooks/useNoteCreation.test.ts +++ b/src/hooks/useNoteCreation.test.ts @@ -116,11 +116,11 @@ describe('entryMatchesTarget', () => { describe('buildNoteContent', () => { it('generates frontmatter with status', () => { - expect(buildNoteContent('My Note', 'Note', 'Active')).toBe('---\ntitle: My Note\ntype: Note\nstatus: Active\n---\n\n# My Note\n\n') + expect(buildNoteContent('My Note', 'Note', 'Active')).toBe('---\ntitle: My Note\ntype: Note\nstatus: Active\n---\n') }) it('omits status when null', () => { - expect(buildNoteContent('AI', 'Topic', null)).toBe('---\ntitle: AI\ntype: Topic\n---\n\n# AI\n\n') + expect(buildNoteContent('AI', 'Topic', null)).toBe('---\ntitle: AI\ntype: Topic\n---\n') }) it('includes template body when provided', () => { diff --git a/src/hooks/useNoteCreation.ts b/src/hooks/useNoteCreation.ts index 5e4d37c2..afb2e9c5 100644 --- a/src/hooks/useNoteCreation.ts +++ b/src/hooks/useNoteCreation.ts @@ -66,8 +66,8 @@ export function buildNoteContent(title: string, type: string, status: string | n const lines = ['---', `title: ${title}`, `type: ${type}`] if (status) lines.push(`status: ${status}`) lines.push('---') - const body = template ? `\n${template}` : '\n' - return `${lines.join('\n')}\n\n# ${title}\n${body}` + const body = template ? `\n${template}` : '' + return `${lines.join('\n')}\n${body}` } export function resolveNewNote(title: string, type: string, vaultPath: string, template?: string | null): { entry: VaultEntry; content: string } { @@ -80,7 +80,7 @@ export function resolveNewNote(title: string, type: string, vaultPath: string, t export function resolveNewType(typeName: string, vaultPath: string): { entry: VaultEntry; content: string } { const slug = slugify(typeName) const entry = buildNewEntry({ path: `${vaultPath}/${slug}.md`, slug, title: typeName, type: 'Type', status: null }) - return { entry, content: `---\ntype: Type\n---\n\n# ${typeName}\n\n` } + return { entry, content: `---\ntype: Type\n---\n` } } export function todayDateString(): string { @@ -89,7 +89,7 @@ export function todayDateString(): string { export function buildDailyNoteContent(date: string): string { const lines = ['---', `title: ${date}`, 'type: Journal', `date: ${date}`, '---'] - return `${lines.join('\n')}\n\n# ${date}\n\n## Intentions\n\n\n\n## Reflections\n\n` + return `${lines.join('\n')}\n\n## Intentions\n\n\n\n## Reflections\n\n` } export function resolveDailyNote(date: string, vaultPath: string): { entry: VaultEntry; content: string } { diff --git a/tests/integration/vault-workflows.spec.ts b/tests/integration/vault-workflows.spec.ts index 58f4e343..99b9582c 100644 --- a/tests/integration/vault-workflows.spec.ts +++ b/tests/integration/vault-workflows.spec.ts @@ -138,7 +138,7 @@ test('create note saves file to disk with correct slug', async ({ page }) => { }).toPass({ timeout: 5_000 }) const content = fs.readFileSync(expectedPath, 'utf-8') - expect(content).toContain('# Untitled note') + expect(content).not.toContain('# Untitled note') expect(content).toContain('type: Note') })