@dsn-starter-kit/components-react 3.5.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/Card/Card.d.mts +86 -21
  2. package/dist/Card/Card.d.mts.map +1 -1
  3. package/dist/Card/Card2.mjs +100 -17
  4. package/dist/Card/Card2.mjs.map +1 -1
  5. package/dist/Card/index.d.mts +2 -2
  6. package/dist/DateInput/DateInput.d.mts +1 -1
  7. package/dist/DateInput/DateInput2.mjs +1 -1
  8. package/dist/DateInput/DateInput2.mjs.map +1 -1
  9. package/dist/DateInputGroup/DateInputGroup2.mjs +3 -3
  10. package/dist/DateInputGroup/DateInputGroup2.mjs.map +1 -1
  11. package/dist/EmailInput/EmailInput.d.mts +10 -5
  12. package/dist/EmailInput/EmailInput.d.mts.map +1 -1
  13. package/dist/EmailInput/EmailInput2.mjs +2 -2
  14. package/dist/EmailInput/EmailInput2.mjs.map +1 -1
  15. package/dist/NumberInput/NumberInput.d.mts +4 -4
  16. package/dist/NumberInput/NumberInput.d.mts.map +1 -1
  17. package/dist/NumberInput/NumberInput2.mjs +2 -2
  18. package/dist/NumberInput/NumberInput2.mjs.map +1 -1
  19. package/dist/PageHeader/PageHeader.d.mts.map +1 -1
  20. package/dist/PageHeader/PageHeader2.mjs +19 -2
  21. package/dist/PageHeader/PageHeader2.mjs.map +1 -1
  22. package/dist/PasswordInput/PasswordInput.d.mts +10 -5
  23. package/dist/PasswordInput/PasswordInput.d.mts.map +1 -1
  24. package/dist/PasswordInput/PasswordInput2.mjs +2 -2
  25. package/dist/PasswordInput/PasswordInput2.mjs.map +1 -1
  26. package/dist/SearchInput/SearchInput.d.mts +10 -5
  27. package/dist/SearchInput/SearchInput.d.mts.map +1 -1
  28. package/dist/SearchInput/SearchInput2.mjs +2 -2
  29. package/dist/SearchInput/SearchInput2.mjs.map +1 -1
  30. package/dist/Select/Select.d.mts +6 -6
  31. package/dist/Select/Select.d.mts.map +1 -1
  32. package/dist/Select/Select2.mjs +4 -4
  33. package/dist/Select/Select2.mjs.map +1 -1
  34. package/dist/TelephoneInput/TelephoneInput.d.mts +10 -5
  35. package/dist/TelephoneInput/TelephoneInput.d.mts.map +1 -1
  36. package/dist/TelephoneInput/TelephoneInput2.mjs +2 -2
  37. package/dist/TelephoneInput/TelephoneInput2.mjs.map +1 -1
  38. package/dist/TextArea/TextArea.d.mts +10 -5
  39. package/dist/TextArea/TextArea.d.mts.map +1 -1
  40. package/dist/TextArea/TextArea2.mjs +2 -2
  41. package/dist/TextArea/TextArea2.mjs.map +1 -1
  42. package/dist/TextInput/TextInput.d.mts +4 -4
  43. package/dist/TextInput/TextInput.d.mts.map +1 -1
  44. package/dist/TextInput/TextInput2.mjs +2 -2
  45. package/dist/TextInput/TextInput2.mjs.map +1 -1
  46. package/dist/TimeInput/TimeInput.d.mts +1 -1
  47. package/dist/TimeInput/TimeInput2.mjs +1 -1
  48. package/dist/TimeInput/TimeInput2.mjs.map +1 -1
  49. package/dist/index.cjs +146 -41
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.css +4993 -4885
  52. package/dist/index.d.cts +140 -50
  53. package/dist/index.d.cts.map +1 -1
  54. package/dist/index.d.mts +2 -2
  55. package/dist/index.mjs +2 -2
  56. package/package.json +3 -3
@@ -2,58 +2,81 @@ import React from "react";
2
2
  //#region src/Card/Card.d.ts
3
3
  interface CardProps extends React.HTMLAttributes<HTMLElement> {
4
4
  /**
5
- * URL voor de stretched link. De `CardHeading` ontvangt `href` automatisch
6
- * via React context en wraps de heading-tekst in een `<a>`.
5
+ * URL voor de stretched link. `CardHeading` en `CardLabel` ontvangen `href`
6
+ * automatisch via React context en zetten hun tekst in een `<a>`.
7
7
  */
8
8
  href?: string;
9
- /** Sub-componenten: `CardHeader`, `CardBody`, `CardFooter` */
9
+ /** Secties: `CardHeader`, `CardPreHeader`, `CardBody`, `CardFooter` */
10
10
  children?: React.ReactNode;
11
11
  className?: string;
12
12
  }
13
13
  /**
14
14
  * Card component
15
- * Configureerbare container voor gestructureerde content met header, body en footer.
16
- * Gebruikt een stretched-link techniek: de link in `CardHeading` dekt de volledige card.
17
- * Screenreaders lezen alleen de heading-tekst als linknaam.
15
+ * Configureerbare container met vier optionele secties: `CardPreHeader`,
16
+ * `CardHeader`, `CardBody` en `CardFooter` (zie DR-2026-11).
17
+ *
18
+ * Zet `CardHeader` in de JSX altijd vóór `CardPreHeader`: zo kondigt een
19
+ * screenreader de heading eerst aan. De CSS zet de pre-header visueel bovenaan.
20
+ *
21
+ * Met `href` wordt de heading een stretched link: de link dekt de volledige
22
+ * card, en screenreaders lezen alleen de heading-tekst als linknaam.
18
23
  *
19
24
  * @example
20
25
  * ```tsx
21
26
  * <Card href="/artikel/slug">
22
27
  * <CardHeader>
23
- * <Image src="/foto.jpg" alt="" width={800} height={450} ratio="16:9" />
28
+ * <CardHeading level={2}>Artikeltitel</CardHeading>
24
29
  * </CardHeader>
30
+ * <CardPreHeader>
31
+ * <Image src="/foto.jpg" alt="" width={800} height={450} ratio="16:9" />
32
+ * </CardPreHeader>
25
33
  * <CardBody>
26
- * <CardHeading level={2}>Artikeltitel</CardHeading>
27
34
  * <Paragraph>Korte beschrijving.</Paragraph>
28
35
  * </CardBody>
29
36
  * <CardFooter>
30
- * <Link href="/artikel/slug" aria-hidden tabIndex={-1}>Lees meer</Link>
37
+ * <CardAffordance>Lees meer</CardAffordance>
31
38
  * </CardFooter>
32
39
  * </Card>
33
40
  * ```
34
41
  */
35
42
  declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLElement>>;
36
- interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
43
+ interface CardPreHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
37
44
  /**
38
- * Afbeelding (`Image` component). Zonder children → toont placeholder
39
- * met `aspect-ratio: 16 / 9` voor visuele consistentie in groep.
45
+ * Afbeelding, badge, logo of icoon. Een `Image` als direct kind loopt door
46
+ * tot de rand van de card. Zonder children → toont een placeholder met
47
+ * `aspect-ratio: 16 / 9` voor visuele consistentie in een groep.
48
+ *
49
+ * Zet hier geen focusbare elementen in: de pre-header staat in de DOM ná de
50
+ * header, dus de focusvolgorde zou afwijken van de visuele volgorde.
40
51
  */
41
52
  children?: React.ReactNode;
42
53
  className?: string;
43
54
  }
44
55
  /**
45
- * CardHeader sub-component
56
+ * CardPreHeader sub-component
57
+ * Staat in de DOM ná `CardHeader` en komt visueel bovenaan via `order: -1`.
46
58
  * Zonder children → toont automatisch een afbeeldingsplaceholder.
47
59
  */
60
+ declare const CardPreHeader: React.ForwardRefExoticComponent<CardPreHeaderProps & React.RefAttributes<HTMLDivElement>>;
61
+ interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
62
+ /** `CardHeading` of `CardLabel`, optioneel gevolgd door een `StatusBadge` */
63
+ children?: React.ReactNode;
64
+ className?: string;
65
+ }
66
+ /**
67
+ * CardHeader sub-component
68
+ * Bevat de heading of het label van de card. Zet hem in de JSX vóór
69
+ * `CardPreHeader`.
70
+ */
48
71
  declare const CardHeader: React.ForwardRefExoticComponent<CardHeaderProps & React.RefAttributes<HTMLDivElement>>;
49
72
  interface CardBodyProps extends React.HTMLAttributes<HTMLDivElement> {
50
- /** `CardHeading`, optionele extra content (bijv. `StatusBadge`), `Paragraph` */
73
+ /** `Paragraph`, `CardDescription`, `CardMeta` of andere inhoud */
51
74
  children?: React.ReactNode;
52
75
  className?: string;
53
76
  }
54
77
  /**
55
78
  * CardBody sub-component
56
- * Groeit via `flex: 1` zodat de footer altijd onderaan uitlijnt.
79
+ * Inhoudssectie onder de header.
57
80
  */
58
81
  declare const CardBody: React.ForwardRefExoticComponent<CardBodyProps & React.RefAttributes<HTMLDivElement>>;
