モーション
willink DS のモーションは、プリミティブ(生の duration / easing 値)と、それを別名参照するセマンティックロールトークンの 2 段構成です。コンポーネントはロールトークンを使い、 テーマはプリミティブを差し替えるだけで全体の動きを調整できます(ADR-0008)。
プリミティブ
duration と easing の生値です。テーマはこの層を :root で override できます。
--duration-fast= 150ms--duration-base= 250ms--duration-slow= 400ms--ease-standard=cubic-bezier(0.2, 0, 0, 1)--ease-emphasized=cubic-bezier(0.3, 0, 0, 1.1)
セマンティックロール
コンポーネントは生値ではなくロールトークンを参照します。各ロールはプリミティブの別名で、 UI の用途と動きの意図を結び付けます。
| ロールトークン | 参照プリミティブ |
|---|---|
--duration-modal-enter / --duration-modal-exit | --duration-fast |
--duration-popover-enter / --duration-popover-exit | --duration-fast |
--duration-tooltip-enter / --duration-tooltip-exit | --duration-fast |
--duration-sheet | --duration-fast |
--duration-accordion | --duration-base |
--duration-toast | --duration-base |
--ease-enter | --ease-standard |
--ease-exit | --ease-standard |
--ease-emphasized-enter | --ease-emphasized |
自動生成ユーティリティ
Tailwind v4 はこれらのロールトークンから duration-{role} / ease-{role} ユーティリティを自動生成します。たとえば duration-accordion や ease-enter をそのままクラスとして利用でき、テーマがプリミティブを override すれば値も追従します。
reduced-motion 契約
prefers-reduced-motion への対応は 2 層の冗長な防御で実装されています(WCAG 2.3.3)。一方が抜けても、 もう一方が動きを止めます。
第 1 層 — コンポーネント単位の Tailwind variant。 アニメーションを持つ各コンポーネント(Dialog / AlertDialog / Sheet / Accordion / Tooltip)は、 アニメーションクラスの隣に motion-reduce:animate-none (または motion-reduce:transition-none)を付与します。
<DialogContent
className="animate-in fade-in-0 zoom-in-95 motion-reduce:animate-none"
/>第 2 層 — preset CSS のセーフティネット。 preset 側の @media (prefers-reduced-motion: reduce) が、すべての animate-* keyframe ユーティリティに加え、Sonner toast([data-sonner-toast])と Skeleton の animate-pulse を一括で停止します。第 1 層を付け忘れた著者や、ライブラリ所有の transition も漏れなく拾います。
@media (prefers-reduced-motion: reduce) {
/* animate-* keyframe ユーティリティ全般 */
[class*="animate-"] {
animation-duration: 0ms !important;
}
/* Sonner toast / Skeleton の animate-pulse も無効化 */
[data-sonner-toast],
.animate-pulse {
animation-duration: 0ms !important;
}
}次は アクセシビリティ で reduced-motion を含む a11y 契約全体を確認する。