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/web/routes/uix/lib/MotionPanel.svelte

88 lines
3.2 KiB

<script lang="ts">
/**
* Motion panel — the animation system as an explorable axis. Most demos
* never surfaced `motion` at all. This applies any preset from the catalog
* to a live sample (the `data-animation-style` + `data-state` content-domain
* pattern), lets you retune the duration / easing tokens, replay on demand,
* and preview the reduced-motion fallback. The selected preset name is the
* value a component's `motion` prop takes where it has one.
*/
import { DURATIONS, EASINGS, MOTION_PRESETS, type MotionKind } from './harness.svelte';
let { note = '' }: { note?: string } = $props();
let preset = $state('scale-fade');
let duration = $state('moderate');
let easing = $state('emphasized');
let reduce = $state(false);
let replayKey = $state(0);
const KINDS: MotionKind[] = ['enter/exit', 'emphasis', 'loop', 'js'];
const current = $derived(MOTION_PRESETS.find((p) => p.name === preset));
const isLoop = $derived(current?.kind === 'loop');
const sampleStyle = $derived(
`--motion-duration-enter: var(--duration-${duration}); --motion-duration-exit: var(--duration-${duration}); --motion-ease-enter: var(--ease-${easing}); --motion-ease-exit: var(--ease-${easing});`
);
</script>
<div data-uix-controls>
<div data-uix-control style="grid-column: 1 / -1;">
<span data-uix-control-label>preset <span data-uix-control-hint>the <code>motion</code> prop value</span></span>
{#each KINDS as kind}
<div data-uix-motion-kind>
<span data-uix-motion-kind-label>{kind}</span>
<span data-uix-chips role="radiogroup">
{#each MOTION_PRESETS.filter((p) => p.kind === kind) as p}
<button data-uix-chip data-active={preset === p.name} onclick={() => (preset = p.name)}>{p.name}</button>
{/each}
</span>
</div>
{/each}
</div>
<label data-uix-control>
<span data-uix-control-label>duration <span data-uix-control-hint>--duration-*</span></span>
<span data-uix-chips role="radiogroup">
{#each DURATIONS as d}
<button data-uix-chip data-active={duration === d} onclick={() => (duration = d)}>{d}</button>
{/each}
</span>
</label>
<label data-uix-control>
<span data-uix-control-label>easing <span data-uix-control-hint>--ease-*</span></span>
<span data-uix-chips role="radiogroup">
{#each EASINGS as e}
<button data-uix-chip data-active={easing === e} onclick={() => (easing = e)}>{e}</button>
{/each}
</span>
</label>
<label data-uix-control>
<span data-uix-control-label>reduced motion <span data-uix-control-hint>data-motion=reduce</span></span>
<span data-uix-switch>
<input type="checkbox" bind:checked={reduce} />
<span data-uix-switch-label>{reduce ? 'on' : 'off'}</span>
</span>
</label>
</div>
<div data-uix-motion-stage>
<div data-uix-motion-sample-wrap data-motion={reduce ? 'reduce' : undefined}>
{#key replayKey}
<div data-uix-motion-sample data-animation-style={preset} data-state="open" style={sampleStyle}>
{preset}
</div>
{/key}
</div>
<div data-uix-motion-stage-foot>
<span data-uix-firma-meta>{current?.blurb}</span>
<button data-uix-play onclick={() => (replayKey += 1)}>↻ {isLoop ? 'remount' : 'replay'}</button>
</div>
</div>
{#if note}
<p data-uix-section-desc style="margin-top: var(--uix-space-4);">{note}</p>
{/if}

Powered by TurnKey Linux.