|
| 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) |
0 commit comments