diff --git a/design/raw-editor-mode.pen b/design/raw-editor-mode.pen new file mode 100644 index 00000000..747b5ab3 --- /dev/null +++ b/design/raw-editor-mode.pen @@ -0,0 +1 @@ +{"children":[],"variables":{}} diff --git a/src/App.tsx b/src/App.tsx index d3ce21de..8408591b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -270,6 +270,9 @@ function App() { const bulkActions = useBulkActions(entryActions, setToastMessage) + // Raw-toggle ref: Editor registers its handleToggleRaw here so the command palette can call it + const rawToggleRef = useRef<() => void>(() => {}) + const { setViewMode, sidebarVisible, noteListVisible } = useViewMode() const zoom = useZoom() const buildNumber = useBuildNumber() @@ -290,6 +293,7 @@ function App() { onArchiveNote: entryActions.handleArchiveNote, onUnarchiveNote: entryActions.handleUnarchiveNote, onCommitPush: commitFlow.openCommitDialog, onSetViewMode: setViewMode, onToggleInspector: () => layout.setInspectorCollapsed(c => !c), + onToggleRawEditor: () => rawToggleRef.current(), onZoomIn: zoom.zoomIn, onZoomOut: zoom.zoomOut, onZoomReset: zoom.zoomReset, zoomLevel: zoom.zoomLevel, onSelect: setSelection, onCloseTab: notes.handleCloseTab, @@ -389,7 +393,9 @@ function App() { onUnarchiveNote={entryActions.handleUnarchiveNote} onRenameTab={handleRenameTab} onContentChange={handleContentChange} + onSave={handleSave} onTitleSync={handleTitleSync} + rawToggleRef={rawToggleRef} canGoBack={navHistory.canGoBack} canGoForward={navHistory.canGoForward} onGoBack={handleGoBack} diff --git a/src/components/BreadcrumbBar.test.tsx b/src/components/BreadcrumbBar.test.tsx index 85fcb7f8..9e867c54 100644 --- a/src/components/BreadcrumbBar.test.tsx +++ b/src/components/BreadcrumbBar.test.tsx @@ -115,3 +115,24 @@ describe('BreadcrumbBar — archive/unarchive', () => { expect(onUnarchive).toHaveBeenCalledOnce() }) }) + +describe('BreadcrumbBar — raw editor toggle', () => { + it('shows Raw editor button with tooltip "Raw editor" when rawMode is off', () => { + const onToggleRaw = vi.fn() + render() + expect(screen.getByTitle('Raw editor')).toBeInTheDocument() + }) + + it('shows "Back to editor" tooltip when rawMode is on', () => { + const onToggleRaw = vi.fn() + render() + expect(screen.getByTitle('Back to editor')).toBeInTheDocument() + }) + + it('calls onToggleRaw when raw button is clicked', () => { + const onToggleRaw = vi.fn() + render() + fireEvent.click(screen.getByTitle('Raw editor')) + expect(onToggleRaw).toHaveBeenCalledOnce() + }) +}) diff --git a/src/components/BreadcrumbBar.tsx b/src/components/BreadcrumbBar.tsx index 80b63135..ee3af859 100644 --- a/src/components/BreadcrumbBar.tsx +++ b/src/components/BreadcrumbBar.tsx @@ -4,6 +4,7 @@ import { cn } from '@/lib/utils' import { MagnifyingGlass, GitBranch, + Code, CursorText, Sparkle, SlidersHorizontal, @@ -22,6 +23,8 @@ interface BreadcrumbBarProps { diffMode: boolean diffLoading: boolean onToggleDiff: () => void + rawMode?: boolean + onToggleRaw?: () => void showAIChat?: boolean onToggleAIChat?: () => void inspectorCollapsed?: boolean @@ -34,7 +37,23 @@ interface BreadcrumbBarProps { const DISABLED_ICON_STYLE = { opacity: 0.4, cursor: 'not-allowed' } as const +function RawToggleButton({ rawMode, onToggleRaw }: { rawMode?: boolean; onToggleRaw?: () => void }) { + return ( + + ) +} + function BreadcrumbActions({ entry, showDiffToggle, diffMode, diffLoading, onToggleDiff, + rawMode, onToggleRaw, showAIChat, onToggleAIChat, inspectorCollapsed, onToggleInspector, onTrash, onRestore, onArchive, onUnarchive, }: Omit) { @@ -68,6 +87,7 @@ function BreadcrumbActions({ entry, showDiffToggle, diffMode, diffLoading, onTog )} +