Diff Motion
`<pura-diff-motion>` watches its light-DOM children and, on every mutation, computes a *keyed semantic diff* and both narrates and animates it. Where `<pura-auto-animate>` silently FLIP-tweens layout, this answers the agent-facing question "what actually changed?": it emits `diffmotion` `{ added, removed, moved, changed }` (lists of keys) and colour-codes each operation, added items glow green and scale in, moved items FLIP-slide with a blue tint, changed items flash amber. Identity comes from each child's `data-key` (falling back to `id`, then index), and "changed" is detected from a content signature (`data-sig`, falling back to `textContent`). The highlight durations multiply `var(--pura-motion)` so a `<pura-motion-budget>` governor (or reduced motion) can calm or stop the visuals, while the diff event still fires. Each instance registers in `window.__puraDiffMotion` by `data-pura-id` and mirrors the latest counts in `data-pura-diff-*`.
Preview
<pura-diff-motion id="list">
<li data-key="1" data-sig="Buy milk">Buy milk</li>
<li data-key="2" data-sig="Walk dog">Walk dog</li>
</pura-diff-motion>
<script type="module">
const dm = document.getElementById('list');
dm.addEventListener('diffmotion', (e) => console.log(e.detail));
// mutate the children however you like (framework render, manual DOM, etc.)
// -> { added:['3'], removed:[], moved:['2'], changed:[] }
</script> Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Stops observing; children mutate with no diff or animation. |
duration | number | (token) | Overrides the token-derived FLIP duration in milliseconds. |
Installation
pura is copy-paste and dependency-free. Load the whole library, or just this component.
<link rel="stylesheet" href="/pura/tokens.css">
<script type="module" src="/pura/lib/diff-motion.js"></script> import "./pura/lib/diff-motion.js";