Skip to content

Phase 2d: preview pane, in-app dialogs, theme toggle - #7

Merged
kelsi-bizer merged 1 commit into
masterfrom
claude/phase-2d-preview-polish
May 9, 2026
Merged

Phase 2d: preview pane, in-app dialogs, theme toggle#7
kelsi-bizer merged 1 commit into
masterfrom
claude/phase-2d-preview-polish

Conversation

@kelsi-bizer

Copy link
Copy Markdown
Owner

Summary

Final polish slice of the notes-app before Phase 3 hands the bundle off to the Docker image. Three quality-of-life additions:

  1. Markdown preview with edit / split / preview view modes
  2. In-app dialogs replacing native prompt/confirm
  3. Explicit theme toggle (system / light / dark, persisted)

What changed

Markdown preview (MarkdownPreview.tsx)

  • marked for parsing, DOMPurify to sanitize the rendered HTML before injecting (single-user trusted brain, but agents and external tools also write here, so HTML is treated as untrusted by default).
  • Wiki links registered as a marked inline extension: [[Page Name]] and [[Page Name|alias]] become <a class="wiki-link" data-target="…"> in the rendered HTML. Code spans and fenced code blocks are skipped automatically because marked doesn't run inline tokenizers inside them.
  • Click handler delegates [data-target] anchors back to the same resolveWikiTarget pipeline the editor uses, so wiki-link navigation is identical in both views.

View mode toggle

  • Header-level edit / split / preview segmented control, persisted to localStorage.
  • split puts the editor and preview side-by-side with a divider; the editor still owns Cmd/Ctrl-click navigation.

Dialogs (Dialog.tsx + useDialog)

  • DialogProvider exposes a promise-based API: prompt({ title, defaultValue, message }), confirm(message, { title }), alert(message).
  • Replaces every window.prompt / window.confirm / window.alert call across the app (new note, rename, delete confirm, error toasts).
  • Backdrop click and Esc cancel; Enter submits; the prompt input auto-selects on open.
  • Styled to match the rest of the app and respects the theme.

Theme (useTheme.ts)

  • Three states: system (default), light, dark. Cycled by the header toggle.
  • :root[data-theme=light|dark] overrides the prefers-color-scheme defaults; :root:not([data-theme]) keeps OS preference for system mode.
  • Persisted to localStorage; defensively wrapped in try/catch so privacy-mode browsers don't crash.

Bundle impact

Before (2c) After (2d)
JS (gzip) 226 KB 250 KB
CSS (gzip) 1.4 KB 2.3 KB

The +24 KB is marked + DOMPurify. Acceptable; can be split via import() if needed later.

Phase 3 readiness

The SPA is now feature-complete enough to ship as the BizerOS Knowledge web client. Phase 3 will:

  1. Build packages/notes-app in the Docker image
  2. Build packages/file-api in the Docker image
  3. Replace the existing nginx-served Logseq SPA with packages/notes-app/dist
  4. Run file-api as a sidecar process and proxy /api/* to it from nginx
  5. Document docker run -v /host/brain:/brain -p 8080:80 ghcr.io/kelsi-bizer/bizeros-knowledge:latest

Test plan

  • cd packages/file-api && pnpm start and cd packages/notes-app && pnpm dev
  • Type a note containing markdown features (# heading, **bold**, ``` fenced code ```, [[Some Page]]). Toggle editsplitpreview — content renders correctly in each
  • Click a [[wiki link]] in the rendered preview — navigates same as Cmd/Ctrl-click in the editor
  • Click "+ New" — modal appears, Esc cancels, Enter submits, focus is on the input
  • Click delete on a note — modal asks for confirmation, focus is on Cancel
  • Cycle the theme button (system → light → dark → system) — colors update; reload preserves the choice
  • pnpm typecheck && pnpm build pass

Generated by Claude Code

Final polish slice of the notes-app before Phase 3 (docker bundling).

Markdown preview:
- New MarkdownPreview component (marked + DOMPurify). Wiki links
  registered as a marked inline extension so [[Page Name]] and
  [[Page Name|alias]] become <a class="wiki-link" data-target="...">
  in rendered HTML, with code spans/blocks naturally exempt because
  marked skips inline tokenization inside them.
- Click handler delegates [data-target] anchors to the same
  resolveWikiTarget pipeline the editor uses.
- View mode toggle in the header: edit / split / preview, persisted
  to localStorage. Split is two panes side by side.

Dialogs:
- DialogProvider exposes promise-based prompt/confirm/alert via the
  useDialog hook, replacing window.prompt and window.confirm
  throughout the app.
- Backdrop, Esc-to-cancel, focus management (input auto-selected on
  prompt; cancel-focused on confirm), Enter to submit.
- Restyled to match the rest of the app, including light/dark.

Theme:
- useTheme hook, three-state cycle (system / light / dark) persisted
  to localStorage.
- :root[data-theme=...] vars override the prefers-color-scheme
  default; :root:not([data-theme]) keeps OS preference for "system".
- Theme button in the header shows current state with a glyph.

Phase 3 readiness:
- The SPA is now feature-complete enough to ship as the BizerOS
  Knowledge web client. Phase 3 swaps the docker image's bundle from
  the Logseq SPA to packages/notes-app/dist and proxies /api to the
  file-api service.
@kelsi-bizer
kelsi-bizer marked this pull request as ready for review May 9, 2026 16:55
@kelsi-bizer
kelsi-bizer merged commit a5c3672 into master May 9, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants