Skip to content

Commit 3c71ea5

Browse files
Jeffrey Lauwersclaude
andcommitted
chore(storybook): consistente story-structuur voor alle componenten
- Voeg vaste sectie-comments toe aan alle story-bestanden (DEFAULT, VARIANTEN, OVERZICHTSSTORIES, TEKST VARIANTEN, RTL) - Hernoem AllStates → AllVariants bij Alert, Note en StatusBadge (visuele varianten, geen interactieve states) - Verwijder lege // HIGH CONTRAST secties uit alle 47 bestanden - Verwijder lege // LARGE TEXT secties (Select, NumberInput, PasswordInput, DateInput, TimeInput, DateInputGroup) - Vertaal Nederlandse story-namen naar Engels (BreadcrumbNavigation, Table) - Herschik ShortText/LongText naar // TEKST VARIANTEN sectie bij RadioOption - Voeg ShortText + LongText stories toe aan ontbrekende componenten (CheckboxGroup, RadioGroup, Details, FormField, FormFieldset) - Voeg RTL stories toe aan Table - Hernoem Card stories naar Engelse namen - Update /new-component-issue command met story-structuurrichtlijnen Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 59c30a4 commit 3c71ea5

46 files changed

Lines changed: 1082 additions & 241 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
# Nieuw component issue aanmaken
2+
3+
Maak een nieuw GitHub issue aan voor een **nieuw design system component**. Het issue volgt het vaste componentspec-formaat — inclusief HTML/CSS-structuur, React API, toegankelijkheidsvereisten en component tokens.
4+
5+
Optionele context meegegeven door de gebruiker (componentnaam, beschrijving, etc.):
6+
7+
> $ARGUMENTS
8+
9+
---
10+
11+
## Stap 1 — Componentnaam en beschrijving
12+
13+
Als `$ARGUMENTS` geen componentnaam bevat, vraag dan:
14+
15+
- Wat is de naam van het component? (PascalCase, bijv. `Tooltip`)
16+
- Geef één zin die beschrijft wat het component doet.
17+
18+
Stel de titel op: `feat(ComponentName): korte beschrijving`
19+
20+
---
21+
22+
## Stap 2 — Verzamel de spec
23+
24+
Vraag de gebruiker naar de volgende onderdelen. Meerdere secties mogen in één keer worden aangeleverd; sluit geen enkel onderdeel over — gebruik HTML-commentaren als er niets is.
25+
26+
### 2a. Beschrijving en gebruik
27+
28+
- **Beschrijving**: Wat doet het component en wanneer gebruik je het? (2–4 zinnen)
29+
- **Gebruik — wanneer wél**: 3–5 bulletpunten
30+
- **Gebruik — wanneer niet**: 1–2 gevallen waarbij een alternatief beter is
31+
32+
### 2b. HTML/CSS implementatie
33+
34+
- **HTML-structuur**: De basis HTML-markup met alle CSS-klassen. Toon relevante varianten (bijv. standaard, open, met modifier).
35+
- **CSS-klassenoverzicht**: tabel met `Klasse | Element | Beschrijving` voor alle `dsn-{component}*` klassen.
36+
37+
> Regels uit het design system:
38+
>
39+
> - Prefix altijd `dsn-`
40+
> - Modifier altijd naast basisklasse: `class="dsn-note dsn-note--info"`
41+
> - Grootte via `--size-{naam}`: `dsn-button--size-small`
42+
> - Geen geneste element-namen: `dsn-alert__content__text`
43+
> - Nooit `aria-label` op buttons — altijd `dsn-button__label` span
44+
> - Nooit hardcoded waarden in CSS — altijd `var(--dsn-*)`
45+
46+
### 2c. React component
47+
48+
- **Code voorbeelden**: basis gebruik + eventuele varianten
49+
- **Props tabel**: `Prop | Type | Default | Beschrijving` voor alle props
50+
51+
### 2d. Toegankelijkheidsvereisten
52+
53+
Vraag specifiek naar:
54+
55+
- Structuur (impliciete ARIA-rollen, `scope`, vereiste attributen)
56+
- Toetsenbordinteractie (indien van toepassing)
57+
- Schermlezers (wat wordt voorgelezen, hoe navigeren gebruikers)
58+
- Bekende beperkingen of onderzoeksbevindingen
59+
60+
### 2e. Component tokens (voorstel)
61+
62+
- JSON-structuur voor alle `dsn.{component}.*` tokens
63+
- Welke globale tokens worden gerefereerd?
64+
- Ontwerpkeuzes achter de tokenwaarden (1–3 regels per niet-voor-de-hand-liggende keuze)
65+
- Markeer onzekere waarden met een ⚠️ opmerking
66+
67+
> **Token schrijfwijze — altijd controleren:**
68+
> Sub-groepen (zoals `icon`, `label`, `control`) worden als geneste objecten geschreven, niet als geflattende sleutels met koppeltekens:
69+
>
70+
> ```json
71+
> // ✅ Correct — geneste structuur
72+
> "icon": {
73+
> "color": { "value": "...", "type": "color" },
74+
> "size": { "value": "...", "type": "dimension" },
75+
> "gap": { "value": "...", "type": "spacing" }
76+
> }
77+
>
78+
> // ❌ Fout — geflattend
79+
> "icon-color": { "value": "...", "type": "color" },
80+
> "icon-size": { "value": "...", "type": "dimension" }
81+
> ```
82+
>
83+
> De gegenereerde CSS custom properties zijn in beide gevallen identiek (`--dsn-{component}-icon-color`, etc.), maar de JSON-schrijfwijze volgt altijd de geneste structuur.
84+
> Controleer elk tokenvoorstel hierop voordat het issue wordt aangemaakt.
85+
86+
---
87+
88+
## Stap 3 — Stel de issue body samen
89+
90+
Bouw de body op in deze volgorde. Vul in wat de gebruiker aanleverde; gebruik HTML-commentaren voor ontbrekende informatie.
91+
92+
````
93+
## Beschrijving
94+
95+
[één-alinea beschrijving van het component]
96+
97+
## Gebruik
98+
99+
Het [ComponentName] component wordt gebruikt voor:
100+
- [use case 1]
101+
- [use case 2]
102+
- [use case 3]
103+
104+
> Gebruik [ComponentName] **niet** als [wanneer-niet-gebruik]. Gebruik in dat geval [alternatief].
105+
106+
## HTML/CSS
107+
108+
### Basis
109+
110+
```html
111+
[basis HTML-markup]
112+
````
113+
114+
### [Variant/Optie naam, indien van toepassing]
115+
116+
```html
117+
[variant markup]
118+
```
119+
120+
### CSS klassen
121+
122+
| Klasse | Element | Beschrijving |
123+
| ----------------- | ------------- | -------------- |
124+
| `dsn-[component]` | `<[element]>` | [beschrijving] |
125+
126+
## React
127+
128+
```tsx
129+
// Basis
130+
<ComponentName prop="waarde">...</ComponentName>
131+
132+
// [Variant naam indien van toepassing]
133+
<ComponentName variant="naam">...</ComponentName>
134+
```
135+
136+
### Props
137+
138+
| Prop | Type | Default | Beschrijving |
139+
| -------- | -------- | ----------- | -------------- |
140+
| `[prop]` | `[type]` | `[default]` | [beschrijving] |
141+
142+
## Toegankelijkheidsvereisten
143+
144+
### Structuur
145+
146+
- [vereiste 1]
147+
- [vereiste 2]
148+
149+
### [Subsectie indien van toepassing: Toetsenbord, Schermlezers, etc.]
150+
151+
- [vereiste]
152+
153+
## Component tokens (voorstel)
154+
155+
> ⚠️ **Review vereist vóór implementatie** — akkoord geven op deze tabel voordat de bouw begint.
156+
157+
```json
158+
{
159+
"dsn": {
160+
"[component]": {
161+
"[token]": { "value": "{dsn.[referentie]}", "type": "[type]" }
162+
}
163+
}
164+
}
165+
```
166+
167+
**Ontwerpkeuzes:**
168+
169+
- [keuze en motivatie]
170+
171+
---
172+
173+
## Acceptatiecriteria
174+
175+
### HTML/CSS
176+
177+
- [ ] Component tokens JSON (`[component].json`)
178+
- [ ] CSS implementatie (`[component].css`)
179+
- [ ] [specifiek CSS-onderdeel]
180+
- [ ] [specifiek CSS-onderdeel]
181+
182+
### React
183+
184+
- [ ] `[ComponentName]` component met [props opsomming]
185+
- [ ] `React.forwardRef<HTML[Element]Element>`
186+
- [ ] Export toegevoegd aan `packages/components-react/src/index.ts`
187+
188+
### Storybook
189+
190+
- [ ] Drie bestanden aangemaakt: `.stories.tsx`, `.docs.mdx`, `.docs.md`
191+
- [ ] `// DEFAULT` sectie — `Default` story
192+
- [ ] `// VARIANTEN` sectie — per-prop/state stories (bijv. `WithDescription`, `Disabled`, `Invalid`)
193+
- [ ] `// OVERZICHTSSTORIES` sectie — `AllVariants` of `AllStates` (zie regel hieronder)
194+
- [ ] `// TEKST VARIANTEN` sectie — `ShortText` + `LongText` (alleen bij componenten met zichtbare tekstinhoud)
195+
- [ ] `// RTL` sectie — `RTL` + `RTLLongText` (alleen bij componenten met tekst of richtingsgevoelige layout)
196+
- [ ] Alle story-namen in het Engels
197+
198+
---
199+
200+
## Definition of Done
201+
202+
### Voorbereiding
203+
204+
- [ ] Feature branch aangemaakt: `git checkout -b feature/[component-name]`
205+
206+
### Werkzaamheden
207+
208+
- [ ] Implementatie afgerond
209+
210+
### Bij nieuw component
211+
212+
- [ ] Drie Storybook-bestanden aangemaakt (`.stories.tsx`, `.docs.mdx`, `.docs.md`)
213+
- [ ] Export toegevoegd aan `packages/components-react/src/index.ts`
214+
- [ ] `Introduction.mdx` bijgewerkt (datum + componentnaam in de lijst)
215+
216+
### Kwaliteitscontrole
217+
218+
- [ ] Tests groen: `pnpm test`
219+
- [ ] TypeScript schoon: `pnpm --filter storybook exec tsc --noEmit`
220+
- [ ] Lint schoon: `pnpm lint`
221+
222+
### Documentatie
223+
224+
- [ ] `MEMORY.md` bijgewerkt indien nieuw patroon of architectuurkeuze
225+
- [ ] Relevante `.docs.md` bijgewerkt
226+
227+
### Oplevering
228+
229+
- [ ] PR aangemaakt: `gh pr create`
230+
- [ ] CI groen op de branch
231+
- [ ] PR gemerged: `gh pr merge --merge`
232+
233+
## Notities / Open vragen
234+
235+
<!-- Edge cases, twijfels, tokenwaarden die nog bepaald moeten worden, dingen om op te letten tijdens refinement. -->
236+
237+
````
238+
239+
**Let op bij het invullen:**
240+
- Acceptatiecriteria **genereer je** op basis van wat de gebruiker in stap 2 heeft opgegeven — maak ze concreet en specifiek
241+
- Storybook stories leiden af uit de HTML/CSS-varianten die beschreven zijn
242+
- Ontbrekende secties krijgen een HTML-commentaar, niet worden weggelaten
243+
- Tokens die nog niet bepaald zijn, markeer je expliciet met een ⚠️-opmerking in de Notities sectie
244+
245+
**Storybook story-structuur — vaste regels:**
246+
247+
Elke `.stories.tsx` volgt altijd deze sectievolgorde (met `// ===` comments als scheidslijn):
248+
249+
1. `// DEFAULT` — altijd één `Default` story
250+
2. `// VARIANTEN` — individuele stories per prop of state
251+
3. `// OVERZICHTSSTORIES` — één overzichtsstory:
252+
- `AllVariants` / `'All variants'` → voor componenten met **visuele kleur- of stijlvarianten** (bijv. `variant="info|warning|error"`)
253+
- `AllStates` / `'All states'` → voor componenten met **interactieve states** (bijv. default, disabled, invalid, read-only)
254+
4. `// TEKST VARIANTEN` — `ShortText` + `LongText` — **alleen** bij componenten met zichtbare tekstinhoud; weglaten bij icoon-only of puur visuele componenten (DotBadge, Icon, Checkbox, Radio)
255+
5. `// RTL` — `RTL` + `RTLLongText` — **alleen** bij componenten met tekst of richtingsgevoelige layout
256+
257+
Geen `// HIGH CONTRAST` sectie — daar zijn we van af gestapt.
258+
259+
---
260+
261+
## Stap 4 — Toon ter review
262+
263+
Laat de volledige title én body zien aan de gebruiker. Vraag om expliciete bevestiging voordat het issue aangemaakt wordt.
264+
265+
---
266+
267+
## Stap 5 — Maak het issue aan
268+
269+
Na bevestiging van de gebruiker:
270+
271+
```bash
272+
gh issue create \
273+
--title "feat(ComponentName): korte beschrijving" \
274+
--label "feat,component,needs refinement" \
275+
--body "BODY"
276+
````
277+
278+
Rapporteer de URL van het aangemaakte issue.
279+
280+
---
281+
282+
## Regels
283+
284+
- Gebruik **altijd** het volledige template — sla geen secties over
285+
- **Genereer** de acceptatiecriteria op basis van de spec — kopieer ze niet blind uit eerdere issues
286+
- Voeg **geen** verzonnen implementatiedetails toe — als iets onbekend is, gebruik HTML-commentaar of ⚠️
287+
- Vraag altijd om **expliciete bevestiging** voordat het issue aangemaakt wordt
288+
- Labels zijn altijd `feat,component,needs refinement` — geen uitzonderingen voor nieuwe componenten
289+
- **Geen Figma-verwijzingen** — er is geen Figma in dit project; schrijf nooit "valideren in Figma", "zie Figma" of soortgelijke verwijzingen
290+
- **Token schrijfwijze** — controleer altijd of sub-groepen als geneste objecten zijn geschreven (zie stap 2e)

packages/storybook/src/ActionGroup.stories.tsx

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,16 @@ const meta: Meta<typeof ActionGroup> = {
4545
export default meta;
4646
type Story = StoryObj<typeof ActionGroup>;
4747

48+
// =============================================================================
49+
// DEFAULT
50+
// =============================================================================
51+
4852
export const Default: Story = {};
4953

54+
// =============================================================================
55+
// VARIANTEN
56+
// =============================================================================
57+
5058
export const WithLink: Story = {
5159
name: 'With Link',
5260
args: {
@@ -85,6 +93,10 @@ export const SingleAction: Story = {
8593
},
8694
};
8795

96+
// =============================================================================
97+
// TEKST VARIANTEN
98+
// =============================================================================
99+
88100
export const ShortText: Story = {
89101
name: 'Short text',
90102
args: {
@@ -126,15 +138,17 @@ export const WithLinkButton: Story = {
126138
},
127139
};
128140

141+
// =============================================================================
142+
// RTL
143+
// =============================================================================
144+
129145
export const RTL: Story = {
130146
name: 'RTL',
131147
decorators: [rtlDecorator],
132148
render: () => (
133-
<div dir="rtl">
134-
<ActionGroup>
135-
<Button variant="strong">حفظ</Button>
136-
<Button variant="subtle">إلغاء</Button>
137-
</ActionGroup>
138-
</div>
149+
<ActionGroup>
150+
<Button variant="strong">حفظ</Button>
151+
<Button variant="subtle">إلغاء</Button>
152+
</ActionGroup>
139153
),
140154
};

0 commit comments

Comments
 (0)