You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/eidos/components/motion
dev fe597f3fa9
fix(motion): audit follow-ups — spring reduced-motion, Motion+loop exit, loop tokens
4 months ago
..
README.md feat(motion): `<Motion>` wrapper — content animate-in/out primitive, (b) step 3 4 months ago
index.ts feat(motion): `<Motion>` wrapper — content animate-in/out primitive, (b) step 3 4 months ago
motion.svelte fix(motion): audit follow-ups — spring reduced-motion, Motion+loop exit, loop tokens 4 months ago
types.ts feat(motion): `<Motion>` wrapper — content animate-in/out primitive, (b) step 3 4 months ago

README.md

Motion

A single-element content animator (RFC §D.12 — the content domain). Wrap any content you want to animate in and out; it rides the existing state-presets + reduced-motion — no new mechanism, no JS engine. Same motion selector as the overlays and <Cascade>.

<script>
  import { Motion } from '$uix/eidos/components/motion'
  let show = $state(true)
</script>

{#if show}
  <Motion motion="scale-fade">
    <div class="card">…</div>
  </Motion>
{/if}

motion is any registered preset (fade / scale-fade / slide-fade / …); 'none' disables. The keyframe / duration / easing / reduced-motion all come from the preset.

How it works

Phase Mechanism
enter (on mount) motionAttrs(motion) puts data-animation-style + a presentation data-state="open" on the element → the EXISTING [data-animation-style][data-state='open'] enter rule plays once. Flash-free (attrs at insertion, backwards fill).
exit (on removal) Svelte out: flips the node to data-state='closed' (the existing exit rule plays) and retains it for the eidos-declared duration (read via the ActiveDom getComputedStyle), then unmounts.

The wrapper writes no visual var and runs no JS animation — it only sets the state attr and holds the node during exit. Eidos owns the keyframes.

<Motion> vs motionAttrs

Use Extra node Exit
<Motion> wrap content to animate in/out yes (a real box — needed for transform/opacity) ✓ (out: retention)
motionAttrs(preset) spread onto your OWN element no — (enter only; you manage exit)

Reach for motionAttrs when an extra wrapper would disrupt layout (inline content) and you only need the entrance; reach for <Motion> when you want the full in/out lifecycle.

Domain boundary

Motion is the content domain only — content that simply appears/disappears, with no semantic event and no state machine. Do not wrap:

  • a stateful component (its own data-state: a Card's selected/idle, a checkbox's checked) — Motion's presentation data-state would clash; that component selects its preset via its own motion prop tied to its own state.
  • an event surface (an overlay's emerge, a commit) — the firma owns the motion; the prop there is an override, not a wrapper.

Props

Prop Type Default Notes
motion MotionPresetName 'fade' The preset played on mount (enter) and removal (exit). 'none' disables.

Plus any HTMLAttributes<HTMLDivElement>.

Decisions

  • No recipe, no morfo events. Motion is structural lifecycle + a preset selector; the morfo (scope: ['eidos']) declares only the data-state of its single part. It reuses the motion registry + the state-presets — it adds no keyframes of its own.
  • Reuses data-state, not a bespoke trigger. The content domain fires via a constant presentation data-state="open" (the <Cascade.Item> pattern), so the existing enter/exit + reduced-motion rules apply verbatim and the generator stays untouched (RFC §D.12).
  • A real box, not display: contents. The transform/opacity need a layout box. For zero-extra-node, use motionAttrs on your own element.

Powered by TurnKey Linux.