update plan
This commit is contained in:
+9
-5
@@ -153,6 +153,7 @@ The set stays role-minimal and grows one concept at a time, driven by the unit t
|
|||||||
- ~~**Overlay scrim + shadow/elevation tokens**~~ — ✅ landed with unit 11 (2026-10-29): `colors.overlay` (translucent-black scrim, denser in dark; TOML-overridable; no platform states one), `Radius.overlay` (10 pt), `Elevations.popover`/`dialog` (transcribed NSPopover-class shadows, builder → `Vec<BoxShadow>`), and `Motion.overlay` (200 ms enter transition). Popover consumes elevation + motion; the scrim waits for Dialog.
|
- ~~**Overlay scrim + shadow/elevation tokens**~~ — ✅ landed with unit 11 (2026-10-29): `colors.overlay` (translucent-black scrim, denser in dark; TOML-overridable; no platform states one), `Radius.overlay` (10 pt), `Elevations.popover`/`dialog` (transcribed NSPopover-class shadows, builder → `Vec<BoxShadow>`), and `Motion.overlay` (200 ms enter transition). Popover consumes elevation + motion; the scrim waits for Dialog.
|
||||||
- ~~**Scrollbar thumb token + metrics**~~ — ✅ landed with the ScrollArea unit (2026-10-29): `colors.scrollbar_thumb` (translucent over content: black in light, light gray in dark; TOML-overridable) and `Theme.scrollbar` (`width` 8 pt, `inset` 2 pt, `min_thumb` 24 pt).
|
- ~~**Scrollbar thumb token + metrics**~~ — ✅ landed with the ScrollArea unit (2026-10-29): `colors.scrollbar_thumb` (translucent over content: black in light, light gray in dark; TOML-overridable) and `Theme.scrollbar` (`width` 8 pt, `inset` 2 pt, `min_thumb` 24 pt).
|
||||||
- ~~**`success` / `warning` roles**~~ — ✅ landed with Toast (2026-10-29): `colors.success`/`warning` (+ foregrounds; light and dark variants; TOML-overridable; no platform states them) and derived `Ramps.success`/`warning` via the OKLCH engine, matching the destructive treatment.
|
- ~~**`success` / `warning` roles**~~ — ✅ landed with Toast (2026-10-29): `colors.success`/`warning` (+ foregrounds; light and dark variants; TOML-overridable; no platform states them) and derived `Ramps.success`/`warning` via the OKLCH engine, matching the destructive treatment.
|
||||||
|
- ~~**Motion tokens**~~ — attempted (unit 14, 2026-10-30) and reverted the same day: the working set (`Curve` + CSS cubic-bezier, `Springs` presets, `[motion]` TOML overrides, an ungated `motion` module with an exit-lifecycle state machine and spring-blended hover washes, exit ghosts on all three overlays, a spring Switch thumb, a store-held toast exiting list) judged too complex for the value, and the motion itself not good enough. The motion system goes back to the drawing board — see the unit 14 row (§6) for what was tried. Two cheap pieces remain worth taking regardless of the rethink: forwarding `reduce_motion` to `cx.set_reduce_motion` in `reapply` (the OS flag is still read but ignored — every animation shipped so far disobeys Reduce Motion), and a 30 fps cap on Progress's indeterminate repeat.
|
||||||
- **`knob` / control-fill role** — only if Slider (unit 7) confirms the Switch's borrowed roles (`primary_foreground` thumb, `border` off-track) as a second consumer; until then no expansion.
|
- **`knob` / control-fill role** — only if Slider (unit 7) confirms the Switch's borrowed roles (`primary_foreground` thumb, `border` off-track) as a second consumer; until then no expansion.
|
||||||
|
|
||||||
Controls through unit 10 paint from existing roles and ramps.
|
Controls through unit 10 paint from existing roles and ramps.
|
||||||
@@ -174,7 +175,7 @@ Every target supplies one accent color (or a stated ramp). Where the platform st
|
|||||||
|
|
||||||
### 5.5 Native metrics
|
### 5.5 Native metrics
|
||||||
|
|
||||||
Native feel is half geometry. Per-platform tables for: control heights and paddings, corner radii (WinUI control vs card rounding; macOS control radii), font fallback lists resolved through `.SystemUIFont` (SF Pro / Segoe UI Variable / Adwaita Sans / Noto Sans — no fonts bundled), focus-ring policy (macOS keyboard ring, WinUI two-layer ring, GTK outline), scrollbar style (overlay vs inline), popup elevation and menu metrics. Values are transcribed from each toolkit's reference metrics and verified with side-by-side screenshots (macOS in Phase B, the rest in Phase F).
|
Native feel is half geometry. Per-platform tables for: control heights and paddings, corner radii (WinUI control vs card rounding; macOS control radii), font fallback lists resolved through `.SystemUIFont` (SF Pro / Segoe UI Variable / Adwaita Sans / Noto Sans — no fonts bundled), focus-ring policy (macOS keyboard ring, WinUI two-layer ring, GTK outline), scrollbar style (overlay vs inline), popup elevation and menu metrics. Motion presets are metrics too: each platform states its curves and durations (macOS tuned to NSPopover/NSMenu transitions, Windows the Fluent decelerate cubic-bezier, GNOME/KDE shell timings) — the token shape is open again after the unit 14 revert, and Phase F sources fill it once the rethink lands. Values are transcribed from each toolkit's reference metrics and verified with side-by-side screenshots (macOS in Phase B, the rest in Phase F).
|
||||||
|
|
||||||
### 5.6 Custom themes
|
### 5.6 Custom themes
|
||||||
|
|
||||||
@@ -213,11 +214,12 @@ Each row is one review unit: build it, show it in the gallery, review, then move
|
|||||||
| 12 | core | Menu | ✅ Landed (2026-10-29). Controlled `open`/`on_change` + `trigger`/`items` (MenuItem: label, icon, shortcut hint, disabled, destructive, checked, separator). Popover shell patterns duplicated per D16 (promote at Dialog); panel = surface + overlay radius + popover elevation, role Menu; claims focus while open; keyboard nav — arrows/home/end over selectable items (wrapping, skipping separators + disabled), enter/space activates (closes menu before the action), escape dismisses; hover selects, click activates; trigger clicks toggle (popover-owned); selection resets on each open; long menus scroll via the ScrollArea once a height is styled. Deferred: submenus, type-ahead, scroll-selected-item-into-view, real shortcut handling |
|
| 12 | core | Menu | ✅ Landed (2026-10-29). Controlled `open`/`on_change` + `trigger`/`items` (MenuItem: label, icon, shortcut hint, disabled, destructive, checked, separator). Popover shell patterns duplicated per D16 (promote at Dialog); panel = surface + overlay radius + popover elevation, role Menu; claims focus while open; keyboard nav — arrows/home/end over selectable items (wrapping, skipping separators + disabled), enter/space activates (closes menu before the action), escape dismisses; hover selects, click activates; trigger clicks toggle (popover-owned); selection resets on each open; long menus scroll via the ScrollArea once a height is styled. Deferred: submenus, type-ahead, scroll-selected-item-into-view, real shortcut handling |
|
||||||
| 11 | core | Popover | ✅ Landed (2026-10-29). First overlay. Controlled `open` + `on_change` (Rc-shared handler); `trigger`/`content` element closures; panel = surface + `Radius.overlay` + `Elevations.popover` + border, role Dialog with label; `anchored()` + `deferred()` (window-overflow flip for free); enter fade via gpui `with_animation` at `Motion.overlay` (respects reduce-motion); claims keyboard focus while open; escape and click-outside dismiss (outside clicks swallowed). No scrim — native macOS popover model; the overlay token waits for Dialog. Known v1 gaps: no exit animation, trigger aria-expanded left to the app |
|
| 11 | core | Popover | ✅ Landed (2026-10-29). First overlay. Controlled `open` + `on_change` (Rc-shared handler); `trigger`/`content` element closures; panel = surface + `Radius.overlay` + `Elevations.popover` + border, role Dialog with label; `anchored()` + `deferred()` (window-overflow flip for free); enter fade via gpui `with_animation` at `Motion.overlay` (respects reduce-motion); claims keyboard focus while open; escape and click-outside dismiss (outside clicks swallowed). No scrim — native macOS popover model; the overlay token waits for Dialog. Known v1 gaps: no exit animation, trigger aria-expanded left to the app |
|
||||||
| 11+ | core | Tooltip ✅ (2026-10-29), Dialog + AlertDialog ✅ (2026-10-29), Toast ✅ (2026-10-29) | One unit each, same gate. Tooltip rides gpui's own `.tooltip()` lifecycle (hover delay, anchoring, dismissal — all framework-owned); ours is the styled view (`surface` + border + `Radius.sm`, small text) plus a `Tooltip::text` closure and a Button passthrough. Dialog + AlertDialog (one component, `alert(true)` switches semantics): scrim (`colors.overlay`, occluding) + centered panel (surface, `Radius.overlay`, `Elevations.dialog`), role Dialog/AlertDialog, focus claimed while open; modal kind closes on escape + scrim click, alert kind is inert to both (the user answers through the actions); actions footer is caller-built elements closing through owner state. Toast: `Toasts` store entity (push/dismiss/clear + auto-dismiss timers on the GPUI executor, `Toast::DURATION` 5 s, zero = sticky) + `ToastsView` deferred stack (top-right, `Radius.overlay` + popover elevation, severity icon from the new success/warning ramps, close button, `on_dismiss` windowless handler). Toast landed the deferred `success`/`warning` tokens (§5.2). Sheet dropped from the roadmap |
|
| 11+ | core | Tooltip ✅ (2026-10-29), Dialog + AlertDialog ✅ (2026-10-29), Toast ✅ (2026-10-29) | One unit each, same gate. Tooltip rides gpui's own `.tooltip()` lifecycle (hover delay, anchoring, dismissal — all framework-owned); ours is the styled view (`surface` + border + `Radius.sm`, small text) plus a `Tooltip::text` closure and a Button passthrough. Dialog + AlertDialog (one component, `alert(true)` switches semantics): scrim (`colors.overlay`, occluding) + centered panel (surface, `Radius.overlay`, `Elevations.dialog`), role Dialog/AlertDialog, focus claimed while open; modal kind closes on escape + scrim click, alert kind is inert to both (the user answers through the actions); actions footer is caller-built elements closing through owner state. Toast: `Toasts` store entity (push/dismiss/clear + auto-dismiss timers on the GPUI executor, `Toast::DURATION` 5 s, zero = sticky) + `ToastsView` deferred stack (top-right, `Radius.overlay` + popover elevation, severity icon from the new success/warning ramps, close button, `on_dismiss` windowless handler). Toast landed the deferred `success`/`warning` tokens (§5.2). Sheet dropped from the roadmap |
|
||||||
|
| 14 | core + theme | Motion | ⏪ Attempted and reverted (2026-10-30). What was tried: theme `Motion` tokens (overlay duration + `Curve` with a CSS cubic-bezier + spring presets, `[motion]` TOML); an ungated core `motion` module (curve→easing, `ExitLifecycle` exit ghosts via keyed window state, spring hover washes); consumers — exit ghosts on Popover/Menu/Dialog (scrim fading both ways), Switch thumb on `with_spring`, Toast fade/slide + a store-held exiting list, Button + toast-close hover washes, Progress capped at 30 fps. All reverted — judged too complex for the value and not good enough to watch. The rethink starts from what the attempt proved: gpui's `with_spring`/`with_animation` are the right substrate (D21) and keyed window state CAN drive overlay exits; the cost centered on the exit-lifecycle plumbing and per-control wash machinery. Keep the plan open, redesign before reimplementing |
|
||||||
| then | data (new) | List, Table, Tree, Tabs, Sidebar | Created on demand, same gate. |
|
| then | data (new) | List, Table, Tree, Tabs, Sidebar | Created on demand, same gate. |
|
||||||
| then | pickers or data | Calendar/DatePicker, TimeField, ColorPicker | Decide at unit time. |
|
| then | pickers or data | Calendar/DatePicker, TimeField, ColorPicker | Decide at unit time. |
|
||||||
| editor | editor (new) | Text/code editor, syntax highlighting (D12) | Same gate. |
|
| editor | editor (new) | Text/code editor, syntax highlighting (D12) | Same gate. |
|
||||||
|
|
||||||
Deferred until a real need: Markdown/TextView, Dock, VirtualList, window-wide text selection, a motion system (use gpui's built-in animations first), charts.
|
Deferred until a real need: Markdown/TextView, Dock, VirtualList, window-wide text selection, a motion system (unit 14 reverted; rethink before reimplementing), charts.
|
||||||
|
|
||||||
### 6.1 After the core units: sizing API — ✅ landed
|
### 6.1 After the core units: sizing API — ✅ landed
|
||||||
|
|
||||||
@@ -253,6 +255,7 @@ Deferred until a real need: bidi/RTL; prefix/suffix adornments and a form field
|
|||||||
| C — controls | One review unit at a time (§6, units 1–9), each: API per §4.3 + tests + gallery page → review gate. macOS SF Symbols resolver behind the icon seam lands with the first unit that shows it matters | Per unit: activation, controlled round-trip, and disabled inertness tested; gallery page shows the live control against the theme; your approval closes the unit |
|
| C — controls | One review unit at a time (§6, units 1–9), each: API per §4.3 + tests + gallery page → review gate. macOS SF Symbols resolver behind the icon seam lands with the first unit that shows it matters | Per unit: activation, controlled round-trip, and disabled inertness tested; gallery page shows the live control against the theme; your approval closes the unit |
|
||||||
| D — input | Wave 2 | Single-line input with cursor, selection, clipboard; NumberInput |
|
| D — input | Wave 2 | Single-line input with cursor, selection, clipboard; NumberInput |
|
||||||
| E — overlays | Wave 3 | Focus trapping and escape/dismiss semantics per overlay |
|
| E — overlays | Wave 3 | Focus trapping and escape/dismiss semantics per overlay |
|
||||||
|
| E+ — motion | Unit 14 (§6): Motion tokens + reduce-motion forwarding + overlay exits + Switch thumb + hover washes | ⏪ Attempted and reverted (2026-10-30); rethink pending. The reduce-motion forwarding fix and the Progress 30 fps cap stay on the table as standalone wins |
|
||||||
| F — platforms + data | `crates/data` + Windows/GNOME/KDE/Omarchy theme sources + Segoe Fluent/freedesktop icon resolvers | Side-by-side gallery screenshots per platform |
|
| F — platforms + data | `crates/data` + Windows/GNOME/KDE/Omarchy theme sources + Segoe Fluent/freedesktop icon resolvers | Side-by-side gallery screenshots per platform |
|
||||||
| G — pickers + polish | Wave 5 → 0.1; start `crates/editor` if wanted | — |
|
| G — pickers + polish | Wave 5 → 0.1; start `crates/editor` if wanted | — |
|
||||||
|
|
||||||
@@ -304,6 +307,7 @@ Pure tests for resolve/overlay chain, payload parsing (fixtures), icon resolutio
|
|||||||
| D18 | Crate split for consumption: `core` (every-app components) → `editor`, `data`, … (advanced) → thin `gpui-native-kit` facade; one cargo feature per component, additive, module-gated |
|
| D18 | Crate split for consumption: `core` (every-app components) → `editor`, `data`, … (advanced) → thin `gpui-native-kit` facade; one cargo feature per component, additive, module-gated |
|
||||||
| D19 | System icons via semantic `IconRole`s with per-platform resolvers (SF Symbols / Segoe Fluent Icons / freedesktop) and a bundled Lucide fallback; platform glyph sets are used at runtime only, never bundled |
|
| D19 | System icons via semantic `IconRole`s with per-platform resolvers (SF Symbols / Segoe Fluent Icons / freedesktop) and a bundled Lucide fallback; platform glyph sets are used at runtime only, never bundled |
|
||||||
| D20 | Components land one element at a time behind a review gate: API sketch → implementation → tests → gallery page → review → next. gpui-kit `base` is the API-design reference for these units; its conventions (controlled state, one activation path, semantic states, a11y labels) and selected utilities are adopted, simplified |
|
| D20 | Components land one element at a time behind a review gate: API sketch → implementation → tests → gallery page → review → next. gpui-kit `base` is the API-design reference for these units; its conventions (controlled state, one activation path, semantic states, a11y labels) and selected utilities are adopted, simplified |
|
||||||
|
| D21 | Motion is a thin layer over gpui's pinned-rev animation/spring primitives (`with_animation`, `with_spring` with velocity retention, built-in reduce-motion snapping, `max_fps`) — no parallel motion framework (bezel's Painter/Fade store and pulse clock rejected); the theme owns durations, curves (`ease_out_quint` default + CSS-spec `CubicBezier`), and spring presets; hover washes ride settled-spring idleness on controls only, data rows snap. ⏪ Under re-evaluation after the unit 14 revert (2026-10-30): the substrate still holds, the execution complexity does not — the rethink may narrow scope to overlay enters/exits only |
|
||||||
|
|
||||||
Dropped from rev 3: D2, D5, D9 (port-era decisions); the review gate returns in a lighter form as D20. D10 (no icon bundling) is superseded by D19.
|
Dropped from rev 3: D2, D5, D9 (port-era decisions); the review gate returns in a lighter form as D20. D10 (no icon bundling) is superseded by D19.
|
||||||
|
|
||||||
@@ -313,8 +317,8 @@ Dropped from rev 3: D2, D5, D9 (port-era decisions); the review gate returns in
|
|||||||
2. ~~Phase B theme engine core~~ ✅ — resolve pipeline, OKLCH ramps, presets, macOS source + watchers, gallery theme inspector.
|
2. ~~Phase B theme engine core~~ ✅ — resolve pipeline, OKLCH ramps, presets, macOS source + watchers, gallery theme inspector.
|
||||||
3. ~~Phase C controls~~ ✅ — units 1–9 (Button → Avatar), each through the review gate; sizing API (§6.1).
|
3. ~~Phase C controls~~ ✅ — units 1–9 (Button → Avatar), each through the review gate; sizing API (§6.1).
|
||||||
4. ~~Phase D input~~ ✅ — single-line Input (unit 10) + the §6.2 completion pass (modifiers, undo/redo, read-only, actions + key context, caret blink, paint polish). NumberInput and multiline remain open as deferred units.
|
4. ~~Phase D input~~ ✅ — single-line Input (unit 10) + the §6.2 completion pass (modifiers, undo/redo, read-only, actions + key context, caret blink, paint polish). NumberInput and multiline remain open as deferred units.
|
||||||
5. **Phase E overlays (in progress)** — Popover ✅ (unit 11), ScrollArea ✅ (unit 11.5, support). **Next: Unit 12 Menu** — reuses the popover shell + ScrollArea; items with icons/shortcuts/separators, keyboard navigation, activation. Then Tooltip → Dialog/AlertDialog (scrim + focus trap) → Sheet → Toast (brings `success`/`warning` tokens). Phase gate: focus trapping and escape/dismiss semantics per overlay.
|
5. ~~Phase E overlays~~ ✅ — Popover (unit 11), ScrollArea (unit 11.5), Menu (unit 12), Tooltip + Dialog/AlertDialog + Toast (unit 11+ row; Sheet dropped). Phase gate held: escape/dismiss semantics and focus behavior per overlay.
|
||||||
6. Then — Phase F: `crates/data` (List, Table, Tree, Tabs, Sidebar) + Windows/GNOME/KDE/Omarchy theme sources + Segoe Fluent/freedesktop icon resolvers, with side-by-side gallery screenshots per platform. NumberInput/multiline return as deferred units when needed.
|
6. ~~Unit 14 — Motion~~ ⏪ Attempted and reverted (2026-10-30) — judged too complex, and the motion not good enough; the plan and the lessons stay (§6 row 14, D21). Next: **Phase F** — `crates/data` (List, Table, Tree, Tabs, Sidebar) + Windows/GNOME/KDE/Omarchy theme sources (each states its Motion preset, §5.5, once the rethink lands) + Segoe Fluent/freedesktop icon resolvers, with side-by-side gallery screenshots per platform. NumberInput/multiline return as deferred units when needed. Cheap standalone wins to fold in anywhere: `cx.set_reduce_motion` forwarding in `reapply` (§5.2), Progress 30 fps cap.
|
||||||
7. Then — Phase G: pickers, polish, → 0.1; start `crates/editor` if wanted.
|
7. Then — Phase G: pickers, polish, → 0.1; start `crates/editor` if wanted.
|
||||||
|
|
||||||
Batched polish candidates between units: Switch thumb slide (motion now exists), scrollbar auto-hide + horizontal thumb, `Undo`/`Redo` menu events.
|
Batched polish candidates between units: scrollbar auto-hide + horizontal thumb, `Undo`/`Redo` menu events.
|
||||||
|
|||||||
Reference in New Issue
Block a user