@dsn-starter-kit/components-react 3.5.0 → 4.1.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.
- package/dist/Card/Card.d.mts +86 -21
- package/dist/Card/Card.d.mts.map +1 -1
- package/dist/Card/Card2.mjs +100 -17
- package/dist/Card/Card2.mjs.map +1 -1
- package/dist/Card/index.d.mts +2 -2
- package/dist/DateInput/DateInput.d.mts +1 -1
- package/dist/DateInput/DateInput2.mjs +1 -1
- package/dist/DateInput/DateInput2.mjs.map +1 -1
- package/dist/DateInputGroup/DateInputGroup2.mjs +3 -3
- package/dist/DateInputGroup/DateInputGroup2.mjs.map +1 -1
- package/dist/Drawer/Drawer.d.mts +5 -2
- package/dist/Drawer/Drawer.d.mts.map +1 -1
- package/dist/Drawer/Drawer2.mjs +18 -3
- package/dist/Drawer/Drawer2.mjs.map +1 -1
- package/dist/EmailInput/EmailInput.d.mts +10 -5
- package/dist/EmailInput/EmailInput.d.mts.map +1 -1
- package/dist/EmailInput/EmailInput2.mjs +2 -2
- package/dist/EmailInput/EmailInput2.mjs.map +1 -1
- package/dist/ModalDialog/ModalDialog.d.mts +13 -3
- package/dist/ModalDialog/ModalDialog.d.mts.map +1 -1
- package/dist/ModalDialog/ModalDialog2.mjs +10 -3
- package/dist/ModalDialog/ModalDialog2.mjs.map +1 -1
- package/dist/NumberInput/NumberInput.d.mts +4 -4
- package/dist/NumberInput/NumberInput.d.mts.map +1 -1
- package/dist/NumberInput/NumberInput2.mjs +2 -2
- package/dist/NumberInput/NumberInput2.mjs.map +1 -1
- package/dist/PageHeader/PageHeader.d.mts.map +1 -1
- package/dist/PageHeader/PageHeader2.mjs +19 -2
- package/dist/PageHeader/PageHeader2.mjs.map +1 -1
- package/dist/PasswordInput/PasswordInput.d.mts +10 -5
- package/dist/PasswordInput/PasswordInput.d.mts.map +1 -1
- package/dist/PasswordInput/PasswordInput2.mjs +2 -2
- package/dist/PasswordInput/PasswordInput2.mjs.map +1 -1
- package/dist/Popover/Popover.d.mts +16 -23
- package/dist/Popover/Popover.d.mts.map +1 -1
- package/dist/Popover/Popover2.mjs +33 -119
- package/dist/Popover/Popover2.mjs.map +1 -1
- package/dist/PopoverMenu/PopoverMenu.d.mts +62 -0
- package/dist/PopoverMenu/PopoverMenu.d.mts.map +1 -0
- package/dist/PopoverMenu/PopoverMenu2.mjs +66 -0
- package/dist/PopoverMenu/PopoverMenu2.mjs.map +1 -0
- package/dist/PopoverMenu/index.d.mts +2 -0
- package/dist/SearchInput/SearchInput.d.mts +10 -5
- package/dist/SearchInput/SearchInput.d.mts.map +1 -1
- package/dist/SearchInput/SearchInput2.mjs +2 -2
- package/dist/SearchInput/SearchInput2.mjs.map +1 -1
- package/dist/Select/Select.d.mts +6 -6
- package/dist/Select/Select.d.mts.map +1 -1
- package/dist/Select/Select2.mjs +4 -4
- package/dist/Select/Select2.mjs.map +1 -1
- package/dist/TelephoneInput/TelephoneInput.d.mts +10 -5
- package/dist/TelephoneInput/TelephoneInput.d.mts.map +1 -1
- package/dist/TelephoneInput/TelephoneInput2.mjs +2 -2
- package/dist/TelephoneInput/TelephoneInput2.mjs.map +1 -1
- package/dist/TextArea/TextArea.d.mts +10 -5
- package/dist/TextArea/TextArea.d.mts.map +1 -1
- package/dist/TextArea/TextArea2.mjs +2 -2
- package/dist/TextArea/TextArea2.mjs.map +1 -1
- package/dist/TextInput/TextInput.d.mts +4 -4
- package/dist/TextInput/TextInput.d.mts.map +1 -1
- package/dist/TextInput/TextInput2.mjs +2 -2
- package/dist/TextInput/TextInput2.mjs.map +1 -1
- package/dist/TimeInput/TimeInput.d.mts +1 -1
- package/dist/TimeInput/TimeInput2.mjs +1 -1
- package/dist/TimeInput/TimeInput2.mjs.map +1 -1
- package/dist/index.cjs +315 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +5950 -5217
- package/dist/index.d.cts +243 -66
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +4 -2
- package/dist/index.mjs +3 -2
- package/dist/utils/popover.d.mts +27 -0
- package/dist/utils/popover.d.mts.map +1 -0
- package/dist/utils/popover.mjs +142 -0
- package/dist/utils/popover.mjs.map +1 -0
- package/package.json +3 -3
package/dist/Card/Card.d.mts
CHANGED
|
@@ -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.
|
|
6
|
-
* via React context en
|
|
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
|
-
/**
|
|
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
|
|
16
|
-
*
|
|
17
|
-
*
|
|
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
|
-
* <
|
|
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
|
-
* <
|
|
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
|
|
43
|
+
interface CardPreHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
37
44
|
/**
|
|
38
|
-
* Afbeelding
|
|
39
|
-
*
|
|
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
|
-
*
|
|
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
|
-
/** `
|
|
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
|
-
*
|
|
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,
|
|
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`
|
|
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
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* bestemming
|
|
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
|
package/dist/Card/Card.d.mts.map
CHANGED
|
@@ -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
|
|
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"}
|
package/dist/Card/Card2.mjs
CHANGED
|
@@ -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
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
-
* <
|
|
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
|
-
* <
|
|
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
|
-
*
|
|
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
|
|
53
|
+
const CardPreHeader = React.forwardRef(({ className, children, ...props }, ref) => {
|
|
46
54
|
return /* @__PURE__ */ jsx("div", {
|
|
47
55
|
ref,
|
|
48
|
-
className: classNames("dsn-
|
|
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
|
-
*
|
|
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,
|
|
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-
|
|
103
|
+
className: classNames("dsn-card__heading", className),
|
|
82
104
|
...props,
|
|
83
105
|
children: href ? /* @__PURE__ */ jsx("a", {
|
|
84
106
|
href,
|
|
85
|
-
className: "dsn-
|
|
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
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* bestemming
|
|
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
|
package/dist/Card/Card2.mjs.map
CHANGED
|
@@ -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"}
|
package/dist/Card/index.d.mts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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"}
|
package/dist/Drawer/Drawer.d.mts
CHANGED
|
@@ -14,8 +14,11 @@ interface DrawerProps extends Omit<React.HTMLAttributes<HTMLDialogElement>, 'chi
|
|
|
14
14
|
* Modaal of non-modaal gedrag.
|
|
15
15
|
* - `true` (standaard): opent via `.showModal()` — achtergrond geblokkeerd,
|
|
16
16
|
* focus blijft binnen het paneel, Escape sluit via `cancel`-event.
|
|
17
|
-
* - `false`: opent via `.
|
|
18
|
-
* gebruiker kan er met Tab naartoe,
|
|
17
|
+
* - `false`: `<dialog popover="manual">`, opent via `.showPopover()` —
|
|
18
|
+
* achtergrond blijft interactief en de gebruiker kan er met Tab naartoe,
|
|
19
|
+
* Escape sluit via `keydown`-listener. Het paneel staat in de top layer,
|
|
20
|
+
* dus een sticky header of een voorouder met `transform` valt er niet
|
|
21
|
+
* overheen.
|
|
19
22
|
* @default true
|
|
20
23
|
*/
|
|
21
24
|
modal?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Drawer.d.mts","names":[],"sources":["../../src/Drawer/Drawer.tsx"],"mappings":";;UA0BiB,oBAAoB,KACnC,MAAM,eAAe;;;;EAMrB;;;;;EAMA
|
|
1
|
+
{"version":3,"file":"Drawer.d.mts","names":[],"sources":["../../src/Drawer/Drawer.tsx"],"mappings":";;UA0BiB,oBAAoB,KACnC,MAAM,eAAe;;;;EAMrB;;;;;EAMA;;;;;;;;;;;;EAaA;;;;;;;EAQA,aAAa,MAAM,UAAU;;;;;EAM7B;;;;;EAMA,WAAW,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA6BN,QAAM,MAAA,0BAAA,cAAA,MAAA,cAAA;UA4JF,0BAA0B,MAAM,eAAe;;;;EAI9D,WAAW,MAAM;;;;;;cAON,cAAY,MAAA,0BAAA,oBAAA,MAAA,cAAA;UA+BR,2BAA2B,MAAM,eAAe;;;;;EAK/D;;;;EAKA,WAAW,MAAM;;;;;;;cAQN,eAAa,MAAA,0BAAA,qBAAA,MAAA,cAAA;UAyCT,wBAAwB,MAAM,eAAe;;;;EAI5D,WAAW,MAAM;;;;;;cAON,YAAU,MAAA,0BAAA,kBAAA,MAAA,cAAA;UAoBN,0BAA0B,MAAM,eAAe;;;;EAI9D,WAAW,MAAM;;;;;;cAON,cAAY,MAAA,0BAAA,oBAAA,MAAA,cAAA"}
|
package/dist/Drawer/Drawer2.mjs
CHANGED
|
@@ -41,14 +41,28 @@ const Drawer = React.forwardRef(({ className, isOpen, onClose, modal = true, tri
|
|
|
41
41
|
const dialogRef = ref ?? internalRef;
|
|
42
42
|
const headingId = React.useId();
|
|
43
43
|
const headingRef = React.useRef(null);
|
|
44
|
+
const popoverShownRef = React.useRef(false);
|
|
45
|
+
const previousFocusRef = React.useRef(null);
|
|
44
46
|
React.useEffect(() => {
|
|
45
47
|
const dialog = dialogRef.current;
|
|
46
48
|
if (!dialog) return;
|
|
47
|
-
|
|
49
|
+
const isShown = dialog.open || popoverShownRef.current;
|
|
50
|
+
if (isOpen && !isShown) {
|
|
48
51
|
if (modal) dialog.showModal();
|
|
49
|
-
else
|
|
52
|
+
else {
|
|
53
|
+
previousFocusRef.current = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
54
|
+
dialog.showPopover();
|
|
55
|
+
popoverShownRef.current = true;
|
|
56
|
+
}
|
|
50
57
|
(headingRef.current ?? dialog).focus();
|
|
51
|
-
} else if (!isOpen &&
|
|
58
|
+
} else if (!isOpen && isShown) {
|
|
59
|
+
if (popoverShownRef.current) {
|
|
60
|
+
const focusWasInside = dialog.contains(document.activeElement);
|
|
61
|
+
dialog.hidePopover();
|
|
62
|
+
popoverShownRef.current = false;
|
|
63
|
+
if (focusWasInside) previousFocusRef.current?.focus();
|
|
64
|
+
} else dialog.close();
|
|
65
|
+
}
|
|
52
66
|
}, [
|
|
53
67
|
isOpen,
|
|
54
68
|
modal,
|
|
@@ -95,6 +109,7 @@ const Drawer = React.forwardRef(({ className, isOpen, onClose, modal = true, tri
|
|
|
95
109
|
"aria-labelledby": headingId,
|
|
96
110
|
onCancel: handleCancel,
|
|
97
111
|
tabIndex: -1,
|
|
112
|
+
popover: modal ? void 0 : "manual",
|
|
98
113
|
...props,
|
|
99
114
|
children
|
|
100
115
|
})
|