diff --git a/.claude/skills/rustmotion/SKILL.md b/.claude/skills/rustmotion/SKILL.md index 0de2b219..3f65bb75 100644 --- a/.claude/skills/rustmotion/SKILL.md +++ b/.claude/skills/rustmotion/SKILL.md @@ -919,7 +919,14 @@ Animates each character or word independently with staggered timing. Use `char_* | --------------- | ------------------ | ----------- | | `border-radius` | f32 | `null` | -**Shape types:** `rect`, `circle`, `rounded_rect`, `ellipse`, `triangle`, `star` (with `points`, default 5), `polygon` (with `sides`, default 6), `path` (with `data` SVG path string) +**Shape types.** `ShapeType` is externally tagged: the plain variants are strings, the parameterised ones are single-key objects. Writing `"shape": "star"` fails with `invalid type: unit variant, expected struct variant`. + +```json +"shape": "rect" // also: circle, rounded_rect, ellipse, triangle +"shape": { "star": { "points": 6 } } // default 5 +"shape": { "polygon": { "sides": 6 } } // default 6 +"shape": { "path": { "data": "M0 0 L10 10" } } +``` **Gradient fill (root field):** ```json @@ -2350,7 +2357,9 @@ New style fields available on all components: | ----------------- | ------ | ------- | -------------------------------------------------------- | | `gradient-border` | object | `null` | `{ "colors": ["#f00", "#00f"], "width": 2, "angle": 0 }` — gradient-colored border ring, border-radius aware, painted instead of `border` when both are set | -`stagger` and `timeline` are **root fields** (siblings of `style`), not style fields — see [rules/component-field-placement.md](rules/component-field-placement.md). `motion-path` does not exist in the current schema (leftover from the pre-CSS `LayerStyle` model) — there is no motion-path-following mechanism today. +`stagger` and `timeline` are **root fields** (siblings of `style`), not style fields — see [rules/component-field-placement.md](rules/component-field-placement.md). + +There is no `motion-path` *style* property — that name is a leftover from the pre-CSS `LayerStyle` model and was removed. To move a component along a path, use the **`motion_path` animation effect** (snake_case), which takes SVG path data and can orient the component along the tangent — see [rules/motion-path.md](rules/motion-path.md). The two spellings are one character apart and mean different things: `motion-path` in `style` is dropped, `motion_path` in `animation` works. **Deprecated (accepted but never rendered — the validator warns):** diff --git a/crates/rustmotion/src/tests.rs b/crates/rustmotion/src/tests.rs index f0e6da95..3c0fc6b1 100644 --- a/crates/rustmotion/src/tests.rs +++ b/crates/rustmotion/src/tests.rs @@ -163,6 +163,41 @@ mod component_smoke { const COMPONENT_ALIASES: &[(&str, &str)] = &[("container", "div"), ("progress_bar", "progress")]; + /// The exact `shape` spellings SKILL.md documents must parse. + /// + /// `ShapeType` is externally tagged, and the skill used to describe the + /// parameterised variants as `star` "(with `points`)", which reads as a + /// sibling field and fails with `invalid type: unit variant, expected + /// struct variant`. The generator writes what the skill says, so a wrong + /// line there is not a documentation nit — it is a stream of invalid + /// scenarios. Pin the spellings. + #[test] + fn skill_documented_shape_spellings_parse() { + use rustmotion_core::schema::ShapeType; + + for spelling in [ + r#""rect""#, + r#""circle""#, + r#""rounded_rect""#, + r#""ellipse""#, + r#""triangle""#, + r#"{ "star": { "points": 6 } }"#, + r#"{ "polygon": { "sides": 6 } }"#, + r#"{ "path": { "data": "M0 0 L10 10" } }"#, + ] { + serde_json::from_str::(spelling).unwrap_or_else(|e| { + panic!("SKILL.md documents `{spelling}`, which does not parse: {e}") + }); + } + + // …and the shape the skill used to imply must still be rejected, so a + // future edit cannot quietly reintroduce it. + assert!( + serde_json::from_str::(r#""star""#).is_err(), + "a bare `star` must stay an error: it is what the old wording produced" + ); + } + #[test] fn all_components_serde_round_trip() { // deserialize → serialize → deserialize → serialize: the canonical diff --git a/examples/cloud-iam.mp4 b/examples/cloud-iam.mp4 new file mode 100644 index 00000000..c1c44017 Binary files /dev/null and b/examples/cloud-iam.mp4 differ diff --git a/examples/effect-ts.mp4 b/examples/effect-ts.mp4 new file mode 100644 index 00000000..4acc0fc7 Binary files /dev/null and b/examples/effect-ts.mp4 differ