59
82
  interface CardHeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {
@@ -69,22 +92,64 @@ interface CardHeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {
69
92
  /**
70
93
  * CardHeading sub-component
71
94
  * Ontvangt `href` automatisch via React context van de parent `Card`.
72
- * Wanneer `href` beschikbaar is, wraps de heading-tekst in een `<a class="dsn-card-heading__link">`.
95
+ * Wanneer `href` beschikbaar is, staat de heading-tekst in een `<a class="dsn-card__link">`.
73
96
  * Het `::before` pseudo-element dekt de volledige card (stretched link).
74
97
  */
75
98
  declare const CardHeading: React.ForwardRefExoticComponent<CardHeadingProps & React.RefAttributes<HTMLHeadingElement>>;
99
+ interface CardLabelProps extends React.HTMLAttributes<HTMLParagraphElement> {
100
+ /** Label-tekst */
101
+ children?: React.ReactNode;
102
+ className?: string;
103
+ }
104
+ /**
105
+ * CardLabel sub-component
106
+ * Gebruik in plaats van `CardHeading` wanneer de card geen nieuw onderwerp
107
+ * introduceert, zoals bij login-opties of instellingen. Ontvangt `href` via
108
+ * context, net als `CardHeading`.
109
+ */
110
+ declare const CardLabel: React.ForwardRefExoticComponent<CardLabelProps & React.RefAttributes<HTMLParagraphElement>>;
111
+ interface CardDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {
112
+ children?: React.ReactNode;
113
+ className?: string;
114
+ }
115
+ /**
116
+ * CardDescription sub-component
117
+ * Korte omschrijving met eigen typografie-tokens.
118
+ */
119
+ declare const CardDescription: React.ForwardRefExoticComponent<CardDescriptionProps & React.RefAttributes<HTMLParagraphElement>>;
120
+ interface CardMetaProps extends React.HTMLAttributes<HTMLParagraphElement> {
121
+ /** Bijv. een `<time>`-element of een auteur */
122
+ children?: React.ReactNode;
123
+ className?: string;
124
+ }
125
+ /**
126
+ * CardMeta sub-component
127
+ * Aanvullende gegevens bij de card, zoals een datum.
128
+ */
129
+ declare const CardMeta: React.ForwardRefExoticComponent<CardMetaProps & React.RefAttributes<HTMLParagraphElement>>;
76
130
  interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {
77
- /** `Link` of `ButtonLink` — staat boven de stretched link via CSS z-index */
131
+ /** `CardAffordance`, of een `Link` / `ButtonLink` naar een andere bestemming */
78
132
  children?: React.ReactNode;
79
133
  className?: string;
80
134
  }
81
135
  /**
82
136
  * CardFooter sub-component
83
- * Directe kinderen staan boven de stretched link via `z-index: 2` in CSS.
84
- * Gebruik `aria-hidden` + `tabIndex={-1}` op de link wanneer deze dezelfde
85
- * bestemming heeft als de card — vermijdt een dubbele tabstop.
137
+ * Staat altijd onderaan de card. Links en buttons staan boven de stretched
138
+ * link en blijven zelfstandig klikbaar. Voor een visuele "Lees meer" naar
139
+ * dezelfde bestemming als de card: gebruik `CardAffordance`.
86
140
  */
87
141
  declare const CardFooter: React.ForwardRefExoticComponent<CardFooterProps & React.RefAttributes<HTMLDivElement>>;
142
+ interface CardAffordanceProps extends React.HTMLAttributes<HTMLSpanElement> {
143
+ /** Bijv. "Lees meer" */
144
+ children?: React.ReactNode;
145
+ className?: string;
146
+ }
147
+ /**
148
+ * CardAffordance sub-component
149
+ * Een `<span aria-hidden="true">` die eruitziet als een link. De stretched
150
+ * link vangt de klik al af, dus er is geen tweede tabstop nodig.
151
+ */
152
+ declare const CardAffordance: React.ForwardRefExoticComponent<CardAffordanceProps & React.RefAttributes<HTMLSpanElement>>;
88
153
  interface CardGroupProps extends React.HTMLAttributes<HTMLElement> {
89
154
  /**
90
155
  * Semantisch container-element.
@@ -103,5 +168,5 @@ interface CardGroupProps extends React.HTMLAttributes<HTMLElement> {
103
168
  */
104
169
  declare const CardGroup: React.ForwardRefExoticComponent<CardGroupProps & React.RefAttributes<HTMLElement>>;
105
170
  //#endregion
106
- export { Card, CardBody, CardBodyProps, CardFooter, CardFooterProps, CardGroup, CardGroupProps, CardHeader, CardHeaderProps, CardHeading, CardHeadingProps, CardProps };
171
+ export { Card, CardAffordance, CardAffordanceProps, CardBody, CardBodyProps, CardDescription, CardDescriptionProps, CardFooter, CardFooterProps, CardGroup, CardGroupProps, CardHeader, CardHeaderProps, CardHeading, CardHeadingProps, CardLabel, CardLabelProps, CardMeta, CardMetaProps, CardPreHeader, CardPreHeaderProps, CardProps };
107
172
  //# sourceMappingURL=Card.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Card.d.mts","names":[],"sources":["../../src/Card/Card.tsx"],"mappings":";;UAkBiB,kBAAkB,MAAM,eAAe;;;;;EAKtD;;EAGA,WAAW,MAAM;EAEjB;;;;;;;;;;;;;;;;;;;;;;;;cAyBW,MAAI,MAAA,0BAAA,YAAA,MAAA,cAAA;UAsBA,wBAAwB,MAAM,eAAe;;;;;EAK5D,WAAW,MAAM;EAEjB;;;;;;cAOW,YAAU,MAAA,0BAAA,kBAAA,MAAA,cAAA;UAwBN,sBAAsB,MAAM,eAAe;;EAE1D,WAAW,MAAM;EAEjB;;;;;;cAOW,UAAQ,MAAA,0BAAA,gBAAA,MAAA,cAAA;UAoBJ,yBAAyB,MAAM,eAAe;;;;;EAK7D;;EAGA,WAAW,MAAM;EAEjB;;;;;;;;cASW,aAAW,MAAA,0BAAA,mBAAA,MAAA,cAAA;UA8BP,wBAAwB,MAAM,eAAe;;EAE5D,WAAW,MAAM;EAEjB;;;;;;;;cASW,YAAU,MAAA,0BAAA,kBAAA,MAAA,cAAA;UAoBN,uBAAuB,MAAM,eAAe;;;;;;EAM3D;;EAGA,WAAW,MAAM;EAEjB;;;;;;;cAQW,WAAS,MAAA,0BAAA,iBAAA,MAAA,cAAA"}
1
+ {"version":3,"file":"Card.d.mts","names":[],"sources":["../../src/Card/Card.tsx"],"mappings":";;UAkBiB,kBAAkB,MAAM,eAAe;;;;;EAKtD;;EAGA,WAAW,MAAM;EAEjB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAgCW,MAAI,MAAA,0BAAA,YAAA,MAAA,cAAA;UAsBA,2BAA2B,MAAM,eAAe;;;;;;;;;EAS/D,WAAW,MAAM;EAEjB;;;;;;;cAQW,eAAa,MAAA,0BAAA,qBAAA,MAAA,cAAA;UAyBT,wBAAwB,MAAM,eAAe;;EAE5D,WAAW,MAAM;EAEjB;;;;;;;cAQW,YAAU,MAAA,0BAAA,kBAAA,MAAA,cAAA;UAoBN,sBAAsB,MAAM,eAAe;;EAE1D,WAAW,MAAM;EAEjB;;;;;;cAOW,UAAQ,MAAA,0BAAA,gBAAA,MAAA,cAAA;UAoBJ,yBAAyB,MAAM,eAAe;;;;;EAK7D;;EAGA,WAAW,MAAM;EAEjB;;;;;;;;cASW,aAAW,MAAA,0BAAA,mBAAA,MAAA,cAAA;UA8BP,uBAAuB,MAAM,eAAe;;EAE3D,WAAW,MAAM;EAEjB;;;;;;;;cASW,WAAS,MAAA,0BAAA,iBAAA,MAAA,cAAA;UA4BL,6BAA6B,MAAM,eAAe;EACjE,WAAW,MAAM;EAEjB;;;;;;cAOW,iBAAe,MAAA,0BAAA,uBAAA,MAAA,cAAA;UAqBX,sBAAsB,MAAM,eAAe;;EAE1D,WAAW,MAAM;EAEjB;;;;;;cAOW,UAAQ,MAAA,0BAAA,gBAAA,MAAA,cAAA;UAoBJ,wBAAwB,MAAM,eAAe;;EAE5D,WAAW,MAAM;EAEjB;;;;;;;;cASW,YAAU,MAAA,0BAAA,kBAAA,MAAA,cAAA;UAoBN,4BAA4B,MAAM,eAAe;;EAEhE,WAAW,MAAM;EAEjB;;;;;;;cAQW,gBAAc,MAAA,0BAAA,sBAAA,MAAA,cAAA;UAsBV,uBAAuB,MAAM,eAAe;;;;;;EAM3D;;EAGA,WAAW,MAAM;EAEjB;;;;;;;cAQW,WAAS,MAAA,0BAAA,iBAAA,MAAA,cAAA"}
@@ -6,22 +6,29 @@ import { jsx } from "react/jsx-runtime";
6
6
  const CardContext = React.createContext({});
7
7
  /**
8
8
  * Card component
9
- * Configureerbare container voor gestructureerde content met header, body en footer.
10
- * Gebruikt een stretched-link techniek: de link in `CardHeading` dekt de volledige card.
11
- * Screenreaders lezen alleen de heading-tekst als linknaam.
9
+ * Configureerbare container met vier optionele secties: `CardPreHeader`,
10
+ * `CardHeader`, `CardBody` en `CardFooter` (zie DR-2026-11).
11
+ *
12
+ * Zet `CardHeader` in de JSX altijd vóór `CardPreHeader`: zo kondigt een
13
+ * screenreader de heading eerst aan. De CSS zet de pre-header visueel bovenaan.
14
+ *
15
+ * Met `href` wordt de heading een stretched link: de link dekt de volledige
16
+ * card, en screenreaders lezen alleen de heading-tekst als linknaam.
12
17
  *
13
18
  * @example
14
19
  * ```tsx
15
20
  * <Card href="/artikel/slug">
16
21
  * <CardHeader>
17
- * <Image src="/foto.jpg" alt="" width={800} height={450} ratio="16:9" />
22
+ * <CardHeading level={2}>Artikeltitel</CardHeading>
18
23
  * </CardHeader>
24
+ * <CardPreHeader>
25
+ * <Image src="/foto.jpg" alt="" width={800} height={450} ratio="16:9" />
26
+ * </CardPreHeader>
19
27
  * <CardBody>
20
- * <CardHeading level={2}>Artikeltitel</CardHeading>
21
28
  * <Paragraph>Korte beschrijving.</Paragraph>
22
29
  * </CardBody>
23
30
  * <CardFooter>
24
- * <Link href="/artikel/slug" aria-hidden tabIndex={-1}>Lees meer</Link>
31
+ * <CardAffordance>Lees meer</CardAffordance>
25
32
  * </CardFooter>
26
33
  * </Card>
27
34
  * ```
@@ -39,13 +46,14 @@ const Card = React.forwardRef(({ className, href, children, ...props }, ref) =>
39
46
  });
40
47
  Card.displayName = "Card";
41
48
  /**
42
- * CardHeader sub-component
49
+ * CardPreHeader sub-component
50
+ * Staat in de DOM ná `CardHeader` en komt visueel bovenaan via `order: -1`.
43
51
  * Zonder children → toont automatisch een afbeeldingsplaceholder.
44
52
  */
45
- const CardHeader = React.forwardRef(({ className, children, ...props }, ref) => {
53
+ const CardPreHeader = React.forwardRef(({ className, children, ...props }, ref) => {
46
54
  return /* @__PURE__ */ jsx("div", {
47
55
  ref,
48
- className: classNames("dsn-card__header", className),
56
+ className: classNames("dsn-card__pre-header", className),
49
57
  ...props,
50
58
  children: children ? children : /* @__PURE__ */ jsx("div", {
51
59
  className: "dsn-card__image-placeholder",
@@ -53,10 +61,24 @@ const CardHeader = React.forwardRef(({ className, children, ...props }, ref) =>
53
61
  })
54
62
  });
55
63
  });
64
+ CardPreHeader.displayName = "CardPreHeader";
65
+ /**
66
+ * CardHeader sub-component
67
+ * Bevat de heading of het label van de card. Zet hem in de JSX vóór
68
+ * `CardPreHeader`.
69
+ */
70
+ const CardHeader = React.forwardRef(({ className, children, ...props }, ref) => {
71
+ return /* @__PURE__ */ jsx("div", {
72
+ ref,
73
+ className: classNames("dsn-card__header", className),
74
+ ...props,
75
+ children
76
+ });
77
+ });
56
78
  CardHeader.displayName = "CardHeader";
57
79
  /**
58
80
  * CardBody sub-component
59
- * Groeit via `flex: 1` zodat de footer altijd onderaan uitlijnt.
81
+ * Inhoudssectie onder de header.
60
82
  */
61
83
  const CardBody = React.forwardRef(({ className, children, ...props }, ref) => {
62
84
  return /* @__PURE__ */ jsx("div", {
@@ -70,7 +92,7 @@ CardBody.displayName = "CardBody";
70
92
  /**
71
93
  * CardHeading sub-component
72
94
  * Ontvangt `href` automatisch via React context van de parent `Card`.
73
- * Wanneer `href` beschikbaar is, wraps de heading-tekst in een `<a class="dsn-card-heading__link">`.
95
+ * Wanneer `href` beschikbaar is, staat de heading-tekst in een `<a class="dsn-card__link">`.
74
96
  * Het `::before` pseudo-element dekt de volledige card (stretched link).
75
97
  */
76
98
  const CardHeading = React.forwardRef(({ className, level = 2, children, ...props }, ref) => {
@@ -78,21 +100,67 @@ const CardHeading = React.forwardRef(({ className, level = 2, children, ...props
78
100
  const Tag = `h${level}`;
79
101
  return /* @__PURE__ */ jsx(Tag, {
80
102
  ref,
81
- className: classNames("dsn-card-heading", className),
103
+ className: classNames("dsn-card__heading", className),
82
104
  ...props,
83
105
  children: href ? /* @__PURE__ */ jsx("a", {
84
106
  href,
85
- className: "dsn-card-heading__link",
107
+ className: "dsn-card__link",
86
108
  children
87
109
  }) : children
88
110
  });
89
111
  });
90
112
  CardHeading.displayName = "CardHeading";
91
113
  /**
114
+ * CardLabel sub-component
115
+ * Gebruik in plaats van `CardHeading` wanneer de card geen nieuw onderwerp
116
+ * introduceert, zoals bij login-opties of instellingen. Ontvangt `href` via
117
+ * context, net als `CardHeading`.
118
+ */
119
+ const CardLabel = React.forwardRef(({ className, children, ...props }, ref) => {
120
+ const { href } = React.useContext(CardContext);
121
+ return /* @__PURE__ */ jsx("p", {
122
+ ref,
123
+ className: classNames("dsn-card__label", className),
124
+ ...props,
125
+ children: href ? /* @__PURE__ */ jsx("a", {
126
+ href,
127
+ className: "dsn-card__link",
128
+ children
129
+ }) : children
130
+ });
131
+ });
132
+ CardLabel.displayName = "CardLabel";
133
+ /**
134
+ * CardDescription sub-component
135
+ * Korte omschrijving met eigen typografie-tokens.
136
+ */
137
+ const CardDescription = React.forwardRef(({ className, children, ...props }, ref) => {
138
+ return /* @__PURE__ */ jsx("p", {
139
+ ref,
140
+ className: classNames("dsn-card__description", className),
141
+ ...props,
142
+ children
143
+ });
144
+ });
145
+ CardDescription.displayName = "CardDescription";
146
+ /**
147
+ * CardMeta sub-component
148
+ * Aanvullende gegevens bij de card, zoals een datum.
149
+ */
150
+ const CardMeta = React.forwardRef(({ className, children, ...props }, ref) => {
151
+ return /* @__PURE__ */ jsx("p", {
152
+ ref,
153
+ className: classNames("dsn-card__meta", className),
154
+ ...props,
155
+ children
156
+ });
157
+ });
158
+ CardMeta.displayName = "CardMeta";
159
+ /**
92
160
  * CardFooter sub-component
93
- * Directe kinderen staan boven de stretched link via `z-index: 2` in CSS.
94
- * Gebruik `aria-hidden` + `tabIndex={-1}` op de link wanneer deze dezelfde
95
- * bestemming heeft als de card — vermijdt een dubbele tabstop.
161
+ * Staat altijd onderaan de card. Links en buttons staan boven de stretched
162
+ * link en blijven zelfstandig klikbaar. Voor een visuele "Lees meer" naar
163
+ * dezelfde bestemming als de card: gebruik `CardAffordance`.
96
164
  */
97
165
  const CardFooter = React.forwardRef(({ className, children, ...props }, ref) => {
98
166
  return /* @__PURE__ */ jsx("div", {
@@ -104,6 +172,21 @@ const CardFooter = React.forwardRef(({ className, children, ...props }, ref) =>
104
172
  });
105
173
  CardFooter.displayName = "CardFooter";
106
174
  /**
175
+ * CardAffordance sub-component
176
+ * Een `<span aria-hidden="true">` die eruitziet als een link. De stretched
177
+ * link vangt de klik al af, dus er is geen tweede tabstop nodig.
178
+ */
179
+ const CardAffordance = React.forwardRef(({ className, children, ...props }, ref) => {
180
+ return /* @__PURE__ */ jsx("span", {
181
+ ref,
182
+ className: classNames("dsn-card__affordance", className),
183
+ "aria-hidden": "true",
184
+ ...props,
185
+ children
186
+ });
187
+ });
188
+ CardAffordance.displayName = "CardAffordance";
189
+ /**
107
190
  * CardGroup sub-component
108
191
  * Flexbox wrapper die gelijke hoogte garandeert en de footer in elke card onderaan uitlijnt.
109
192
  * Rendert `role="list"` wanneer `as="ul"` — nodig omdat CSS-resets de lijstsemantiek verwijderen.
@@ -120,6 +203,6 @@ const CardGroup = React.forwardRef(({ className, as: Tag = "ul", children, ...pr
120
203
  });
121
204
  CardGroup.displayName = "CardGroup";
122
205
  //#endregion
123
- export { Card, CardBody, CardFooter, CardGroup, CardHeader, CardHeading };
206
+ export { Card, CardAffordance, CardBody, CardDescription, CardFooter, CardGroup, CardHeader, CardHeading, CardLabel, CardMeta, CardPreHeader };
124
207
 
125
208
  //# sourceMappingURL=Card2.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Card2.mjs","names":[],"sources":["../../src/Card/Card.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames } from '@dsn-starter-kit/core';\nimport './Card.css';\n\n// =============================================================================\n// Context — Card deelt href met CardHeading via React context\n// =============================================================================\n\ninterface CardContextValue {\n href?: string;\n}\n\nconst CardContext = React.createContext<CardContextValue>({});\n\n// =============================================================================\n// Card — root container\n// =============================================================================\n\nexport interface CardProps extends React.HTMLAttributes<HTMLElement> {\n /**\n * URL voor de stretched link. De `CardHeading` ontvangt `href` automatisch\n * via React context en wraps de heading-tekst in een `<a>`.\n */\n href?: string;\n\n /** Sub-componenten: `CardHeader`, `CardBody`, `CardFooter` */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * Card component\n * Configureerbare container voor gestructureerde content met header, body en footer.\n * Gebruikt een stretched-link techniek: de link in `CardHeading` dekt de volledige card.\n * Screenreaders lezen alleen de heading-tekst als linknaam.\n *\n * @example\n * ```tsx\n * <Card href=\"/artikel/slug\">\n * <CardHeader>\n * <Image src=\"/foto.jpg\" alt=\"\" width={800} height={450} ratio=\"16:9\" />\n * </CardHeader>\n * <CardBody>\n * <CardHeading level={2}>Artikeltitel</CardHeading>\n * <Paragraph>Korte beschrijving.</Paragraph>\n * </CardBody>\n * <CardFooter>\n * <Link href=\"/artikel/slug\" aria-hidden tabIndex={-1}>Lees meer</Link>\n * </CardFooter>\n * </Card>\n * ```\n */\nexport const Card = React.forwardRef<HTMLElement, CardProps>(\n ({ className, href, children, ...props }, ref) => {\n return (\n <CardContext.Provider value={{ href }}>\n <article\n ref={ref}\n className={classNames('dsn-card', className)}\n {...props}\n >\n {children}\n </article>\n </CardContext.Provider>\n );\n }\n);\n\nCard.displayName = 'Card';\n\n// =============================================================================\n// CardHeader — optionele afbeeldingssectie\n// =============================================================================\n\nexport interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Afbeelding (`Image` component). Zonder children → toont placeholder\n * met `aspect-ratio: 16 / 9` voor visuele consistentie in groep.\n */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardHeader sub-component\n * Zonder children → toont automatisch een afbeeldingsplaceholder.\n */\nexport const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-card__header', className)}\n {...props}\n >\n {children ? (\n children\n ) : (\n <div className=\"dsn-card__image-placeholder\" aria-hidden=\"true\" />\n )}\n </div>\n );\n }\n);\n\nCardHeader.displayName = 'CardHeader';\n\n// =============================================================================\n// CardBody — inhoudssectie\n// =============================================================================\n\nexport interface CardBodyProps extends React.HTMLAttributes<HTMLDivElement> {\n /** `CardHeading`, optionele extra content (bijv. `StatusBadge`), `Paragraph` */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardBody sub-component\n * Groeit via `flex: 1` zodat de footer altijd onderaan uitlijnt.\n */\nexport const CardBody = React.forwardRef<HTMLDivElement, CardBodyProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-card__body', className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nCardBody.displayName = 'CardBody';\n\n// =============================================================================\n// CardHeading — heading met stretched link\n// =============================================================================\n\nexport interface CardHeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {\n /**\n * Semantisch heading-niveau. Visuele appearance is altijd \"card-heading\".\n * @default 2\n */\n level?: 2 | 3 | 4;\n\n /** Heading-tekst */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardHeading sub-component\n * Ontvangt `href` automatisch via React context van de parent `Card`.\n * Wanneer `href` beschikbaar is, wraps de heading-tekst in een `<a class=\"dsn-card-heading__link\">`.\n * Het `::before` pseudo-element dekt de volledige card (stretched link).\n */\nexport const CardHeading = React.forwardRef<\n HTMLHeadingElement,\n CardHeadingProps\n>(({ className, level = 2, children, ...props }, ref) => {\n const { href } = React.useContext(CardContext);\n const Tag = `h${level}` as 'h2' | 'h3' | 'h4';\n\n return (\n <Tag\n ref={ref}\n className={classNames('dsn-card-heading', className)}\n {...props}\n >\n {href ? (\n <a href={href} className=\"dsn-card-heading__link\">\n {children}\n </a>\n ) : (\n children\n )}\n </Tag>\n );\n});\n\nCardHeading.displayName = 'CardHeading';\n\n// =============================================================================\n// CardFooter — voettekst\n// =============================================================================\n\nexport interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** `Link` of `ButtonLink` — staat boven de stretched link via CSS z-index */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardFooter sub-component\n * Directe kinderen staan boven de stretched link via `z-index: 2` in CSS.\n * Gebruik `aria-hidden` + `tabIndex={-1}` op de link wanneer deze dezelfde\n * bestemming heeft als de card — vermijdt een dubbele tabstop.\n */\nexport const CardFooter = React.forwardRef<HTMLDivElement, CardFooterProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-card__footer', className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nCardFooter.displayName = 'CardFooter';\n\n// =============================================================================\n// CardGroup — layout wrapper\n// =============================================================================\n\nexport interface CardGroupProps extends React.HTMLAttributes<HTMLElement> {\n /**\n * Semantisch container-element.\n * Gebruik `div` wanneer cards geen lijst-context hebben.\n * @default 'ul'\n */\n as?: 'ul' | 'div';\n\n /** `Card` componenten */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardGroup sub-component\n * Flexbox wrapper die gelijke hoogte garandeert en de footer in elke card onderaan uitlijnt.\n * Rendert `role=\"list\"` wanneer `as=\"ul\"` — nodig omdat CSS-resets de lijstsemantiek verwijderen.\n */\nexport const CardGroup = React.forwardRef<HTMLElement, CardGroupProps>(\n ({ className, as: Tag = 'ul', children, ...props }, ref) => {\n const roleProps = Tag === 'ul' ? { role: 'list' as const } : {};\n\n return (\n <Tag\n ref={ref as React.Ref<HTMLUListElement & HTMLDivElement>}\n className={classNames('dsn-card-group', className)}\n {...roleProps}\n {...props}\n >\n {children}\n </Tag>\n );\n }\n);\n\nCardGroup.displayName = 'CardGroup';\n"],"mappings":";;;;;AAYA,MAAM,cAAc,MAAM,cAAgC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;AAyC5D,MAAa,OAAO,MAAM,YACvB,EAAE,WAAW,MAAM,UAAU,GAAG,SAAS,QAAQ;CAChD,OACE,oBAAC,YAAY,UAAb;EAAsB,OAAO,EAAE,KAAK;EAClC,UAAA,oBAAC,WAAD;GACO;GACL,WAAW,WAAW,YAAY,SAAS;GAC3C,GAAI;GAEH;EACM,CAAA;CACW,CAAA;AAE1B,CACF;AAEA,KAAK,cAAc;;;;;AAoBnB,MAAa,aAAa,MAAM,YAC7B,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1C,OACE,oBAAC,OAAD;EACO;EACL,WAAW,WAAW,oBAAoB,SAAS;EACnD,GAAI;EAEH,UAAA,WACC,WAEA,oBAAC,OAAD;GAAK,WAAU;GAA8B,eAAY;EAAQ,CAAA;CAEhE,CAAA;AAET,CACF;AAEA,WAAW,cAAc;;;;;AAiBzB,MAAa,WAAW,MAAM,YAC3B,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1C,OACE,oBAAC,OAAD;EACO;EACL,WAAW,WAAW,kBAAkB,SAAS;EACjD,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,SAAS,cAAc;;;;;;;AAyBvB,MAAa,cAAc,MAAM,YAG9B,EAAE,WAAW,QAAQ,GAAG,UAAU,GAAG,SAAS,QAAQ;CACvD,MAAM,EAAE,SAAS,MAAM,WAAW,WAAW;CAC7C,MAAM,MAAM,IAAI;CAEhB,OACE,oBAAC,KAAD;EACO;EACL,WAAW,WAAW,oBAAoB,SAAS;EACnD,GAAI;EAEH,UAAA,OACC,oBAAC,KAAD;GAAS;GAAM,WAAU;GACtB;EACA,CAAA,IAEH;CAEC,CAAA;AAET,CAAC;AAED,YAAY,cAAc;;;;;;;AAmB1B,MAAa,aAAa,MAAM,YAC7B,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1C,OACE,oBAAC,OAAD;EACO;EACL,WAAW,WAAW,oBAAoB,SAAS;EACnD,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,WAAW,cAAc;;;;;;AAyBzB,MAAa,YAAY,MAAM,YAC5B,EAAE,WAAW,IAAI,MAAM,MAAM,UAAU,GAAG,SAAS,QAAQ;CAC1D,MAAM,YAAY,QAAQ,OAAO,EAAE,MAAM,OAAgB,IAAI,CAAC;CAE9D,OACE,oBAAC,KAAD;EACO;EACL,WAAW,WAAW,kBAAkB,SAAS;EACjD,GAAI;EACJ,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,UAAU,cAAc"}
1
+ {"version":3,"file":"Card2.mjs","names":[],"sources":["../../src/Card/Card.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames } from '@dsn-starter-kit/core';\nimport './Card.css';\n\n// =============================================================================\n// Context — Card deelt href met CardHeading via React context\n// =============================================================================\n\ninterface CardContextValue {\n href?: string;\n}\n\nconst CardContext = React.createContext<CardContextValue>({});\n\n// =============================================================================\n// Card — root container\n// =============================================================================\n\nexport interface CardProps extends React.HTMLAttributes<HTMLElement> {\n /**\n * URL voor de stretched link. `CardHeading` en `CardLabel` ontvangen `href`\n * automatisch via React context en zetten hun tekst in een `<a>`.\n */\n href?: string;\n\n /** Secties: `CardHeader`, `CardPreHeader`, `CardBody`, `CardFooter` */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * Card component\n * Configureerbare container met vier optionele secties: `CardPreHeader`,\n * `CardHeader`, `CardBody` en `CardFooter` (zie DR-2026-11).\n *\n * Zet `CardHeader` in de JSX altijd vóór `CardPreHeader`: zo kondigt een\n * screenreader de heading eerst aan. De CSS zet de pre-header visueel bovenaan.\n *\n * Met `href` wordt de heading een stretched link: de link dekt de volledige\n * card, en screenreaders lezen alleen de heading-tekst als linknaam.\n *\n * @example\n * ```tsx\n * <Card href=\"/artikel/slug\">\n * <CardHeader>\n * <CardHeading level={2}>Artikeltitel</CardHeading>\n * </CardHeader>\n * <CardPreHeader>\n * <Image src=\"/foto.jpg\" alt=\"\" width={800} height={450} ratio=\"16:9\" />\n * </CardPreHeader>\n * <CardBody>\n * <Paragraph>Korte beschrijving.</Paragraph>\n * </CardBody>\n * <CardFooter>\n * <CardAffordance>Lees meer</CardAffordance>\n * </CardFooter>\n * </Card>\n * ```\n */\nexport const Card = React.forwardRef<HTMLElement, CardProps>(\n ({ className, href, children, ...props }, ref) => {\n return (\n <CardContext.Provider value={{ href }}>\n <article\n ref={ref}\n className={classNames('dsn-card', className)}\n {...props}\n >\n {children}\n </article>\n </CardContext.Provider>\n );\n }\n);\n\nCard.displayName = 'Card';\n\n// =============================================================================\n// CardPreHeader — slot dat visueel bovenaan staat\n// =============================================================================\n\nexport interface CardPreHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * Afbeelding, badge, logo of icoon. Een `Image` als direct kind loopt door\n * tot de rand van de card. Zonder children → toont een placeholder met\n * `aspect-ratio: 16 / 9` voor visuele consistentie in een groep.\n *\n * Zet hier geen focusbare elementen in: de pre-header staat in de DOM ná de\n * header, dus de focusvolgorde zou afwijken van de visuele volgorde.\n */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardPreHeader sub-component\n * Staat in de DOM ná `CardHeader` en komt visueel bovenaan via `order: -1`.\n * Zonder children → toont automatisch een afbeeldingsplaceholder.\n */\nexport const CardPreHeader = React.forwardRef<\n HTMLDivElement,\n CardPreHeaderProps\n>(({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-card__pre-header', className)}\n {...props}\n >\n {children ? (\n children\n ) : (\n <div className=\"dsn-card__image-placeholder\" aria-hidden=\"true\" />\n )}\n </div>\n );\n});\n\nCardPreHeader.displayName = 'CardPreHeader';\n\n// =============================================================================\n// CardHeader — heading of label, plus bijbehorende badges\n// =============================================================================\n\nexport interface CardHeaderProps extends React.HTMLAttributes<HTMLDivElement> {\n /** `CardHeading` of `CardLabel`, optioneel gevolgd door een `StatusBadge` */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardHeader sub-component\n * Bevat de heading of het label van de card. Zet hem in de JSX vóór\n * `CardPreHeader`.\n */\nexport const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-card__header', className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nCardHeader.displayName = 'CardHeader';\n\n// =============================================================================\n// CardBody — inhoudssectie\n// =============================================================================\n\nexport interface CardBodyProps extends React.HTMLAttributes<HTMLDivElement> {\n /** `Paragraph`, `CardDescription`, `CardMeta` of andere inhoud */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardBody sub-component\n * Inhoudssectie onder de header.\n */\nexport const CardBody = React.forwardRef<HTMLDivElement, CardBodyProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-card__body', className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nCardBody.displayName = 'CardBody';\n\n// =============================================================================\n// CardHeading — heading met stretched link\n// =============================================================================\n\nexport interface CardHeadingProps extends React.HTMLAttributes<HTMLHeadingElement> {\n /**\n * Semantisch heading-niveau. Visuele appearance is altijd \"card-heading\".\n * @default 2\n */\n level?: 2 | 3 | 4;\n\n /** Heading-tekst */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardHeading sub-component\n * Ontvangt `href` automatisch via React context van de parent `Card`.\n * Wanneer `href` beschikbaar is, staat de heading-tekst in een `<a class=\"dsn-card__link\">`.\n * Het `::before` pseudo-element dekt de volledige card (stretched link).\n */\nexport const CardHeading = React.forwardRef<\n HTMLHeadingElement,\n CardHeadingProps\n>(({ className, level = 2, children, ...props }, ref) => {\n const { href } = React.useContext(CardContext);\n const Tag = `h${level}` as 'h2' | 'h3' | 'h4';\n\n return (\n <Tag\n ref={ref}\n className={classNames('dsn-card__heading', className)}\n {...props}\n >\n {href ? (\n <a href={href} className=\"dsn-card__link\">\n {children}\n </a>\n ) : (\n children\n )}\n </Tag>\n );\n});\n\nCardHeading.displayName = 'CardHeading';\n\n// =============================================================================\n// CardLabel — compacte aanduiding zonder heading-semantiek\n// =============================================================================\n\nexport interface CardLabelProps extends React.HTMLAttributes<HTMLParagraphElement> {\n /** Label-tekst */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardLabel sub-component\n * Gebruik in plaats van `CardHeading` wanneer de card geen nieuw onderwerp\n * introduceert, zoals bij login-opties of instellingen. Ontvangt `href` via\n * context, net als `CardHeading`.\n */\nexport const CardLabel = React.forwardRef<HTMLParagraphElement, CardLabelProps>(\n ({ className, children, ...props }, ref) => {\n const { href } = React.useContext(CardContext);\n\n return (\n <p\n ref={ref}\n className={classNames('dsn-card__label', className)}\n {...props}\n >\n {href ? (\n <a href={href} className=\"dsn-card__link\">\n {children}\n </a>\n ) : (\n children\n )}\n </p>\n );\n }\n);\n\nCardLabel.displayName = 'CardLabel';\n\n// =============================================================================\n// CardDescription — korte omschrijving\n// =============================================================================\n\nexport interface CardDescriptionProps extends React.HTMLAttributes<HTMLParagraphElement> {\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardDescription sub-component\n * Korte omschrijving met eigen typografie-tokens.\n */\nexport const CardDescription = React.forwardRef<\n HTMLParagraphElement,\n CardDescriptionProps\n>(({ className, children, ...props }, ref) => {\n return (\n <p\n ref={ref}\n className={classNames('dsn-card__description', className)}\n {...props}\n >\n {children}\n </p>\n );\n});\n\nCardDescription.displayName = 'CardDescription';\n\n// =============================================================================\n// CardMeta — aanvullende gegevens, zoals een datum\n// =============================================================================\n\nexport interface CardMetaProps extends React.HTMLAttributes<HTMLParagraphElement> {\n /** Bijv. een `<time>`-element of een auteur */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardMeta sub-component\n * Aanvullende gegevens bij de card, zoals een datum.\n */\nexport const CardMeta = React.forwardRef<HTMLParagraphElement, CardMetaProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <p\n ref={ref}\n className={classNames('dsn-card__meta', className)}\n {...props}\n >\n {children}\n </p>\n );\n }\n);\n\nCardMeta.displayName = 'CardMeta';\n\n// =============================================================================\n// CardFooter — voettekst\n// =============================================================================\n\nexport interface CardFooterProps extends React.HTMLAttributes<HTMLDivElement> {\n /** `CardAffordance`, of een `Link` / `ButtonLink` naar een andere bestemming */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardFooter sub-component\n * Staat altijd onderaan de card. Links en buttons staan boven de stretched\n * link en blijven zelfstandig klikbaar. Voor een visuele \"Lees meer\" naar\n * dezelfde bestemming als de card: gebruik `CardAffordance`.\n */\nexport const CardFooter = React.forwardRef<HTMLDivElement, CardFooterProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={classNames('dsn-card__footer', className)}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nCardFooter.displayName = 'CardFooter';\n\n// =============================================================================\n// CardAffordance — visuele hint zonder eigen interactie\n// =============================================================================\n\nexport interface CardAffordanceProps extends React.HTMLAttributes<HTMLSpanElement> {\n /** Bijv. \"Lees meer\" */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardAffordance sub-component\n * Een `<span aria-hidden=\"true\">` die eruitziet als een link. De stretched\n * link vangt de klik al af, dus er is geen tweede tabstop nodig.\n */\nexport const CardAffordance = React.forwardRef<\n HTMLSpanElement,\n CardAffordanceProps\n>(({ className, children, ...props }, ref) => {\n return (\n <span\n ref={ref}\n className={classNames('dsn-card__affordance', className)}\n aria-hidden=\"true\"\n {...props}\n >\n {children}\n </span>\n );\n});\n\nCardAffordance.displayName = 'CardAffordance';\n\n// =============================================================================\n// CardGroup — layout wrapper\n// =============================================================================\n\nexport interface CardGroupProps extends React.HTMLAttributes<HTMLElement> {\n /**\n * Semantisch container-element.\n * Gebruik `div` wanneer cards geen lijst-context hebben.\n * @default 'ul'\n */\n as?: 'ul' | 'div';\n\n /** `Card` componenten */\n children?: React.ReactNode;\n\n className?: string;\n}\n\n/**\n * CardGroup sub-component\n * Flexbox wrapper die gelijke hoogte garandeert en de footer in elke card onderaan uitlijnt.\n * Rendert `role=\"list\"` wanneer `as=\"ul\"` — nodig omdat CSS-resets de lijstsemantiek verwijderen.\n */\nexport const CardGroup = React.forwardRef<HTMLElement, CardGroupProps>(\n ({ className, as: Tag = 'ul', children, ...props }, ref) => {\n const roleProps = Tag === 'ul' ? { role: 'list' as const } : {};\n\n return (\n <Tag\n ref={ref as React.Ref<HTMLUListElement & HTMLDivElement>}\n className={classNames('dsn-card-group', className)}\n {...roleProps}\n {...props}\n >\n {children}\n </Tag>\n );\n }\n);\n\nCardGroup.displayName = 'CardGroup';\n"],"mappings":";;;;;AAYA,MAAM,cAAc,MAAM,cAAgC,CAAC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgD5D,MAAa,OAAO,MAAM,YACvB,EAAE,WAAW,MAAM,UAAU,GAAG,SAAS,QAAQ;CAChD,OACE,oBAAC,YAAY,UAAb;EAAsB,OAAO,EAAE,KAAK;EAClC,UAAA,oBAAC,WAAD;GACO;GACL,WAAW,WAAW,YAAY,SAAS;GAC3C,GAAI;GAEH;EACM,CAAA;CACW,CAAA;AAE1B,CACF;AAEA,KAAK,cAAc;;;;;;AAyBnB,MAAa,gBAAgB,MAAM,YAGhC,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC5C,OACE,oBAAC,OAAD;EACO;EACL,WAAW,WAAW,wBAAwB,SAAS;EACvD,GAAI;EAEH,UAAA,WACC,WAEA,oBAAC,OAAD;GAAK,WAAU;GAA8B,eAAY;EAAQ,CAAA;CAEhE,CAAA;AAET,CAAC;AAED,cAAc,cAAc;;;;;;AAkB5B,MAAa,aAAa,MAAM,YAC7B,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1C,OACE,oBAAC,OAAD;EACO;EACL,WAAW,WAAW,oBAAoB,SAAS;EACnD,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,WAAW,cAAc;;;;;AAiBzB,MAAa,WAAW,MAAM,YAC3B,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1C,OACE,oBAAC,OAAD;EACO;EACL,WAAW,WAAW,kBAAkB,SAAS;EACjD,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,SAAS,cAAc;;;;;;;AAyBvB,MAAa,cAAc,MAAM,YAG9B,EAAE,WAAW,QAAQ,GAAG,UAAU,GAAG,SAAS,QAAQ;CACvD,MAAM,EAAE,SAAS,MAAM,WAAW,WAAW;CAC7C,MAAM,MAAM,IAAI;CAEhB,OACE,oBAAC,KAAD;EACO;EACL,WAAW,WAAW,qBAAqB,SAAS;EACpD,GAAI;EAEH,UAAA,OACC,oBAAC,KAAD;GAAS;GAAM,WAAU;GACtB;EACA,CAAA,IAEH;CAEC,CAAA;AAET,CAAC;AAED,YAAY,cAAc;;;;;;;AAmB1B,MAAa,YAAY,MAAM,YAC5B,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1C,MAAM,EAAE,SAAS,MAAM,WAAW,WAAW;CAE7C,OACE,oBAAC,KAAD;EACO;EACL,WAAW,WAAW,mBAAmB,SAAS;EAClD,GAAI;EAEH,UAAA,OACC,oBAAC,KAAD;GAAS;GAAM,WAAU;GACtB;EACA,CAAA,IAEH;CAED,CAAA;AAEP,CACF;AAEA,UAAU,cAAc;;;;;AAgBxB,MAAa,kBAAkB,MAAM,YAGlC,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC5C,OACE,oBAAC,KAAD;EACO;EACL,WAAW,WAAW,yBAAyB,SAAS;EACxD,GAAI;EAEH;CACA,CAAA;AAEP,CAAC;AAED,gBAAgB,cAAc;;;;;AAiB9B,MAAa,WAAW,MAAM,YAC3B,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1C,OACE,oBAAC,KAAD;EACO;EACL,WAAW,WAAW,kBAAkB,SAAS;EACjD,GAAI;EAEH;CACA,CAAA;AAEP,CACF;AAEA,SAAS,cAAc;;;;;;;AAmBvB,MAAa,aAAa,MAAM,YAC7B,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC1C,OACE,oBAAC,OAAD;EACO;EACL,WAAW,WAAW,oBAAoB,SAAS;EACnD,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,WAAW,cAAc;;;;;;AAkBzB,MAAa,iBAAiB,MAAM,YAGjC,EAAE,WAAW,UAAU,GAAG,SAAS,QAAQ;CAC5C,OACE,oBAAC,QAAD;EACO;EACL,WAAW,WAAW,wBAAwB,SAAS;EACvD,eAAY;EACZ,GAAI;EAEH;CACG,CAAA;AAEV,CAAC;AAED,eAAe,cAAc;;;;;;AAyB7B,MAAa,YAAY,MAAM,YAC5B,EAAE,WAAW,IAAI,MAAM,MAAM,UAAU,GAAG,SAAS,QAAQ;CAC1D,MAAM,YAAY,QAAQ,OAAO,EAAE,MAAM,OAAgB,IAAI,CAAC;CAE9D,OACE,oBAAC,KAAD;EACO;EACL,WAAW,WAAW,kBAAkB,SAAS;EACjD,GAAI;EACJ,GAAI;EAEH;CACE,CAAA;AAET,CACF;AAEA,UAAU,cAAc"}
@@ -1,2 +1,2 @@
1
- import { Card, CardBody, CardBodyProps, CardFooter, CardFooterProps, CardGroup, CardGroupProps, CardHeader, CardHeaderProps, CardHeading, CardHeadingProps, CardProps } from "./Card.mjs";
2
- export { Card, CardBody, type CardBodyProps, CardFooter, type CardFooterProps, CardGroup, type CardGroupProps, CardHeader, type CardHeaderProps, CardHeading, type CardHeadingProps, type CardProps };
1
+ import { Card, CardAffordance, CardAffordanceProps, CardBody, CardBodyProps, CardDescription, CardDescriptionProps, CardFooter, CardFooterProps, CardGroup, CardGroupProps, CardHeader, CardHeaderProps, CardHeading, CardHeadingProps, CardLabel, CardLabelProps, CardMeta, CardMetaProps, CardPreHeader, CardPreHeaderProps, CardProps } from "./Card.mjs";
2
+ export { Card, CardAffordance, type CardAffordanceProps, CardBody, type CardBodyProps, CardDescription, type CardDescriptionProps, CardFooter, type CardFooterProps, CardGroup, type CardGroupProps, CardHeader, type CardHeaderProps, CardHeading, type CardHeadingProps, CardLabel, type CardLabelProps, CardMeta, type CardMetaProps, CardPreHeader, type CardPreHeaderProps, type CardProps };
@@ -14,7 +14,7 @@ interface DateInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement
14
14
  /**
15
15
  * Date Input component
16
16
  * Date input with an interactive calendar button at inline-end that opens the native date picker.
17
- * Fixed width (sm) — not configurable, as date inputs have a predictable content width.
17
+ * Fixed inline-size (md): not configurable, as date inputs have a predictable content length.
18
18
  *
19
19
  * @example
20
20
  * ```tsx
@@ -8,7 +8,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
8
8
  /**
9
9
  * Date Input component
10
10
  * Date input with an interactive calendar button at inline-end that opens the native date picker.
11
- * Fixed width (sm) — not configurable, as date inputs have a predictable content width.
11
+ * Fixed inline-size (md): not configurable, as date inputs have a predictable content length.
12
12
  *
13
13
  * @example
14
14
  * ```tsx
@@ -1 +1 @@
1
- {"version":3,"file":"DateInput2.mjs","names":[],"sources":["../../src/DateInput/DateInput.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames } from '@dsn-starter-kit/core';\nimport { Button } from '../Button';\nimport { Icon } from '../Icon';\nimport './DateInput.css';\n\nexport interface DateInputProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'type'\n> {\n /**\n * Whether the input is in an invalid state\n * @default false\n */\n invalid?: boolean;\n\n /**\n * Additional CSS class names\n */\n className?: string;\n}\n\n/**\n * Date Input component\n * Date input with an interactive calendar button at inline-end that opens the native date picker.\n * Fixed width (sm) — not configurable, as date inputs have a predictable content width.\n *\n * @example\n * ```tsx\n * // Basic usage\n * <DateInput />\n *\n * // With label\n * <FormFieldLabel htmlFor=\"date\">Datum</FormFieldLabel>\n * <DateInput id=\"date\" />\n *\n * // With default value\n * <DateInput defaultValue=\"2025-03-15\" />\n *\n * // Invalid state\n * <DateInput invalid aria-invalid=\"true\" aria-describedby=\"error\" />\n * ```\n */\nexport const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(\n ({ className, invalid, disabled, readOnly, ...props }, ref) => {\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n // Merge external ref with internal ref\n const handleRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n }\n },\n [ref]\n );\n\n const handleButtonClick = () => {\n if (inputRef.current && 'showPicker' in inputRef.current) {\n inputRef.current.showPicker();\n }\n };\n\n const inputClasses = classNames(\n 'dsn-text-input',\n 'dsn-date-input',\n className\n );\n\n return (\n <div className=\"dsn-date-input-wrapper\">\n <input\n ref={handleRef}\n type=\"date\"\n className={inputClasses}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n readOnly={readOnly}\n {...props}\n />\n {!disabled && !readOnly && (\n <Button\n variant=\"subtle\"\n size=\"small\"\n iconOnly\n iconStart={<Icon name=\"calendar-event\" aria-hidden />}\n className=\"dsn-date-input__button\"\n onClick={handleButtonClick}\n >\n Datumkiezer openen\n </Button>\n )}\n </div>\n );\n }\n);\n\nDateInput.displayName = 'DateInput';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAa,YAAY,MAAM,YAC5B,EAAE,WAAW,SAAS,UAAU,UAAU,GAAG,SAAS,QAAQ;CAC7D,MAAM,WAAW,MAAM,OAAyB,IAAI;CAGpD,MAAM,YAAY,MAAM,aACrB,SAAkC;EACjC,SAA8D,UAC5D;EACF,IAAI,OAAO,QAAQ,YACjB,IAAI,IAAI;OACH,IAAI,KACT,IAAyD,UACvD;CAEN,GACA,CAAC,GAAG,CACN;CAEA,MAAM,0BAA0B;EAC9B,IAAI,SAAS,WAAW,gBAAgB,SAAS,SAC/C,SAAS,QAAQ,WAAW;CAEhC;CAEA,MAAM,eAAe,WACnB,kBACA,kBACA,SACF;CAEA,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,SAAD;GACE,KAAK;GACL,MAAK;GACL,WAAW;GACX,gBAAc,WAAW,KAAA;GACf;GACA;GACV,GAAI;EACL,CAAA,GACA,CAAC,YAAY,CAAC,YACb,oBAAC,QAAD;GACE,SAAQ;GACR,MAAK;GACL,UAAA;GACA,WAAW,oBAAC,MAAD;IAAM,MAAK;IAAiB,eAAA;GAAa,CAAA;GACpD,WAAU;GACV,SAAS;GACV,UAAA;EAEO,CAAA,CAEP;;AAET,CACF;AAEA,UAAU,cAAc"}
1
+ {"version":3,"file":"DateInput2.mjs","names":[],"sources":["../../src/DateInput/DateInput.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames } from '@dsn-starter-kit/core';\nimport { Button } from '../Button';\nimport { Icon } from '../Icon';\nimport './DateInput.css';\n\nexport interface DateInputProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'type'\n> {\n /**\n * Whether the input is in an invalid state\n * @default false\n */\n invalid?: boolean;\n\n /**\n * Additional CSS class names\n */\n className?: string;\n}\n\n/**\n * Date Input component\n * Date input with an interactive calendar button at inline-end that opens the native date picker.\n * Fixed inline-size (md): not configurable, as date inputs have a predictable content length.\n *\n * @example\n * ```tsx\n * // Basic usage\n * <DateInput />\n *\n * // With label\n * <FormFieldLabel htmlFor=\"date\">Datum</FormFieldLabel>\n * <DateInput id=\"date\" />\n *\n * // With default value\n * <DateInput defaultValue=\"2025-03-15\" />\n *\n * // Invalid state\n * <DateInput invalid aria-invalid=\"true\" aria-describedby=\"error\" />\n * ```\n */\nexport const DateInput = React.forwardRef<HTMLInputElement, DateInputProps>(\n ({ className, invalid, disabled, readOnly, ...props }, ref) => {\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n // Merge external ref with internal ref\n const handleRef = React.useCallback(\n (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n }\n },\n [ref]\n );\n\n const handleButtonClick = () => {\n if (inputRef.current && 'showPicker' in inputRef.current) {\n inputRef.current.showPicker();\n }\n };\n\n const inputClasses = classNames(\n 'dsn-text-input',\n 'dsn-date-input',\n className\n );\n\n return (\n <div className=\"dsn-date-input-wrapper\">\n <input\n ref={handleRef}\n type=\"date\"\n className={inputClasses}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n readOnly={readOnly}\n {...props}\n />\n {!disabled && !readOnly && (\n <Button\n variant=\"subtle\"\n size=\"small\"\n iconOnly\n iconStart={<Icon name=\"calendar-event\" aria-hidden />}\n className=\"dsn-date-input__button\"\n onClick={handleButtonClick}\n >\n Datumkiezer openen\n </Button>\n )}\n </div>\n );\n }\n);\n\nDateInput.displayName = 'DateInput';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAa,YAAY,MAAM,YAC5B,EAAE,WAAW,SAAS,UAAU,UAAU,GAAG,SAAS,QAAQ;CAC7D,MAAM,WAAW,MAAM,OAAyB,IAAI;CAGpD,MAAM,YAAY,MAAM,aACrB,SAAkC;EACjC,SAA8D,UAC5D;EACF,IAAI,OAAO,QAAQ,YACjB,IAAI,IAAI;OACH,IAAI,KACT,IAAyD,UACvD;CAEN,GACA,CAAC,GAAG,CACN;CAEA,MAAM,0BAA0B;EAC9B,IAAI,SAAS,WAAW,gBAAgB,SAAS,SAC/C,SAAS,QAAQ,WAAW;CAEhC;CAEA,MAAM,eAAe,WACnB,kBACA,kBACA,SACF;CAEA,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,SAAD;GACE,KAAK;GACL,MAAK;GACL,WAAW;GACX,gBAAc,WAAW,KAAA;GACf;GACA;GACV,GAAI;EACL,CAAA,GACA,CAAC,YAAY,CAAC,YACb,oBAAC,QAAD;GACE,SAAQ;GACR,MAAK;GACL,UAAA;GACA,WAAW,oBAAC,MAAD;IAAM,MAAK;IAAiB,eAAA;GAAa,CAAA;GACpD,WAAU;GACV,SAAS;GACV,UAAA;EAEO,CAAA,CAEP;;AAET,CACF;AAEA,UAAU,cAAc"}
@@ -61,7 +61,7 @@ const DateInputGroup = React.forwardRef(({ className, value, onChange, invalid,
61
61
  children: "Dag"
62
62
  }), /* @__PURE__ */ jsx(NumberInput, {
63
63
  id: dayId,
64
- width: "xs",
64
+ inlineSize: "xs",
65
65
  value: value?.day ?? "",
66
66
  onChange: handleChange("day"),
67
67
  invalid,
@@ -80,7 +80,7 @@ const DateInputGroup = React.forwardRef(({ className, value, onChange, invalid,
80
80
  children: "Maand"
81
81
  }), /* @__PURE__ */ jsx(NumberInput, {
82
82
  id: monthId,
83
- width: "xs",
83
+ inlineSize: "xs",
84
84
  value: value?.month ?? "",
85
85
  onChange: handleChange("month"),
86
86
  invalid,
@@ -99,7 +99,7 @@ const DateInputGroup = React.forwardRef(({ className, value, onChange, invalid,
99
99
  children: "Jaar"
100
100
  }), /* @__PURE__ */ jsx(NumberInput, {
101
101
  id: yearId,
102
- width: "sm",
102
+ inlineSize: "sm",
103
103
  value: value?.year ?? "",
104
104
  onChange: handleChange("year"),
105
105
  invalid,
@@ -1 +1 @@
1
- {"version":3,"file":"DateInputGroup2.mjs","names":[],"sources":["../../src/DateInputGroup/DateInputGroup.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames } from '@dsn-starter-kit/core';\nimport { NumberInput } from '../NumberInput';\nimport './DateInputGroup.css';\n\nexport interface DateInputGroupValue {\n day: string;\n month: string;\n year: string;\n}\n\nexport interface DateInputGroupProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange'\n> {\n /**\n * The current value of the date group\n */\n value?: DateInputGroupValue;\n\n /**\n * Called when any field changes, with the full updated value object\n */\n onChange?: (value: DateInputGroupValue) => void;\n\n /**\n * Whether all fields are in an invalid state\n * @default false\n */\n invalid?: boolean;\n\n /**\n * Whether all fields are disabled\n * @default false\n */\n disabled?: boolean;\n\n /**\n * id prefix used to generate unique ids for each field (dag, maand, jaar)\n * E.g. id=\"geboortedatum\" → \"geboortedatum-dag\", \"geboortedatum-maand\", \"geboortedatum-jaar\"\n */\n id?: string;\n}\n\n/**\n * Date Input Group component\n * Three separate inputs for day, month and year.\n * More accessible than a native date picker: works consistently across all browsers and\n * devices, and allows partial input (e.g. year only).\n *\n * Wrap in a FormFieldset for a complete form field with legend and error message.\n *\n * @example\n * ```tsx\n * // Basic usage\n * <DateInputGroup\n * value={{ day: '', month: '', year: '' }}\n * onChange={(val) => setValue(val)}\n * />\n *\n * // Complete form field\n * <FormFieldset>\n * <FormFieldLegend>Geboortedatum</FormFieldLegend>\n * <FormFieldDescription>Bijvoorbeeld: 15 3 1990</FormFieldDescription>\n * <DateInputGroup\n * id=\"geboortedatum\"\n * value={value}\n * onChange={setValue}\n * />\n * </FormFieldset>\n *\n * // Invalid state\n * <DateInputGroup invalid value={value} onChange={setValue} />\n * ```\n */\nexport const DateInputGroup = React.forwardRef<\n HTMLDivElement,\n DateInputGroupProps\n>(({ className, value, onChange, invalid, disabled, id, ...props }, ref) => {\n const classes = classNames('dsn-date-input-group', className);\n\n const handleChange =\n (field: keyof DateInputGroupValue) =>\n (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange?.({\n day: value?.day ?? '',\n month: value?.month ?? '',\n year: value?.year ?? '',\n [field]: e.target.value,\n });\n };\n\n const dayId = id ? `${id}-dag` : undefined;\n const monthId = id ? `${id}-maand` : undefined;\n const yearId = id ? `${id}-jaar` : undefined;\n\n return (\n <div ref={ref} className={classes} {...props}>\n <div className=\"dsn-date-input-group__field\">\n <label className=\"dsn-date-input-group__label\" htmlFor={dayId}>\n Dag\n </label>\n <NumberInput\n id={dayId}\n width=\"xs\"\n value={value?.day ?? ''}\n onChange={handleChange('day')}\n invalid={invalid}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n placeholder=\"DD\"\n min={1}\n max={31}\n />\n </div>\n <div className=\"dsn-date-input-group__field\">\n <label className=\"dsn-date-input-group__label\" htmlFor={monthId}>\n Maand\n </label>\n <NumberInput\n id={monthId}\n width=\"xs\"\n value={value?.month ?? ''}\n onChange={handleChange('month')}\n invalid={invalid}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n placeholder=\"MM\"\n min={1}\n max={12}\n />\n </div>\n <div className=\"dsn-date-input-group__field\">\n <label className=\"dsn-date-input-group__label\" htmlFor={yearId}>\n Jaar\n </label>\n <NumberInput\n id={yearId}\n width=\"sm\"\n value={value?.year ?? ''}\n onChange={handleChange('year')}\n invalid={invalid}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n placeholder=\"JJJJ\"\n min={1}\n max={9999}\n />\n </div>\n </div>\n );\n});\n\nDateInputGroup.displayName = 'DateInputGroup';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2EA,MAAa,iBAAiB,MAAM,YAGjC,EAAE,WAAW,OAAO,UAAU,SAAS,UAAU,IAAI,GAAG,SAAS,QAAQ;CAC1E,MAAM,UAAU,WAAW,wBAAwB,SAAS;CAE5D,MAAM,gBACH,WACA,MAA2C;EAC1C,WAAW;GACT,KAAK,OAAO,OAAO;GACnB,OAAO,OAAO,SAAS;GACvB,MAAM,OAAO,QAAQ;IACpB,QAAQ,EAAE,OAAO;EACpB,CAAC;CACH;CAEF,MAAM,QAAQ,KAAK,GAAG,GAAG,QAAQ,KAAA;CACjC,MAAM,UAAU,KAAK,GAAG,GAAG,UAAU,KAAA;CACrC,MAAM,SAAS,KAAK,GAAG,GAAG,SAAS,KAAA;CAEnC,OACE,qBAAC,OAAD;EAAU;EAAK,WAAW;EAAS,GAAI;EAAvC,UAAA;GACE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,SAAD;KAAO,WAAU;KAA8B,SAAS;KAAO,UAAA;IAExD,CAAA,GACP,oBAAC,aAAD;KACE,IAAI;KACJ,OAAM;KACN,OAAO,OAAO,OAAO;KACrB,UAAU,aAAa,KAAK;KACnB;KACT,gBAAc,WAAW,KAAA;KACf;KACV,aAAY;KACZ,KAAK;KACL,KAAK;IACN,CAAA,CACE;;GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,SAAD;KAAO,WAAU;KAA8B,SAAS;KAAS,UAAA;IAE1D,CAAA,GACP,oBAAC,aAAD;KACE,IAAI;KACJ,OAAM;KACN,OAAO,OAAO,SAAS;KACvB,UAAU,aAAa,OAAO;KACrB;KACT,gBAAc,WAAW,KAAA;KACf;KACV,aAAY;KACZ,KAAK;KACL,KAAK;IACN,CAAA,CACE;;GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,SAAD;KAAO,WAAU;KAA8B,SAAS;KAAQ,UAAA;IAEzD,CAAA,GACP,oBAAC,aAAD;KACE,IAAI;KACJ,OAAM;KACN,OAAO,OAAO,QAAQ;KACtB,UAAU,aAAa,MAAM;KACpB;KACT,gBAAc,WAAW,KAAA;KACf;KACV,aAAY;KACZ,KAAK;KACL,KAAK;IACN,CAAA,CACE;;EACF;;AAET,CAAC;AAED,eAAe,cAAc"}
1
+ {"version":3,"file":"DateInputGroup2.mjs","names":[],"sources":["../../src/DateInputGroup/DateInputGroup.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames } from '@dsn-starter-kit/core';\nimport { NumberInput } from '../NumberInput';\nimport './DateInputGroup.css';\n\nexport interface DateInputGroupValue {\n day: string;\n month: string;\n year: string;\n}\n\nexport interface DateInputGroupProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'onChange'\n> {\n /**\n * The current value of the date group\n */\n value?: DateInputGroupValue;\n\n /**\n * Called when any field changes, with the full updated value object\n */\n onChange?: (value: DateInputGroupValue) => void;\n\n /**\n * Whether all fields are in an invalid state\n * @default false\n */\n invalid?: boolean;\n\n /**\n * Whether all fields are disabled\n * @default false\n */\n disabled?: boolean;\n\n /**\n * id prefix used to generate unique ids for each field (dag, maand, jaar)\n * E.g. id=\"geboortedatum\" → \"geboortedatum-dag\", \"geboortedatum-maand\", \"geboortedatum-jaar\"\n */\n id?: string;\n}\n\n/**\n * Date Input Group component\n * Three separate inputs for day, month and year.\n * More accessible than a native date picker: works consistently across all browsers and\n * devices, and allows partial input (e.g. year only).\n *\n * Wrap in a FormFieldset for a complete form field with legend and error message.\n *\n * @example\n * ```tsx\n * // Basic usage\n * <DateInputGroup\n * value={{ day: '', month: '', year: '' }}\n * onChange={(val) => setValue(val)}\n * />\n *\n * // Complete form field\n * <FormFieldset>\n * <FormFieldLegend>Geboortedatum</FormFieldLegend>\n * <FormFieldDescription>Bijvoorbeeld: 15 3 1990</FormFieldDescription>\n * <DateInputGroup\n * id=\"geboortedatum\"\n * value={value}\n * onChange={setValue}\n * />\n * </FormFieldset>\n *\n * // Invalid state\n * <DateInputGroup invalid value={value} onChange={setValue} />\n * ```\n */\nexport const DateInputGroup = React.forwardRef<\n HTMLDivElement,\n DateInputGroupProps\n>(({ className, value, onChange, invalid, disabled, id, ...props }, ref) => {\n const classes = classNames('dsn-date-input-group', className);\n\n const handleChange =\n (field: keyof DateInputGroupValue) =>\n (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange?.({\n day: value?.day ?? '',\n month: value?.month ?? '',\n year: value?.year ?? '',\n [field]: e.target.value,\n });\n };\n\n const dayId = id ? `${id}-dag` : undefined;\n const monthId = id ? `${id}-maand` : undefined;\n const yearId = id ? `${id}-jaar` : undefined;\n\n return (\n <div ref={ref} className={classes} {...props}>\n <div className=\"dsn-date-input-group__field\">\n <label className=\"dsn-date-input-group__label\" htmlFor={dayId}>\n Dag\n </label>\n <NumberInput\n id={dayId}\n inlineSize=\"xs\"\n value={value?.day ?? ''}\n onChange={handleChange('day')}\n invalid={invalid}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n placeholder=\"DD\"\n min={1}\n max={31}\n />\n </div>\n <div className=\"dsn-date-input-group__field\">\n <label className=\"dsn-date-input-group__label\" htmlFor={monthId}>\n Maand\n </label>\n <NumberInput\n id={monthId}\n inlineSize=\"xs\"\n value={value?.month ?? ''}\n onChange={handleChange('month')}\n invalid={invalid}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n placeholder=\"MM\"\n min={1}\n max={12}\n />\n </div>\n <div className=\"dsn-date-input-group__field\">\n <label className=\"dsn-date-input-group__label\" htmlFor={yearId}>\n Jaar\n </label>\n <NumberInput\n id={yearId}\n inlineSize=\"sm\"\n value={value?.year ?? ''}\n onChange={handleChange('year')}\n invalid={invalid}\n aria-invalid={invalid || undefined}\n disabled={disabled}\n placeholder=\"JJJJ\"\n min={1}\n max={9999}\n />\n </div>\n </div>\n );\n});\n\nDateInputGroup.displayName = 'DateInputGroup';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2EA,MAAa,iBAAiB,MAAM,YAGjC,EAAE,WAAW,OAAO,UAAU,SAAS,UAAU,IAAI,GAAG,SAAS,QAAQ;CAC1E,MAAM,UAAU,WAAW,wBAAwB,SAAS;CAE5D,MAAM,gBACH,WACA,MAA2C;EAC1C,WAAW;GACT,KAAK,OAAO,OAAO;GACnB,OAAO,OAAO,SAAS;GACvB,MAAM,OAAO,QAAQ;IACpB,QAAQ,EAAE,OAAO;EACpB,CAAC;CACH;CAEF,MAAM,QAAQ,KAAK,GAAG,GAAG,QAAQ,KAAA;CACjC,MAAM,UAAU,KAAK,GAAG,GAAG,UAAU,KAAA;CACrC,MAAM,SAAS,KAAK,GAAG,GAAG,SAAS,KAAA;CAEnC,OACE,qBAAC,OAAD;EAAU;EAAK,WAAW;EAAS,GAAI;EAAvC,UAAA;GACE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,SAAD;KAAO,WAAU;KAA8B,SAAS;KAAO,UAAA;IAExD,CAAA,GACP,oBAAC,aAAD;KACE,IAAI;KACJ,YAAW;KACX,OAAO,OAAO,OAAO;KACrB,UAAU,aAAa,KAAK;KACnB;KACT,gBAAc,WAAW,KAAA;KACf;KACV,aAAY;KACZ,KAAK;KACL,KAAK;IACN,CAAA,CACE;;GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,SAAD;KAAO,WAAU;KAA8B,SAAS;KAAS,UAAA;IAE1D,CAAA,GACP,oBAAC,aAAD;KACE,IAAI;KACJ,YAAW;KACX,OAAO,OAAO,SAAS;KACvB,UAAU,aAAa,OAAO;KACrB;KACT,gBAAc,WAAW,KAAA;KACf;KACV,aAAY;KACZ,KAAK;KACL,KAAK;IACN,CAAA,CACE;;GACL,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,SAAD;KAAO,WAAU;KAA8B,SAAS;KAAQ,UAAA;IAEzD,CAAA,GACP,oBAAC,aAAD;KACE,IAAI;KACJ,YAAW;KACX,OAAO,OAAO,QAAQ;KACtB,UAAU,aAAa,MAAM;KACpB;KACT,gBAAc,WAAW,KAAA;KACf;KACV,aAAY;KACZ,KAAK;KACL,KAAK;IACN,CAAA,CACE;;EACF;;AAET,CAAC;AAED,eAAe,cAAc"}
@@ -1,6 +1,11 @@
1
1
  import React from "react";
2
- import { FormControlWidth } from "@dsn-starter-kit/core";
2
+ import { FormControlInlineSize } from "@dsn-starter-kit/core";
3
3
  //#region src/EmailInput/EmailInput.d.ts
4
+ /**
5
+ * Inline-size variants offered by EmailInput. xs and sm are left out: they
6
+ * are too narrow for the content this field is meant for.
7
+ */
8
+ type EmailInputInlineSize = Exclude<FormControlInlineSize, 'xs' | 'sm'>;
4
9
  interface EmailInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type'> {
5
10
  /**
6
11
  * Whether the input is in an invalid state
@@ -8,10 +13,10 @@ interface EmailInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElemen
8
13
  */
9
14
  invalid?: boolean;
10
15
  /**
11
- * Width variant for the input
12
- * @default undefined (uses default max-width from form-control)
16
+ * Inline-size variant for the input (md, lg, xl or full)
17
+ * @default undefined (uses default max-inline-size from form-control)
13
18
  */
14
- width?: FormControlWidth;
19
+ inlineSize?: EmailInputInlineSize;
15
20
  /**
16
21
  * Additional CSS class names
17
22
  */
@@ -36,5 +41,5 @@ interface EmailInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElemen
36
41
  */
37
42
  declare const EmailInput: React.ForwardRefExoticComponent<EmailInputProps & React.RefAttributes<HTMLInputElement>>;
38
43
  //#endregion
39
- export { EmailInput, EmailInputProps };
44
+ export { EmailInput, EmailInputInlineSize, EmailInputProps };
40
45
  //# sourceMappingURL=EmailInput.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"EmailInput.d.mts","names":[],"sources":["../../src/EmailInput/EmailInput.tsx"],"mappings":";;;UAIiB,wBAAwB,KACvC,MAAM,oBAAoB;;;;;EAO1B;;;;;EAMA,QAAQ;;;;EAKR;;;;;;;;;;;;;;;;;;;cAoBW,YAAU,MAAA,0BAAA,kBAAA,MAAA,cAAA"}
1
+ {"version":3,"file":"EmailInput.d.mts","names":[],"sources":["../../src/EmailInput/EmailInput.tsx"],"mappings":";;;;;;;KAQY,uBAAuB,QAAQ;UAE1B,wBAAwB,KACvC,MAAM,oBAAoB;;;;;EAO1B;;;;;EAMA,aAAa;;;;EAKb;;;;;;;;;;;;;;;;;;;cAoBW,YAAU,MAAA,0BAAA,kBAAA,MAAA,cAAA"}
@@ -20,8 +20,8 @@ import { jsx } from "react/jsx-runtime";
20
20
  * <EmailInput invalid aria-invalid="true" aria-describedby="error" />
21
21
  * ```
22
22
  */
23
- const EmailInput = React.forwardRef(({ className, invalid, width, autoComplete, ...props }, ref) => {
24
- const classes = classNames("dsn-text-input", width && `dsn-text-input--width-${width}`, className);
23
+ const EmailInput = React.forwardRef(({ className, invalid, inlineSize, autoComplete, ...props }, ref) => {
24
+ const classes = classNames("dsn-text-input", inlineSize && `dsn-text-input--inline-size-${inlineSize}`, className);
25
25
  return /* @__PURE__ */ jsx("input", {
26
26
  ref,
27
27
  type: "email",
@@ -1 +1 @@
1
- {"version":3,"file":"EmailInput2.mjs","names":[],"sources":["../../src/EmailInput/EmailInput.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, FormControlWidth } from '@dsn-starter-kit/core';\nimport './EmailInput.css';\n\nexport interface EmailInputProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'type'\n> {\n /**\n * Whether the input is in an invalid state\n * @default false\n */\n invalid?: boolean;\n\n /**\n * Width variant for the input\n * @default undefined (uses default max-width from form-control)\n */\n width?: FormControlWidth;\n\n /**\n * Additional CSS class names\n */\n className?: string;\n}\n\n/**\n * Email Input component\n * Email input with appropriate inputmode and autocomplete\n *\n * @example\n * ```tsx\n * // Basic usage\n * <EmailInput placeholder=\"naam@voorbeeld.nl\" />\n *\n * // With label\n * <FormFieldLabel htmlFor=\"email\">E-mailadres</FormFieldLabel>\n * <EmailInput id=\"email\" />\n *\n * // Invalid state\n * <EmailInput invalid aria-invalid=\"true\" aria-describedby=\"error\" />\n * ```\n */\nexport const EmailInput = React.forwardRef<HTMLInputElement, EmailInputProps>(\n ({ className, invalid, width, autoComplete, ...props }, ref) => {\n const classes = classNames(\n 'dsn-text-input',\n width && `dsn-text-input--width-${width}`,\n className\n );\n\n return (\n <input\n ref={ref}\n type=\"email\"\n inputMode=\"email\"\n className={classes}\n autoComplete={autoComplete || 'email'}\n aria-invalid={invalid || undefined}\n {...props}\n />\n );\n }\n);\n\nEmailInput.displayName = 'EmailInput';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2CA,MAAa,aAAa,MAAM,YAC7B,EAAE,WAAW,SAAS,OAAO,cAAc,GAAG,SAAS,QAAQ;CAC9D,MAAM,UAAU,WACd,kBACA,SAAS,yBAAyB,SAClC,SACF;CAEA,OACE,oBAAC,SAAD;EACO;EACL,MAAK;EACL,WAAU;EACV,WAAW;EACX,cAAc,gBAAgB;EAC9B,gBAAc,WAAW,KAAA;EACzB,GAAI;CACL,CAAA;AAEL,CACF;AAEA,WAAW,cAAc"}
1
+ {"version":3,"file":"EmailInput2.mjs","names":[],"sources":["../../src/EmailInput/EmailInput.tsx"],"sourcesContent":["import React from 'react';\nimport { classNames, FormControlInlineSize } from '@dsn-starter-kit/core';\nimport './EmailInput.css';\n\n/**\n * Inline-size variants offered by EmailInput. xs and sm are left out: they\n * are too narrow for the content this field is meant for.\n */\nexport type EmailInputInlineSize = Exclude<FormControlInlineSize, 'xs' | 'sm'>;\n\nexport interface EmailInputProps extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'type'\n> {\n /**\n * Whether the input is in an invalid state\n * @default false\n */\n invalid?: boolean;\n\n /**\n * Inline-size variant for the input (md, lg, xl or full)\n * @default undefined (uses default max-inline-size from form-control)\n */\n inlineSize?: EmailInputInlineSize;\n\n /**\n * Additional CSS class names\n */\n className?: string;\n}\n\n/**\n * Email Input component\n * Email input with appropriate inputmode and autocomplete\n *\n * @example\n * ```tsx\n * // Basic usage\n * <EmailInput placeholder=\"naam@voorbeeld.nl\" />\n *\n * // With label\n * <FormFieldLabel htmlFor=\"email\">E-mailadres</FormFieldLabel>\n * <EmailInput id=\"email\" />\n *\n * // Invalid state\n * <EmailInput invalid aria-invalid=\"true\" aria-describedby=\"error\" />\n * ```\n */\nexport const EmailInput = React.forwardRef<HTMLInputElement, EmailInputProps>(\n ({ className, invalid, inlineSize, autoComplete, ...props }, ref) => {\n const classes = classNames(\n 'dsn-text-input',\n inlineSize && `dsn-text-input--inline-size-${inlineSize}`,\n className\n );\n\n return (\n <input\n ref={ref}\n type=\"email\"\n inputMode=\"email\"\n className={classes}\n autoComplete={autoComplete || 'email'}\n aria-invalid={invalid || undefined}\n {...props}\n />\n );\n }\n);\n\nEmailInput.displayName = 'EmailInput';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAiDA,MAAa,aAAa,MAAM,YAC7B,EAAE,WAAW,SAAS,YAAY,cAAc,GAAG,SAAS,QAAQ;CACnE,MAAM,UAAU,WACd,kBACA,cAAc,+BAA+B,cAC7C,SACF;CAEA,OACE,oBAAC,SAAD;EACO;EACL,MAAK;EACL,WAAU;EACV,WAAW;EACX,cAAc,gBAAgB;EAC9B,gBAAc,WAAW,KAAA;EACzB,GAAI;CACL,CAAA;AAEL,CACF;AAEA,WAAW,cAAc"}