feat: add note layout preference

This commit is contained in:
lucaronin
2026-04-26 04:41:18 +02:00
parent 5fd8f8fb40
commit c7edc71a97
19 changed files with 277 additions and 16 deletions

View File

@@ -4,7 +4,7 @@ import { describe, expect, it, vi } from 'vitest'
import { EditorContentLayout } from './EditorContentLayout'
vi.mock('../BreadcrumbBar', () => ({
BreadcrumbBar: () => <div data-testid="breadcrumb-bar" />,
BreadcrumbBar: ({ noteLayout }: { noteLayout?: string }) => <div data-testid="breadcrumb-bar" data-note-layout={noteLayout} />,
}))
vi.mock('../ArchivedNoteBanner', () => ({
@@ -63,6 +63,8 @@ function createModel(overrides: Record<string, unknown> = {}) {
onEditorChange: vi.fn(),
isDeletedPreview: false,
rawLatestContentRef: { current: null },
noteLayout: 'centered',
onToggleNoteLayout: vi.fn(),
forceRawMode: false,
showAIChat: false,
onToggleAIChat: vi.fn(),
@@ -99,4 +101,11 @@ describe('EditorContentLayout', () => {
expect(container.querySelector('.animate-pulse')).not.toBeNull()
expect(screen.queryByTestId('title-field-input')).not.toBeInTheDocument()
})
it('marks the editor content root and breadcrumb with the note layout preference', () => {
const { container } = render(<EditorContentLayout {...createModel({ noteLayout: 'left' })} />)
expect(container.firstElementChild).toHaveClass('editor-content-layout--left')
expect(screen.getByTestId('breadcrumb-bar')).toHaveAttribute('data-note-layout', 'left')
})
})

View File

@@ -1,4 +1,5 @@
import type React from 'react'
import { cn } from '@/lib/utils'
import { DiffView } from '../DiffView'
import { BreadcrumbBar } from '../BreadcrumbBar'
import { ArchivedNoteBanner } from '../ArchivedNoteBanner'
@@ -28,6 +29,8 @@ type BreadcrumbActions = Pick<
| 'onArchiveNote'
| 'onUnarchiveNote'
| 'onRenameFilename'
| 'noteLayout'
| 'onToggleNoteLayout'
>
function EditorLoadingSkeleton() {
@@ -128,6 +131,8 @@ function ActiveTabBreadcrumb({
onArchive={bindPath(actions.onArchiveNote, path)}
onUnarchive={bindPath(actions.onUnarchiveNote, path)}
onRenameFilename={actions.onRenameFilename}
noteLayout={actions.noteLayout}
onToggleNoteLayout={actions.onToggleNoteLayout}
/>
)
}
@@ -228,18 +233,23 @@ export function EditorContentLayout(model: EditorContentModel) {
isDeletedPreview,
rawLatestContentRef,
rawModeContent,
noteLayout,
} = model
const rootClassName = cn(
'flex flex-1 flex-col min-w-0 min-h-0',
noteLayout === 'left' ? 'editor-content-layout--left' : 'editor-content-layout--centered',
)
if (!activeTab) {
return (
<div className="flex flex-1 flex-col min-w-0 min-h-0">
<div className={rootClassName}>
{isLoadingNewTab && showEditor && <EditorLoadingSkeleton />}
</div>
)
}
return (
<div className="flex flex-1 flex-col min-w-0 min-h-0">
<div className={rootClassName}>
<ActiveTabBreadcrumb
activeTab={activeTab}
barRef={breadcrumbBarRef}
@@ -263,6 +273,8 @@ export function EditorContentLayout(model: EditorContentModel) {
onArchiveNote: model.onArchiveNote,
onUnarchiveNote: model.onUnarchiveNote,
onRenameFilename: model.onRenameFilename,
noteLayout: model.noteLayout,
onToggleNoteLayout: model.onToggleNoteLayout,
}}
/>
<EditorChrome

View File

@@ -1,7 +1,7 @@
import type React from 'react'
import { useRef } from 'react'
import type { useCreateBlockNote } from '@blocknote/react'
import type { NoteStatus, VaultEntry } from '../../types'
import type { NoteLayout, NoteStatus, VaultEntry } from '../../types'
import { useEditorTheme } from '../../hooks/useTheme'
import { deriveEditorContentState } from './editorContentState'
@@ -40,6 +40,8 @@ export interface EditorContentProps {
rawModeContent?: string | null
rawLatestContentRef?: React.MutableRefObject<string | null>
onRenameFilename?: (path: string, newFilenameStem: string) => void
noteLayout?: NoteLayout
onToggleNoteLayout?: () => void
isConflicted?: boolean
onKeepMine?: (path: string) => void
onKeepTheirs?: (path: string) => void