plans/README.md: index, execution order 000->005, executor ground rules (test gate, DSL landmines) 000: shared craft crate (easing/duration/color tokens, Pressable, CraftToast, motion math + units) 001: HIGH press contract - feedback on down, commit on up-if-over, 0.96 scale (all 3 crates) 002: MEDIUM toast enter/exit, interruptible, reduced-motion aware (all 3 crates) 003: MEDIUM insurance sheet momentum projection + velocity-handoff settle, rubber-band 004: MEDIUM koboyo drawer slide, origin-aware popovers, animated camera fit 005: LOW polish - color tokens, concentric radii, real icons, tabular figures
4.7 KiB
4.7 KiB
000 — Create the shared craft crate
- Status: TODO
- Commit:
d50006e - Severity: infra (prerequisite for 001–005)
- Category: Cohesion & tokens
- Estimated scope: 1 new crate (~5 files), 1 patch edit, 3 Cargo.toml edits
Problem
Three crates re-implement chrome independently with zero shared motion language: no easing
tokens, no shared pressable, three copy-pasted toast blocks, brand hex repeated per widget
(insurance/src/app.rs:31,108,122,170 — #7b5cf6, #8a74ff, #f7a982…). Every subsequent
plan needs one home for the house values, or the fix itself becomes three drifting copies.
Target
New workspace member makepad-ports/craft/ (crate name makepad-example-craft, copied to
examples/craft by setup_makepad.sh, same layout as the other three), exporting:
script_modtokens stored on themodobject (the only cross-file sharing mechanism):mod.craft.ease_out_strong=Ease.Bezier {cp0: 0.23, cp1: 1.0, cp2: 0.32, cp3: 1.0}mod.craft.ease_in_out_strong=Ease.Bezier {cp0: 0.77, cp1: 0.0, cp2: 0.175, cp3: 1.0}mod.craft.ease_sheet=Ease.Bezier {cp0: 0.32, cp1: 0.72, cp2: 0.0, cp3: 1.0}mod.craft.ease_polish=Ease.Bezier {cp0: 0.2, cp1: 0.0, cp2: 0.0, cp3: 1.0}- durations:
dur_press_release: 0.15,dur_hover: 0.1,dur_popover: 0.2,dur_drawer: 0.25,dur_toast_in: 0.3,dur_toast_out: 0.2
Pressablewidget (Rust:#[derive(Script, ScriptHook, Widget, Animator)]) — full spec in plan 001; defined here, adopted there.CraftToastwidget — full spec in plan 002.reduce_motion:pub fn play_or_cut(reduce: bool, cx, w: &mut impl AnimatorImpl, st)helper (RECIPES.md §6) + a#[rust] reduce_motion: boolconvention documented in the crate docs. Defaultfalse.src/model.rs-style pure modulemotion.rswith unit-testable math:pub fn project(v_px_per_s: f64, rate: f64) -> f64→(v/1000.0)*rate/(1.0-rate)pub fn rubberband(over: f64, dim: f64) -> f64→over*dim*0.55/(dim+0.55*over.abs())pub fn settle(from: f64, target: f64, v0: f64, lambda: f64, t: f64) -> (f64 /*pos*/, bool /*done*/)— exponential settle:x = (d + (v0 + λd)t)·e^(−λt), done when|x| < 0.5 && |v0·e^(−λt)| < 10.0
Repo conventions to follow
- Crate skeleton: copy
makepad-ports/insurance/structure (src/{lib,main,app,model}.rs,tests/), Cargo.toml identical shape (makepad-widgets = { path = "../../widgets", version = "2.0.0" }). - Workspace registration: extend
patches/makepad-dev-headless-linux.patchwhere it already inserts members (+ "examples/rider",etc.) with+ "examples/craft",; keep the patch applying cleanly against dev @b41e740(git apply --check). - Consumers add
makepad-example-craft = { path = "../craft" }and callmakepad_example_craft::script_mod(vm)before their ownscript_modinApp::run. - Widget registration exemplar: the
let ChatList = #(ChatList::register_widget(vm)) {…}pattern noted inmakepad-ports/README.mdbug 3.
Steps
- Create
craft/Cargo.toml,src/lib.rs(exportsscript_mod,motion, widgets),src/motion.rswith the three functions +#[cfg(test)]unit tests (below). - Create
src/widgets.rs:Pressable+CraftToastRust structs and theirscript_mod!block registeringmod.craft.*tokens and both widgets. - Edit the patch: add
"examples/craft"toworkspace.members; updatesetup_makepad.shcopy step to includecraft. - Add the dep +
script_modcall torider,koboyo,insurance(no behavior change yet). - Unit tests in
motion.rs:project(1000.0, 0.998)≈499.0(±0.5);project(0.0, _) == 0.0; sign followsv.rubberbandis monotonic,< over, andrubberband(0.0, d) == 0.0.settlereachesdonewithposwithin0.5oftargetfor(from=200, target=0, v0=−800, λ=12)beforet = 1.0; position is continuous att=0(pos(0) == from).
Boundaries
- Do NOT move any existing UI into the crate yet (that's 001/002).
- Do NOT touch
reference/,uploads/, or the three apps'model.rs. - Do NOT add third-party dependencies.
- If the patch no longer applies to dev @
b41e740, STOP and report — do not rebase upstream.
Verification
- Mechanical:
cargo test -p makepad-example-craft --libgreen (new tests);cargo test -p makepad-example-{rider,koboyo,insurance} --lib --test integrationstill 21/9, 29/14, 28/14;git apply --checkpasses on a fresh checkout. - Done when: all four crates build, tokens are reachable from a consumer
script_mod!block asmod.craft.ease_out_strong, and the 140-test baseline is intact.