Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions .claude/skills/rustmotion/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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):**

Expand Down
35 changes: 35 additions & 0 deletions crates/rustmotion/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<ShapeType>(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::<ShapeType>(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
Expand Down
Binary file added examples/cloud-iam.mp4
Binary file not shown.
Binary file added examples/effect-ts.mp4
Binary file not shown.
Loading