Skip to content

feat(M7): pages, Liquid Glass dock + UI library#11

Merged
pedrobritx merged 1 commit into
mainfrom
claude/vigilant-davinci-3h3rt
May 29, 2026
Merged

feat(M7): pages, Liquid Glass dock + UI library#11
pedrobritx merged 1 commit into
mainfrom
claude/vigilant-davinci-3h3rt

Conversation

@pedrobritx
Copy link
Copy Markdown
Owner

Milestone 7, built against the three supplied Apple PencilKit / iOS-style design frames: the Liquid Glass UI library, the bottom drawing dock, the color picker, multi-page boards, and a light/dark theme toggle.

What's in it

@notux/ui — Liquid Glass library (was an empty stub)

  • Theme system (useTheme/applyTheme/getInitialTheme): light + dark token sets on [data-theme], persisted to localStorage, defaulting to OS preference; applied before first paint (no flash).
  • Glass primitives: GlassPanel, GlassButton, Popover (portal + speech-bubble tail), Sheet (bottom sheet on narrow screens), Segmented, Slider (opacity track), Swatch (rainbow-ring variant).
  • Faithful SVG instruments (pen, fineliner, highlighter, eraser, pencil, marker) that lift when active.
  • Single design-system stylesheet exported as @notux/ui/styles.css.

Dock (Frames 1 & 2)

  • Bottom-centered glass dock replaces the old left ToolPalette: instruments + rainbow color swatch + a "+" tray (select / shapes / text / import / theme toggle).
  • Per-instrument settings (dockStore): each instrument remembers its color, width and opacity and pushes resolved values into toolStore so the canvas tools pick them up. The active instrument lifts; tapping it opens a width-preset + opacity popover.

Color picker (Frame 3)

  • Grid + Sliders tabs, opacity slider, saved swatches (persisted to localStorage), and the EyeDropper API where supported. (Spectrum tab intentionally omitted per the agreed scope.)

Pages

  • Synced ordered page list in the Yjs doc (packages/sync/src/pageList.ts) with seeding that migrates existing single-page boards (keeps page-0 content selectable).
  • pageStore mirrors shapeStore's Yjs-binding/revision pattern; the active page is local per-user. Board threads the active pageId into CanvasStage/SelectionInspector; a navigator pill + tray handles add / switch / rename / delete / reorder.

Stroke pipeline

  • Added opacity + style to ToolOptions / YStroke / DraftStroke; PenTool writes them; StrokeRenderer / OverlayLayer apply style-specific paint (highlighter = multiply) without double-applying the Group opacity already handled in ShapesLayer. The old highlighter ×4 size hack is removed (widths are now WYSIWYG).

Theming

  • Theme tokens moved into the UI library; Konva layers read theme colors via a small cssVar() helper and re-render on toggle. Inspector + home restyled to tokens.

Scope decisions (confirmed with the requester)

  • Light + Dark with a toggle • Faithful SVG instrumentsRuler omitted this milestone • Faithful color picker (Grid + Sliders, no Spectrum).

Verification

  • pnpm -r typecheck — all 5 packages clean.
  • pnpm build — full production build succeeds (Vite, 340 modules; @notux/ui CSS bundled).
  • Page-list logic (compiled with tsc, run on Node against real yjs): fresh-seed, idempotent seeding, migration of existing page-0 boards, multi-page migration, add / rename / reorder / delete (delete also drops the page's shapes), and cross-Y.Doc replication (the multiplayer path). 11/11 pass.
  • Dock state machine (compiled, run on Node): selectInstrument pushes the resolved preset into toolStore; per-instrument color/width/opacity memory survives switching; eraser → eraser tool; highlighter width is no longer ×4. 10/10 pass.

⚠️ No browser/visual verification. This sandbox has no Chromium and no Playwright/headless browser, so the rendered dock, popover, color picker, page navigator and the theme toggle have not been smoke-tested visually. Recommend a manual pnpm dev pass (open /board/<id>) before marking ready for review — in particular: dock layout vs. the frames, popover/sheet positioning, and the light↔dark flip.

Notes

  • A Page type / DB table already existed but was unused; this PR syncs page metadata via Yjs (consistent with how shapes sync). Server-side page persistence and live page thumbnails are left as follow-ups.
  • ToolPalette.tsx and its CSS were removed (superseded by the dock); its image/PDF import logic moved into the dock's "+" tray.

Generated by Claude Code

Build out Milestone 7 against the supplied PencilKit-style design frames:
a Liquid Glass component library, the bottom drawing dock, the iOS color
picker, multi-page boards, and a light/dark theme toggle.

packages/ui (Liquid Glass library)
- Theme system (useTheme/applyTheme/getInitialTheme): light + dark token
  sets on [data-theme], persisted to localStorage, defaulting to OS preference.
- Glass primitives: GlassPanel, GlassButton, Popover (portal + speech-bubble
  tail), Sheet (bottom sheet on narrow screens), Segmented, Slider (opacity
  track), Swatch (rainbow ring variant).
- Faithful SVG drawing instruments (pen, fineliner, highlighter, eraser,
  pencil, marker) that lift when active.
- Single design-system stylesheet exported as @notux/ui/styles.css.

Dock (Frames 1 & 2)
- Bottom-centered glass dock replaces the old left ToolPalette: instruments +
  rainbow color swatch + "+" tray (select/shapes/text/import/theme toggle).
- Per-instrument settings (dockStore) — each instrument remembers its color,
  width and opacity and pushes resolved values into toolStore so the canvas
  tools pick them up. Active instrument lifts; tapping it opens a width-preset
  + opacity popover.

Color picker (Frame 3)
- Grid + Sliders tabs, opacity slider, saved swatches (persisted), and the
  EyeDropper API where supported.

Pages
- Synced ordered page list in the Yjs doc (sync/pageList.ts) with seeding that
  migrates existing single-page boards. pageStore mirrors shapeStore's
  Yjs-binding/revision pattern; active page is local per-user. Board threads
  the active pageId into CanvasStage/SelectionInspector; navigator pill +
  tray for add/switch/rename/delete/reorder.

Stroke pipeline
- Add opacity + style to ToolOptions/YStroke/DraftStroke; PenTool writes them
  (the old highlighter x4 size hack is removed); StrokeRenderer/OverlayLayer
  apply style-specific paint (highlighter = multiply) without double-applying
  the Group opacity already handled in ShapesLayer.

Theming
- CSS tokens moved into the UI library; canvas Konva layers read theme colors
  via cssVar() and re-render on toggle. Inspector/home restyled to tokens.
@pedrobritx pedrobritx marked this pull request as ready for review May 29, 2026 17:27
@pedrobritx pedrobritx merged commit 86845c7 into main May 29, 2026
4 checks passed
@pedrobritx pedrobritx deleted the claude/vigilant-davinci-3h3rt branch May 29, 2026 17:27
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