diff --git a/lara.lock b/lara.lock
index 9387bd6e..35801758 100644
--- a/lara.lock
+++ b/lara.lock
@@ -36,6 +36,7 @@ files:
command.navigation.showArchivedNotes: 241399b908884adfe8608a3ab827ca74
command.navigation.listType: 4f70c27c6826a37543c8ada561397c22
command.note.newNote: 23c4edda8b815f750782f01870d27271
+ command.note.newNoteInCurrentFolder: 167b765903c70ab1b645908ff8a899ab
command.note.newType: adce5108f18945cc502a06c02445e32d
command.note.newTypedNote: 1493eda772c2179cb6247169d00723b2
command.note.saveNote: 2a309cda46e95b00d2a5a8afb3cc0047
@@ -366,6 +367,7 @@ files:
sidebar.action.createFolder: 5dc1e97c14fbe72d8b566ce29c39f010
sidebar.action.renameFolder: db76034f8218cda07dadb746a5643019
sidebar.action.deleteFolder: 2a2f15300f6f7c81d69860ac1796b517
+ sidebar.action.createNodeInFolderMenu: 857a479229a4ab0bc62bbfb621d3180a
sidebar.action.revealFolderMenu: 76f4ed52da9937ae432dcf5a108fabb4
sidebar.action.copyFolderPathMenu: 1779ec6018a385912c1a5499a1bbf2b2
sidebar.action.renameFolderMenu: deb1d8fa030292e7eda2c244b313aca2
diff --git a/src/components/FolderTree.test.tsx b/src/components/FolderTree.test.tsx
index b50fbd04..e4b3e33f 100644
--- a/src/components/FolderTree.test.tsx
+++ b/src/components/FolderTree.test.tsx
@@ -4,6 +4,7 @@ import { describe, it, expect, vi } from 'vitest'
import { FolderTree } from './FolderTree'
import { FOLDER_ROW_SINGLE_CLICK_DELAY_MS } from './folder-tree/useFolderRowInteractions'
import { FOLDER_ROW_NESTING_INDENT, getFolderConnectorLeft } from './folder-tree/folderTreeLayout'
+import { CREATE_NOTE_IN_FOLDER_EVENT } from '../hooks/noteCreationRequests'
import type { FolderNode, SidebarSelection } from '../types'
const mockFolders: FolderNode[] = [
@@ -526,6 +527,44 @@ describe('FolderTree', () => {
expect(onCopyFolderPath).toHaveBeenCalledWith('projects')
})
+ it('creates a note in the right-clicked mounted folder', () => {
+ const onCreateNoteInFolder = vi.fn()
+ const folders: FolderNode[] = [
+ {
+ name: 'Personal',
+ path: '',
+ rootPath: '/Users/luca/Personal',
+ children: [{ name: 'projects', path: 'projects', rootPath: '/Users/luca/Personal', children: [] }],
+ },
+ {
+ name: 'Team',
+ path: '',
+ rootPath: '/Users/luca/Team',
+ children: [{ name: 'projects', path: 'projects', rootPath: '/Users/luca/Team', children: [] }],
+ },
+ ]
+
+ render(
+ ,
+ )
+
+ window.addEventListener(CREATE_NOTE_IN_FOLDER_EVENT, onCreateNoteInFolder)
+ fireEvent.contextMenu(screen.getAllByTestId('folder-row:projects')[1])
+ fireEvent.click(screen.getByTestId('create-node-in-folder-menu-item'))
+
+ expect(onCreateNoteInFolder).toHaveBeenCalledOnce()
+ expect((onCreateNoteInFolder.mock.calls[0][0] as CustomEvent).detail).toEqual({
+ folderPath: 'projects',
+ rootPath: '/Users/luca/Team',
+ })
+ window.removeEventListener(CREATE_NOTE_IN_FOLDER_EVENT, onCreateNoteInFolder)
+ })
+
it('keeps destructive folder actions off the vault root row and menu', () => {
render(
diff --git a/src/components/MermaidDiagram.tsx b/src/components/MermaidDiagram.tsx
index 1bead6f3..16245aad 100644
--- a/src/components/MermaidDiagram.tsx
+++ b/src/components/MermaidDiagram.tsx
@@ -1,5 +1,5 @@
import { ArrowsOut as Maximize2 } from '@phosphor-icons/react'
-import { useEffect, useId, useMemo, useRef, useState, type SyntheticEvent } from 'react'
+import { useEffect, useId, useMemo, useState, type SyntheticEvent } from 'react'
import { Button } from '@/components/ui/button'
import {
Dialog,
@@ -159,13 +159,7 @@ function MermaidLightbox({ svg }: { svg: string }) {
}
function MermaidSourceFallback({ source }: { source: string }) {
- const sourceRef = useRef(null)
-
- useEffect(() => {
- sourceRef.current?.setAttribute('aria-label', 'Mermaid source')
- }, [])
-
- return {source}
+ return {source}
}
export function MermaidDiagram({ diagram, source }: MermaidDiagramProps) {
diff --git a/src/components/NoteList.rendering.test.tsx b/src/components/NoteList.rendering.test.tsx
index 9a5a9cd5..6b1b6345 100644
--- a/src/components/NoteList.rendering.test.tsx
+++ b/src/components/NoteList.rendering.test.tsx
@@ -188,6 +188,26 @@ describe('NoteList rendering', () => {
expect(onCreateNote).toHaveBeenCalledWith(undefined)
})
+ it('shows the active folder name and creates notes inside that folder', () => {
+ const { onCreateNote } = renderNoteList({
+ selection: {
+ kind: 'folder',
+ path: 'Projects/2026 Planning',
+ rootPath: '/Users/luca/Laputa',
+ },
+ })
+
+ expect(screen.getByRole('heading', { name: '2026 Planning' })).toBeInTheDocument()
+
+ fireEvent.click(screen.getByTitle('Create new note'))
+
+ expect(onCreateNote).toHaveBeenCalledWith(undefined, {
+ creationPath: 'folder_header',
+ folderPath: 'Projects/2026 Planning',
+ vaultPath: '/Users/luca/Laputa',
+ })
+ })
+
it('pins the current entity and shows grouped children', () => {
renderNoteList({ selection: { kind: 'entity', entry: mockEntries[0] } })
expect(screen.getAllByText('Build Laputa App').length).toBeGreaterThanOrEqual(1)
diff --git a/src/components/folder-tree/FolderContextMenu.tsx b/src/components/folder-tree/FolderContextMenu.tsx
index abec475c..8721f549 100644
--- a/src/components/folder-tree/FolderContextMenu.tsx
+++ b/src/components/folder-tree/FolderContextMenu.tsx
@@ -1,10 +1,11 @@
import type { RefObject } from 'react'
-import { ClipboardText, FolderOpen, PencilSimple, Trash } from '@phosphor-icons/react'
+import { ClipboardText, FolderOpen, PencilSimple, Plus, Trash } from '@phosphor-icons/react'
import { Button } from '@/components/ui/button'
import { translate, type AppLocale } from '../../lib/i18n'
export interface FolderContextMenuState {
path: string
+ rootPath?: string
x: number
y: number
}
@@ -15,6 +16,7 @@ interface FolderContextMenuProps {
onDelete?: (folderPath: string) => void
onReveal?: (folderPath: string) => void
onCopyPath?: (folderPath: string) => void
+ onCreateNote?: (folderPath: string, rootPath?: string) => void
onRename: (folderPath: string) => void
locale?: AppLocale
}
@@ -25,6 +27,7 @@ export function FolderContextMenu({
onDelete,
onReveal,
onCopyPath,
+ onCreateNote,
onRename,
locale = 'en',
}: FolderContextMenuProps) {
@@ -38,6 +41,18 @@ export function FolderContextMenu({
style={{ left: menu.x, top: menu.y, minWidth: 180 }}
data-testid="folder-context-menu"
>
+ {onCreateNote && (
+
+ )}
{onReveal && (