Rewrite the showcase's Motion section without Tailwind

Plan step 38: the two demo buttons are now real <x-button>s (filled
for Move, text for Change the figure) instead of a hand-rolled state-
layer/focus-ring button; each spring's row and its travelling dot
move onto <x-surface>/<x-stack> plus data-md-showcase-motion-row/
-track/-dot in showcase.css — only the dot's size and colour are
fixed there, since the transition under test stays the spring token
in the view's own inline style.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
Andreas Reinhold / reini
2026-09-15 04:17:45 +02:00
co-authored by Claude Sonnet 5
parent a4b368386d
commit 3669415d57
2 changed files with 51 additions and 30 deletions
+21
View File
@@ -240,4 +240,25 @@
[data-md-showcase-elevation-tile][data-md-elevation='5'] {
box-shadow: var(--md-sys-elevation-5);
}
/* Motion: one spring's row (its name, and a track the dot travels), and the dot itself — its
colour is decoration, its size is the only thing this file fixes; the transition is the
spring under test, so it stays the view's own inline style. */
[data-md-showcase-motion-row] {
display: grid;
grid-template-columns: 144px 1fr;
align-items: center;
gap: var(--md-sys-measurement-space200);
}
[data-md-showcase-motion-track] {
height: var(--md-sys-measurement-space400);
}
[data-md-showcase-motion-dot] {
width: var(--md-sys-measurement-space400);
height: var(--md-sys-measurement-space400);
border-radius: var(--md-sys-shape-corner-full);
background-color: var(--md-sys-color-tertiary);
}
}
@@ -1,39 +1,39 @@
<section id="motion" class="scroll-mt-24 space-y-6" x-data="{ moved: false, figure: 1204 }">
<h2 class="type-headline-md">Motion</h2>
<x-livewire-material::stack as="section" id="motion" gap="space300" x-data="{ moved: false, figure: 1204 }">
<h2 class="md-type-headline-md">Motion</h2>
<p class="max-w-3xl type-body-md text-on-surface-variant">
M3 Expressive's springs as <code>ease-spatial-*</code> and <code>ease-effects-*</code>, each with its
<code>--md-sys-motion-*-duration</code>. Reduced motion makes all of them instant.
<p class="md-type-body-md md-ink-variant">
M3 Expressive's springs as <code>--md-sys-motion-spatial-*</code> and <code>--md-sys-motion-effects-*</code>, each with its
own duration. Reduced motion makes all of them instant.
</p>
<p class="max-w-3xl type-body-md text-on-surface-variant" data-test="when-to-use">
<p class="md-type-body-md md-ink-variant" data-test="when-to-use">
Position, size and shape move on the spatial springs, which overshoot — <code>fast</code> for small elements, <code>slow</code> for large ones. Colour and opacity move on the effects springs, which never overshoot. Always pair an easing with its duration; everything that moves goes through these tokens, so reduced motion makes it instant. The Standard scheme (<code>motion.scheme</code>) swaps the spatial springs for a restrained set.
</p>
<button type="button" class="state-layer focus-ring rounded-corner-full bg-primary px-6 py-2.5 type-label-lg text-on-primary" x-on:click="moved = ! moved">
Move
</button>
<x-livewire-material::button variant="filled" label="Move" x-on:click="moved = ! moved" />
<div class="space-y-3 rounded-corner-lg bg-surface-container p-4">
@foreach (['spatial-fast', 'spatial-default', 'spatial-slow', 'effects-fast', 'effects-default', 'effects-slow'] as $spring)
<div class="grid grid-cols-[9rem_1fr] items-center gap-4">
<code class="type-label-md text-on-surface-variant">ease-{{ $spring }}</code>
<div class="h-8">
<div
class="size-8 rounded-corner-full bg-tertiary"
style="transition: translate var(--md-sys-motion-{{ $spring }}-duration) var(--md-sys-motion-{{ $spring }})"
x-bind:style="moved && { translate: '16rem' }"
></div>
<x-livewire-material::surface level="surface-container" padding="space200" corner="lg">
<x-livewire-material::stack gap="space100">
@foreach (['spatial-fast', 'spatial-default', 'spatial-slow', 'effects-fast', 'effects-default', 'effects-slow'] as $spring)
<div data-md-showcase-motion-row>
<code class="md-type-label-md md-ink-variant">--md-sys-motion-{{ $spring }}</code>
<div data-md-showcase-motion-track>
<div
data-md-showcase-motion-dot
style="transition: translate var(--md-sys-motion-{{ $spring }}-duration) var(--md-sys-motion-{{ $spring }})"
x-bind:style="moved && { translate: '16rem' }"
></div>
</div>
</div>
</div>
@endforeach
</div>
@endforeach
</x-livewire-material::stack>
</x-livewire-material::surface>
<div class="flex flex-wrap items-center gap-4 rounded-corner-lg bg-surface-container p-4">
<p class="type-emphasized-display-sm tabular-nums" x-figure x-text="figure.toLocaleString('en') + ' files'">1,204 files</p>
<button type="button" class="state-layer focus-ring rounded-corner-full px-4 py-2 type-label-lg text-primary" x-on:click="figure = Math.round(Math.random() * 5000)">
Change the figure
</button>
<code class="type-label-md text-on-surface-variant">x-figure</code>
</div>
</section>
<x-livewire-material::surface level="surface-container" padding="space200" corner="lg">
<x-livewire-material::row gap="space200" wrap align="center">
<p class="md-type-emphasized-display-sm md-tabular" x-figure x-text="figure.toLocaleString('en') + ' files'">1,204 files</p>
<x-livewire-material::button variant="text" label="Change the figure" x-on:click="figure = Math.round(Math.random() * 5000)" />
<code class="md-type-label-md md-ink-variant">x-figure</code>
</x-livewire-material::row>
</x-livewire-material::surface>
</x-livewire-material::stack>