From 0fb115bbe1f05eb95fdff8d7a0a759e6ac424f1a Mon Sep 17 00:00:00 2001 From: lucaronin Date: Thu, 2 Apr 2026 19:02:42 +0200 Subject: [PATCH] feat: show vault-relative path below title in editor Notes in subdirectories now display their vault-relative path (e.g. docs/adr/0001-tauri-stack.md) as small muted text below the title field. Root-level notes show no path. Note list entries do not display any path. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/components/TitleField.test.tsx | 15 +++++++++++++++ src/components/TitleField.tsx | 17 ++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/components/TitleField.test.tsx b/src/components/TitleField.test.tsx index 36866025..5d38eb69 100644 --- a/src/components/TitleField.test.tsx +++ b/src/components/TitleField.test.tsx @@ -101,4 +101,19 @@ describe('TitleField', () => { window.dispatchEvent(new CustomEvent('laputa:focus-editor', { detail: { selectTitle: true } })) expect(document.activeElement).toBe(input) }) + + it('shows vault-relative path for notes in subdirectories', () => { + render( {}} />) + expect(screen.getByTestId('title-field-path')).toHaveTextContent('docs/adr/0001-tauri-stack.md') + }) + + it('hides path for notes at vault root', () => { + render( {}} />) + expect(screen.queryByTestId('title-field-path')).not.toBeInTheDocument() + }) + + it('hides path when vaultPath is not provided', () => { + render( {}} />) + expect(screen.queryByTestId('title-field-path')).not.toBeInTheDocument() + }) }) diff --git a/src/components/TitleField.tsx b/src/components/TitleField.tsx index 47efe515..726eef28 100644 --- a/src/components/TitleField.tsx +++ b/src/components/TitleField.tsx @@ -5,6 +5,10 @@ interface TitleFieldProps { title: string filename: string editable?: boolean + /** Absolute path of the note file. */ + notePath?: string + /** Absolute path of the vault root. */ + vaultPath?: string /** Called when the user finishes editing the title (blur or Enter). */ onTitleChange: (newTitle: string) => void } @@ -48,7 +52,7 @@ function useOptimisticTitle(title: string, onTitleChange: (t: string) => void) { * Dedicated title input field above the editor. * Displays the title as an editable field and shows the resulting filename below. */ -export function TitleField({ title, filename, editable = true, onTitleChange }: TitleFieldProps) { +export function TitleField({ title, filename, editable = true, notePath, vaultPath, onTitleChange }: TitleFieldProps) { const inputRef = useRef(null) const { value, isEditing, handleFocus, commitTitle, revert, setEdit } = useOptimisticTitle(title, onTitleChange) @@ -80,6 +84,12 @@ export function TitleField({ title, filename, editable = true, onTitleChange }: const currentStem = filename.replace(/\.md$/, '') const showFilename = isEditing || currentStem !== expectedSlug + // Compute vault-relative path (only for notes in subdirectories) + const relativePath = notePath && vaultPath + ? notePath.replace(vaultPath + '/', '') + : null + const showRelativePath = relativePath && relativePath.includes('/') + return (
)} + {showRelativePath && ( + + {relativePath} + + )}
) }