Skip to content

Commit 1772f8a

Browse files
Merge pull request #88 from jeffreylauwers/feature/transition-animation-tokens
Merged via Claude Code
2 parents 117a938 + ad23ffc commit 1772f8a

File tree

13 files changed

+360
-15
lines changed

13 files changed

+360
-15
lines changed

docs/02-design-tokens-reference.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Design Tokens Reference
22

3-
**Last Updated:** March 5, 2026
3+
**Last Updated:** March 15, 2026
44

55
Complete reference for all design tokens in the Design System Starter Kit.
66

@@ -14,6 +14,7 @@ Complete reference for all design tokens in the Design System Starter Kit.
1414
4. [Colors](#colors)
1515
5. [Borders](#borders)
1616
6. [Focus States](#focus-states)
17+
7. [Motion](#motion)
1718

1819
---
1920

@@ -308,6 +309,50 @@ Focus indicators use a dual-outline technique: a primary `outline` for the main
308309

309310
---
310311

312+
## Motion
313+
314+
### Transition Duration
315+
316+
Five semantic durations for UI transitions. All are set to `0ms` under `@media (prefers-reduced-motion: reduce)`.
317+
318+
| Token | CSS Variable | Value |
319+
| ------- | ----------------------------------- | ----- |
320+
| instant | `--dsn-transition-duration-instant` | 0ms |
321+
| fast | `--dsn-transition-duration-fast` | 100ms |
322+
| normal | `--dsn-transition-duration-normal` | 200ms |
323+
| slow | `--dsn-transition-duration-slow` | 350ms |
324+
| slower | `--dsn-transition-duration-slower` | 500ms |
325+
326+
### Transition Easing
327+
328+
Five semantic easing curves for consistent motion feel.
329+
330+
| Token | CSS Variable | Value |
331+
| ------- | --------------------------------- | ---------------------------------- |
332+
| default | `--dsn-transition-easing-default` | `cubic-bezier(0.25, 0.1, 0.25, 1)` |
333+
| enter | `--dsn-transition-easing-enter` | `cubic-bezier(0, 0, 0.2, 1)` |
334+
| exit | `--dsn-transition-easing-exit` | `cubic-bezier(0.4, 0, 1, 1)` |
335+
| move | `--dsn-transition-easing-move` | `cubic-bezier(0.4, 0, 0.2, 1)` |
336+
| linear | `--dsn-transition-easing-linear` | `linear` |
337+
338+
**Usage in components:**
339+
340+
```css
341+
.dsn-button {
342+
transition:
343+
background-color var(--dsn-transition-duration-normal)
344+
var(--dsn-transition-easing-default),
345+
color var(--dsn-transition-duration-normal)
346+
var(--dsn-transition-easing-default),
347+
border-color var(--dsn-transition-duration-normal)
348+
var(--dsn-transition-easing-default);
349+
}
350+
```
351+
352+
**Reduced motion:** All duration tokens resolve to `0ms` via a central `@media (prefers-reduced-motion: reduce)` block appended to every full CSS configuration — no component-level media queries needed.
353+
354+
---
355+
311356
## Token Statistics
312357

313358
**Total Tokens (as of v4.9.0):**

docs/05-storybook-configuration.md

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Storybook Configuration
22

3-
**Last Updated:** March 13, 2026
3+
**Last Updated:** March 15, 2026
44

55
Documentation for the Storybook setup, runtime theme switching, UI components, and documentation structure.
66

@@ -398,6 +398,49 @@ const meta: Meta<typeof Button> = {
398398
/>
399399
```
400400

401+
### TokenTable
402+
403+
**Location:** `packages/storybook/src/components/TokenTable.tsx`
404+
405+
**Purpose:** Renders a table of design tokens with optional live preview visuals and computed CSS values.
406+
407+
**Props:**
408+
409+
| Prop | Type | Default | Description |
410+
| --------------- | ------------- | -------- | ----------------------------------- |
411+
| `tokens` | `Token[]` || Array of `{ name, cssVar, value? }` |
412+
| `previewType` | `PreviewType` | `'none'` | Visual preview type |
413+
| `showLiveValue` | `boolean` | `true` | Show computed CSS value |
414+
415+
**`previewType` values:**
416+
417+
| Value | Preview |
418+
| ----------------------- | ------------------------------------------------------------- |
419+
| `'color'` | Gekleurd vlak 32×32px |
420+
| `'spacing'` | Horizontale balk (breedte = tokenwaarde) |
421+
| `'typography-size'` | "Aa" in de tokengrootte |
422+
| `'border-radius'` | Gevuld vlak 40×40px met border-radius toegepast |
423+
| `'shadow'` | Kaartje met `box-shadow` toegepast |
424+
| `'transition-duration'` | Animerende sweep-balk (animationDuration = token) |
425+
| `'transition-easing'` | Stip op track (animationTimingFunction = token, vaste 1200ms) |
426+
| `'none'` | Geen preview kolom |
427+
428+
Alle kleur-previews gebruiken `--dsn-color-accent-1-inverse-bg-default` als accentkleur.
429+
430+
### TocLink
431+
432+
**Location:** `packages/storybook/src/components/TocLink.tsx`
433+
434+
**Purpose:** Anchor-navigatie binnen een Storybook docs-pagina zonder de Storybook URL te breken.
435+
436+
Storybook gebruikt `?path=`-gebaseerde URL-routing. Een gewone `<a href="#section">` vervangt de hele URL en laat de sidebar verdwijnen. `TocLink` onderschept de klik via `e.preventDefault()` en roept `document.getElementById(targetId)?.scrollIntoView({ behavior: 'smooth' })` aan.
437+
438+
```tsx
439+
<TocLink targetId="colors">Colors</TocLink>
440+
// rendert als: <a class="dsn-link" href="#colors">Colors</a>
441+
// klik: scrollt naar element met id="colors", geen URL-verandering
442+
```
443+
401444
---
402445

403446
## Documentation Structure

docs/changelog.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ All notable changes to this project are documented in this file.
66

77
---
88

9+
## Version 5.8.0 (March 15, 2026)
10+
11+
### Motion tokens: transition duration & easing (PR #85)
12+
13+
- **10 nieuwe design tokens** — 5 duration (`instant/fast/normal/slow/slower`) en 5 easing (`default/enter/exit/move/linear`) in `base.json` van het Start-thema
14+
- **Centrale `prefers-reduced-motion` media query** — toegevoegd via `build.js` post-processing aan alle 8 volledige CSS-configuraties; alle duration tokens worden `0ms`; geen component-level media queries nodig
15+
- **5 component CSS-bestanden bijgewerkt** — hardcoded `0.2s ease` vervangen door `var(--dsn-transition-duration-normal)` en `var(--dsn-transition-easing-default)` in `button.css`, `link.css`, `text-input.css`, `text-area.css`, `details.css`
16+
- **Storybook Design Tokens pagina uitgebreid** — Motion-sectie toegevoegd onderaan met `## Motion`, `### Transition Duration` en `### Transition Easing` tabellen
17+
- **`TokenTable` nieuwe `previewType` waarden**`transition-duration` (animated sweep bar) en `transition-easing` (dot op track) tonen live animatie-previews in de documentatie
18+
- **Navigatie-index** toegevoegd aan de Design Tokens pagina — genummerde `OrderedList` met `TocLink` componenten (gebruikt `scrollIntoView` i.p.v. URL-navigatie zodat de Storybook sidebar intact blijft)
19+
- **Preview kleuren** geüniformeerd — spacing, border-radius en motion previews gebruiken allemaal `--dsn-color-accent-1-inverse-bg-default`
20+
21+
---
22+
923
## Version 5.7.0 (March 13, 2026)
1024

1125
### Body component: document-level cascade basisstijlen (PR #84, issue #83)

packages/components-html/src/button/button.css

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@
2323
cursor: pointer;
2424
user-select: none;
2525
transition:
26-
background-color 0.2s ease,
27-
color 0.2s ease,
28-
border-color 0.2s ease;
26+
background-color var(--dsn-transition-duration-normal)
27+
var(--dsn-transition-easing-default),
28+
color var(--dsn-transition-duration-normal)
29+
var(--dsn-transition-easing-default),
30+
border-color var(--dsn-transition-duration-normal)
31+
var(--dsn-transition-easing-default);
2932

3033
/* Accessibility - WCAG pointer target */
3134
min-block-size: var(--dsn-button-min-block-size);

packages/components-html/src/details/details.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@
103103
width: var(--dsn-details-icon-size);
104104
height: var(--dsn-details-icon-size);
105105
color: var(--dsn-details-summary-color);
106-
transition: transform 0.2s ease;
106+
transition: transform var(--dsn-transition-duration-normal)
107+
var(--dsn-transition-easing-default);
107108
}
108109

109110
.dsn-details[open] .dsn-details__icon {

packages/components-html/src/link/link.css

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
/* Interaction */
2121
cursor: pointer;
2222
transition:
23-
color 0.2s ease,
24-
text-decoration-color 0.2s ease;
23+
color var(--dsn-transition-duration-normal)
24+
var(--dsn-transition-easing-default),
25+
text-decoration-color var(--dsn-transition-duration-normal)
26+
var(--dsn-transition-easing-default);
2527
}
2628

2729
/* Icon sizing */

packages/components-html/src/text-area/text-area.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343

4444
/* Transitions */
4545
transition-property: border-color, box-shadow, background-color;
46-
transition-duration: 0.2s;
47-
transition-timing-function: ease-in-out;
46+
transition-duration: var(--dsn-transition-duration-normal);
47+
transition-timing-function: var(--dsn-transition-easing-default);
4848
}
4949

5050
/* Placeholder */

packages/components-html/src/text-input/text-input.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040

4141
/* Transitions */
4242
transition-property: border-color, box-shadow, background-color;
43-
transition-duration: 0.2s;
44-
transition-timing-function: ease-in-out;
43+
transition-duration: var(--dsn-transition-duration-normal);
44+
transition-timing-function: var(--dsn-transition-easing-default);
4545
}
4646

4747
/* Placeholder */

packages/design-tokens/src/config/build.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,36 @@ fullConfigNames.forEach((name, index) => {
5858

5959
console.log(`\n✅ Built ${fullConfigNames.length} full configurations\n`);
6060

61+
// =============================================================================
62+
// APPEND PREFERS-REDUCED-MOTION MEDIA QUERY
63+
// =============================================================================
64+
65+
console.log(
66+
'🎬 Appending prefers-reduced-motion media query to CSS files...\n'
67+
);
68+
69+
const reducedMotionBlock = `
70+
@media (prefers-reduced-motion: reduce) {
71+
:root {
72+
--dsn-transition-duration-instant: 0ms;
73+
--dsn-transition-duration-fast: 0ms;
74+
--dsn-transition-duration-normal: 0ms;
75+
--dsn-transition-duration-slow: 0ms;
76+
--dsn-transition-duration-slower: 0ms;
77+
}
78+
}
79+
`;
80+
81+
fullConfigNames.forEach((name) => {
82+
const cssFilePath = path.join(__dirname, '..', '..', `dist/css/${name}.css`);
83+
if (fs.existsSync(cssFilePath)) {
84+
fs.appendFileSync(cssFilePath, reducedMotionBlock);
85+
console.log(` ✅ dist/css/${name}.css`);
86+
}
87+
});
88+
89+
console.log('\n✅ prefers-reduced-motion media query appended\n');
90+
6191
// =============================================================================
6292
// BUILD SCOPED CONFIGURATIONS (for runtime switching)
6393
// =============================================================================

packages/design-tokens/src/tokens/themes/start/base.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,52 @@
530530
"value": "0 4px 8px 0 {dsn.color.shadow.direct}, 0 16px 32px 0 {dsn.color.shadow.ambient}, 0 0 0 1px {dsn.color.shadow.highlight}",
531531
"comment": "Grote elevatie — modals, dialogen, side panels"
532532
}
533+
},
534+
"transition": {
535+
"duration": {
536+
"instant": {
537+
"value": "0ms",
538+
"comment": "State-changes die onmiddellijk moeten aanvoelen"
539+
},
540+
"fast": {
541+
"value": "100ms",
542+
"comment": "Subtiele hover-states, kleur-transitions"
543+
},
544+
"normal": {
545+
"value": "200ms",
546+
"comment": "Standaard UI-transitions"
547+
},
548+
"slow": {
549+
"value": "350ms",
550+
"comment": "Grotere bewegingen, accordions"
551+
},
552+
"slower": {
553+
"value": "500ms",
554+
"comment": "Complexe animaties, page-level transitions"
555+
}
556+
},
557+
"easing": {
558+
"default": {
559+
"value": "cubic-bezier(0.25, 0.1, 0.25, 1)",
560+
"comment": "Algemeen — equivalent van CSS ease"
561+
},
562+
"enter": {
563+
"value": "cubic-bezier(0, 0, 0.2, 1)",
564+
"comment": "Elementen die het scherm binnenkomen (decelereren)"
565+
},
566+
"exit": {
567+
"value": "cubic-bezier(0.4, 0, 1, 1)",
568+
"comment": "Elementen die het scherm verlaten (accelereren)"
569+
},
570+
"move": {
571+
"value": "cubic-bezier(0.4, 0, 0.2, 1)",
572+
"comment": "Elementen die van positie wisselen"
573+
},
574+
"linear": {
575+
"value": "linear",
576+
"comment": "Progress bars, loaders"
577+
}
578+
}
533579
}
534580
}
535581
}

0 commit comments

Comments
 (0)