feat: show archived note indicator banner in editor (#183)
Adds a subtle ArchivedNoteBanner component below the breadcrumb bar when a note is archived. Banner includes: - Muted gray background with archive icon + 'Archived' label - 'Unarchive' button (ArrowUUpLeft icon) wired to same handler as Cmd+E - Keyboard hint shown in button title Editor remains fully editable (banner is purely informational). Indicator appears/disappears reactively via entry.archived from store. Co-authored-by: Test <test@test.com>
This commit is contained in:
1
design/archived-note-indicator.pen
Normal file
1
design/archived-note-indicator.pen
Normal file
@@ -0,0 +1 @@
|
||||
{"children":[],"variables":{}}
|
||||
26
src/components/ArchivedNoteBanner.test.tsx
Normal file
26
src/components/ArchivedNoteBanner.test.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
import { render, screen, fireEvent } from '@testing-library/react'
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { ArchivedNoteBanner } from './ArchivedNoteBanner'
|
||||
|
||||
describe('ArchivedNoteBanner', () => {
|
||||
it('renders archive icon and label', () => {
|
||||
render(<ArchivedNoteBanner onUnarchive={vi.fn()} />)
|
||||
expect(screen.getByTestId('archived-note-banner')).toBeTruthy()
|
||||
expect(screen.getByText('Archived')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('renders unarchive button with keyboard hint', () => {
|
||||
render(<ArchivedNoteBanner onUnarchive={vi.fn()} />)
|
||||
const btn = screen.getByTestId('unarchive-btn')
|
||||
expect(btn).toBeTruthy()
|
||||
expect(btn.textContent).toContain('Unarchive')
|
||||
expect(btn.title).toBe('Unarchive (Cmd+E)')
|
||||
})
|
||||
|
||||
it('calls onUnarchive when button is clicked', () => {
|
||||
const onUnarchive = vi.fn()
|
||||
render(<ArchivedNoteBanner onUnarchive={onUnarchive} />)
|
||||
fireEvent.click(screen.getByTestId('unarchive-btn'))
|
||||
expect(onUnarchive).toHaveBeenCalledOnce()
|
||||
})
|
||||
})
|
||||
48
src/components/ArchivedNoteBanner.tsx
Normal file
48
src/components/ArchivedNoteBanner.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Archive, ArrowUUpLeft } from '@phosphor-icons/react'
|
||||
|
||||
interface ArchivedNoteBannerProps {
|
||||
onUnarchive: () => void
|
||||
}
|
||||
|
||||
export function ArchivedNoteBanner({ onUnarchive }: ArchivedNoteBannerProps) {
|
||||
return (
|
||||
<div
|
||||
data-testid="archived-note-banner"
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 6,
|
||||
padding: '4px 16px',
|
||||
background: 'var(--muted)',
|
||||
borderBottom: '1px solid var(--border)',
|
||||
fontSize: 12,
|
||||
color: 'var(--muted-foreground)',
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
<Archive size={13} weight="bold" />
|
||||
<span>Archived</span>
|
||||
<button
|
||||
data-testid="unarchive-btn"
|
||||
onClick={onUnarchive}
|
||||
style={{
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
gap: 4,
|
||||
marginLeft: 'auto',
|
||||
padding: '2px 8px',
|
||||
background: 'transparent',
|
||||
border: '1px solid var(--border)',
|
||||
borderRadius: 4,
|
||||
fontSize: 11,
|
||||
color: 'var(--muted-foreground)',
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
title="Unarchive (Cmd+E)"
|
||||
>
|
||||
<ArrowUUpLeft size={12} />
|
||||
Unarchive
|
||||
</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import type { useCreateBlockNote } from '@blocknote/react'
|
||||
import { DiffView } from './DiffView'
|
||||
import { BreadcrumbBar } from './BreadcrumbBar'
|
||||
import { TrashedNoteBanner } from './TrashedNoteBanner'
|
||||
import { ArchivedNoteBanner } from './ArchivedNoteBanner'
|
||||
import { RawEditorView } from './RawEditorView'
|
||||
import { countWords } from '../utils/wikilinks'
|
||||
import { SingleEditorView } from './SingleEditorView'
|
||||
@@ -173,6 +174,9 @@ export function EditorContent({
|
||||
onDeletePermanently={() => onDeleteNote?.(activeTab.entry.path)}
|
||||
/>
|
||||
)}
|
||||
{activeTab?.entry.archived && breadcrumbProps.onUnarchiveNote && (
|
||||
<ArchivedNoteBanner onUnarchive={() => breadcrumbProps.onUnarchiveNote!(activeTab.entry.path)} />
|
||||
)}
|
||||
<EditorBody activeTab={activeTab} isLoadingNewTab={isLoadingNewTab} entries={entries} editor={editor} diffMode={diffMode} diffContent={diffContent} onToggleDiff={onToggleDiff} rawMode={rawMode} onRawContentChange={onRawContentChange} onSave={onSave} onNavigateWikilink={onNavigateWikilink} onEditorChange={onEditorChange} vaultPath={vaultPath} isDarkTheme={isDarkTheme} isTrashed={isTrashed} />
|
||||
</div>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user