dsebastien_obsidian-journal.../documentation/Components.md
Sebastien 445a5a0dd5 feat(plugin): remember Periodic Review column collapsed state
Persist each column's collapsed/expanded state in the Base view file
(key folded_{periodType}) and restore it on reopen, gated by a new
global "Remember column state" setting (default on).

- FoldableColumn: initiallyFolded + onFoldChange options.
- View createColumn: restore from / persist to Base config when enabled.
- New global setting rememberColumnState (type, default, load, tab).
- Config-key helper getColumnFoldedConfigKey + spec. Docs updated.
2026-06-30 11:19:39 +02:00

6.2 KiB

Components

UI components in src/app/components/.

NoteCard

note-card.ts - Expandable card displaying a single periodic note.

Features

  • Collapsible header with title (filename + period suffix)
  • Three view modes: view, edit, source
  • Embedded markdown editor via EmbeddableEditor
  • Debounced auto-save (1s)
  • State preservation during reconciliation
  • Cursor and scroll position preservation during external updates
  • External content updates don't interrupt active editing
  • Optional frontmatter fold on open (collapseFrontmatter, source mode only)

Props

constructor(
    parent: HTMLElement,
    app: App,
    file: TFile,
    periodType: PeriodType,
    noteDate: Date | null,
    initiallyExpanded: boolean,
    onOpen?: (file: TFile) => void,
    options?: NoteCardOptions
)

interface NoteCardOptions {
    foldable?: boolean // Card can be collapsed (default true)
    forcedMode?: CardMode // Lock the mode; user can't switch
    hideModeToggle?: boolean // Hide the view/edit/source buttons
    isDone?: boolean
    onToggleDone?: () => void
    onPrevious?: () => void
    onNext?: () => void
    collapseFrontmatter?: boolean // Fold YAML frontmatter on open (default false)
}

The Periodic Review view passes collapseFrontmatter: settings.collapseFrontmatter (the global setting) to every card; the card calls EmbeddableEditor.foldFrontmatter() after creating the source-mode editor.

State

type CardMode = 'view' | 'edit' | 'source'

interface CardState {
    expanded: boolean
    mode: CardMode
    hasActiveEditor: boolean
}

Key Methods

Method Description
toggle() Toggle expanded state
setMode(mode) Switch view/edit/source mode
getMode() Get current mode
isExpanded() Check if expanded
hasActiveEditor() Check if editor has focus
refreshContent() Reload content (preserves cursor/scroll)
getElement() Get DOM element
getFile() Get associated TFile

CSS Classes

  • .pn-card - Container
  • .pn-card--expanded - Expanded state
  • .pn-card--current - Current period highlight
  • .pn-card__header - Header area
  • .pn-card__title - Title text
  • .pn-card__content - Content area

CreateNoteButton

create-note-button.ts - Placeholder for missing notes with create action.

Variants

  • default - Compact inline button
  • large - Prominent button for column content

Props

constructor(
    parent: HTMLElement,
    date: Date,
    config: PeriodicNoteConfig,
    periodType: PeriodType,
    onClick: (date: Date) => Promise<boolean>,
    variant: 'default' | 'large' = 'default'
)

CSS Classes

  • .pn-card--missing - Missing note card style
  • .pn-create-btn - Default create button
  • .pn-create-large - Large variant container
  • .pn-create-large__btn - Large variant button

FoldableColumn

foldable-column.ts - Collapsible column for Periodic Review view.

Structure

[Header: fold button | title | actions]
[Selector: period list]
[Content: note content]

Props

constructor(
    parent: HTMLElement,
    title: string,
    options?: FoldableColumnOptions
)

interface FoldableColumnOptions {
    initiallyFolded?: boolean // Start collapsed (e.g. restored from Base config)
    onFoldChange?: (folded: boolean) => void // Fired on user toggles, not initial state
}

The Periodic Review view passes initiallyFolded from the persisted Base config (folded_{periodType}) and an onFoldChange that writes it back — both gated by the global rememberColumnState setting.

Key Methods

Method Description
toggleFold() Toggle collapsed state
fold() Collapse column
unfold() Expand column
isFolded() Check if collapsed
setWidth(width) Set column width in pixels
getSelectorEl() Get period selector container
getContentEl() Get content container
getHeaderActionsEl() Get header actions container
clear() Clear selector and content

When folded, the selector and content elements are hidden via an inline display: none (set in applyFoldVisibility()), because the layered .pr-column--folded CSS loses to unlayered Obsidian/theme rules (see documentation/history/2026-06-30.md).

CSS Classes

  • .pr-column - Container
  • .pr-column--folded - Collapsed state
  • .pr-column__header - Header area
  • .pr-column__title - Column title
  • .pr-column__fold-btn - Fold toggle button
  • .pr-column__selector - Period list area
  • .pr-column__content - Content display area

PeriodTabs

period-tabs.ts - Tab bar for period type selection in Periodic Notes view.

Props

constructor(
    parent: HTMLElement,
    availableModes: PeriodType[],
    currentMode: PeriodType,
    onChange: (mode: PeriodType) => void
)

Key Methods

Method Description
setActiveMode() Programmatically set active tab
getCurrentMode() Get active period type
getElement() Get DOM element

CSS Classes

  • .pn-tabs - Tab container
  • .pn-tab - Individual tab
  • .pn-tab--active - Active tab

Component Hierarchy

PeriodicNotesView
├── PeriodTabs
└── Cards Container
    ├── NoteCard (for existing notes)
    └── CreateNoteButton (for missing notes)

PeriodicReviewView
└── Columns Container
    └── FoldableColumn[]
        ├── Period Selector (period items)
        ├── Content Area
        │   ├── Note Content (sections)
        │   └── CreateNoteButton (if missing)
        └── Header Actions (create next year btn)