add motion to dialog

This commit is contained in:
2026-10-30 10:32:47 +07:00
parent c4955cca18
commit c0aa186d12
2 changed files with 7 additions and 3 deletions
+5 -1
View File
@@ -255,7 +255,11 @@ impl RenderOnce for Dialog {
.items_center()
.justify_center()
.p_4()
.child(scrim)
.child(scrim.with_animation(
"dialog-scrim-enter",
Animation::new(enter_duration).with_easing(ease_out_quint()),
|scrim, delta| scrim.opacity(delta),
))
.child(panel.with_animation(
"dialog-enter",
Animation::new(enter_duration).with_easing(ease_out_quint()),
+2 -2
View File
@@ -215,7 +215,7 @@ 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 |
| 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 |
| 14 | core + theme | Motion (per component) | Replaces the reverted 2026-10-30 framework attempt — no token tower, no `motion` module, no ghost panels; just gpui's own primitives used inline, one separately reviewed pass per component, each a few lines: (a) theme: ✅ landed — `reapply` forwards `reduce_motion` via `cx.set_reduce_motion`, so gpui snaps every animation under the OS setting; (b) Switch: ✅ landed — the thumb absolute-positions in the track and slides on `with_spring` (inline `SpringConfig::new(500, 35, 1)`, `Pixels` target, mounts at its target so the initial render never animates; velocity survives mid-flight retargets); (c) Toast: ✅ landed — each toast slides up 8 px into its stack slot on `with_animation` at `Motion.overlay` with `ease_out_quint` (margin-driven, so only the entering toast moves; keyed per entry so the clock survives unrelated stack re-renders); (d) Dialog: the scrim enters with the panel instead of snapping; (e) Progress: cap the indeterminate sweep at 30 fps. Overlay enter fades already exist from units 11/12. Exits and hover washes stay out — they were the complexity sink (§ deferred list). Each pass reviewed in the gallery on its own |
| 14 | core + theme | Motion (per component) | Replaces the reverted 2026-10-30 framework attempt — no token tower, no `motion` module, no ghost panels; just gpui's own primitives used inline, one separately reviewed pass per component, each a few lines: (a) theme: ✅ landed — `reapply` forwards `reduce_motion` via `cx.set_reduce_motion`, so gpui snaps every animation under the OS setting; (b) Switch: ✅ landed — the thumb absolute-positions in the track and slides on `with_spring` (inline `SpringConfig::new(500, 35, 1)`, `Pixels` target, mounts at its target so the initial render never animates; velocity survives mid-flight retargets); (c) Toast: ✅ landed — each toast slides up 8 px into its stack slot on `with_animation` at `Motion.overlay` with `ease_out_quint` (margin-driven, so only the entering toast moves; keyed per entry so the clock survives unrelated stack re-renders); (d) Dialog: ✅ landed — the scrim enters with the panel (same `Motion.overlay` timing and easing, its own `dialog-scrim-enter` animation id so the clocks start in the same frame); (e) Progress: cap the indeterminate sweep at 30 fps. Overlay enter fades already exist from units 11/12. Exits and hover washes stay out — they were the complexity sink (§ deferred list). Each pass reviewed in the gallery on its own |
| 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. |
| editor | editor (new) | Text/code editor, syntax highlighting (D12) | Same gate. |
@@ -319,7 +319,7 @@ Dropped from rev 3: D2, D5, D9 (port-era decisions); the review gate returns in
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.
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. **Next: unit 14 — motion, per component (§6 row 14, D21)** — ~~(a) theme `reduce_motion` → `cx.set_reduce_motion` in `reapply`~~ ✅ landed; ~~(b) Switch thumb `with_spring`~~ ✅ landed. Remaining passes, each small and separately reviewed: (d) Dialog scrim enters with the panel; (e) Progress 30 fps cap. No shared machinery; exits and hover washes stay deferred (§6 deferred list).
6. **Next: unit 14 — motion, per component (§6 row 14, D21)** — ~~(a) theme `reduce_motion` → `cx.set_reduce_motion` in `reapply`~~ ✅ landed; ~~(b) Switch thumb `with_spring`~~ ✅ landed. Remaining passes, each small and separately reviewed: (e) Progress 30 fps cap. No shared machinery; exits and hover washes stay deferred (§6 deferred list).
7. Then — Phase F: `crates/data` (List, Table, Tree, Tabs, Sidebar) + Windows/GNOME/KDE/Omarchy theme sources (a source may state `Motion.overlay` when it needs platform timing, §5.5) + Segoe Fluent/freedesktop icon resolvers, with side-by-side gallery screenshots per platform. NumberInput/multiline return as deferred units when needed.
8. Then — Phase G: pickers, polish, → 0.1; start `crates/editor` if wanted.