@developer-overheid-nl/don-register-components 1.0.1 → 1.2.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 (44) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/package.json +11 -8
  3. package/src/alignBox/AlignBox.tsx +6 -2
  4. package/src/alignBox/styles.module.css +4 -0
  5. package/src/amountLabel/AmountLabel.tsx +16 -0
  6. package/src/amountLabel/styles.module.css +11 -0
  7. package/src/analytics/PiwikPro.tsx +94 -0
  8. package/src/analytics/index.ts +1 -0
  9. package/src/badgeList/BadgeList.tsx +26 -0
  10. package/src/badgeList/styles.module.css +24 -0
  11. package/src/client.ts +5 -0
  12. package/src/copyButton/CopyButton.tsx +6 -6
  13. package/src/dataBadgeLink/DataBadgeLink.tsx +3 -0
  14. package/src/dataBadgeLink/styles.module.css +26 -0
  15. package/src/dataSummary/styles.module.css +10 -5
  16. package/src/facetFilters/FacetFilters.tsx +313 -0
  17. package/src/facetFilters/styles.module.css +3 -0
  18. package/src/formFieldCheckboxGroup/FormFieldCheckboxGroup.tsx +16 -0
  19. package/src/formFieldCheckboxGroup/styles.module.css +5 -0
  20. package/src/formFieldCheckboxOption/FormFieldCheckboxOption.tsx +26 -0
  21. package/src/formFieldCheckboxOption/styles.module.css +22 -0
  22. package/src/formFieldRadioGroup/FormFieldRadioGroup.tsx +13 -0
  23. package/src/formFieldRadioGroup/styles.module.css +5 -0
  24. package/src/formFieldRadioOption/FormFieldRadioOption.tsx +75 -0
  25. package/src/formFieldRadioOption/styles.module.css +49 -0
  26. package/src/formFieldSwitch/FormFieldSwitch.tsx +79 -0
  27. package/src/formFieldSwitch/styles.module.css +32 -0
  28. package/src/heading/Heading.tsx +5 -0
  29. package/src/i18n.ts +1 -0
  30. package/src/iconBadge/IconBadge.tsx +3 -0
  31. package/src/iconBadge/getAppearance.ts +7 -1
  32. package/src/index.ts +27 -1
  33. package/src/infoButton/InfoButton.tsx +45 -0
  34. package/src/infoButton/styles.module.css +43 -0
  35. package/src/overlay/Overlay.tsx +18 -0
  36. package/src/overlay/styles.module.css +15 -0
  37. package/src/paragraph/Paragraph.tsx +16 -2
  38. package/src/paragraph/styles.module.css +6 -0
  39. package/src/pillBadge/styles.module.css +20 -0
  40. package/src/scoreBadge/ScoreBadge.tsx +1 -0
  41. package/src/switch/Switch.tsx +86 -0
  42. package/src/switch/styles.module.css +7 -0
  43. package/src/toolTip/ToolTip.tsx +55 -0
  44. package/src/toolTip/styles.module.css +48 -0
@@ -0,0 +1,313 @@
1
+ "use client";
2
+
3
+ import clsx from "clsx";
4
+ import type { ChangeEvent } from "react";
5
+ import { type HTMLProps, type PropsWithChildren, useRef } from "react";
6
+ import { I18nextProvider, useTranslation } from "react-i18next";
7
+ import FormFieldCheckboxGroup from "../formFieldCheckboxGroup/FormFieldCheckboxGroup";
8
+ import FormFieldCheckboxOption from "../formFieldCheckboxOption/FormFieldCheckboxOption";
9
+ import FormFieldRadioGroup from "../formFieldRadioGroup/FormFieldRadioGroup";
10
+ import FormFieldRadioOption from "../formFieldRadioOption/FormFieldRadioOption";
11
+ import FormFieldSwitch from "../formFieldSwitch/FormFieldSwitch";
12
+ import Heading, {
13
+ clampHeadingLevel,
14
+ type HeadingProps,
15
+ } from "../heading/Heading";
16
+ import i18n from "../i18n";
17
+ import Paragraph from "../paragraph/Paragraph";
18
+ import ToolTip from "../toolTip/ToolTip";
19
+ import styles from "./styles.module.css";
20
+
21
+ enum FilterType {
22
+ Toggle = "toggle",
23
+ Date = "date",
24
+ Multi = "multi-select",
25
+ Single = "single-select",
26
+ }
27
+
28
+ export interface SelectOption {
29
+ value: string;
30
+ label: string;
31
+ description?: string | null;
32
+ count: number;
33
+ selected: boolean;
34
+ }
35
+
36
+ interface BaseFilterItems {
37
+ key: string;
38
+ label: string;
39
+ description: string;
40
+ }
41
+
42
+ interface ToggleFilterData extends BaseFilterItems {
43
+ type: FilterType.Toggle;
44
+ value?: boolean;
45
+ count?: number;
46
+ }
47
+
48
+ interface DateFilterData extends BaseFilterItems {
49
+ type: FilterType.Date;
50
+ value?: string;
51
+ count?: number;
52
+ }
53
+
54
+ interface MultiSelectFilterData extends BaseFilterItems {
55
+ type: FilterType.Multi;
56
+ options: SelectOption[];
57
+ }
58
+
59
+ interface SingleSelectFilterData extends BaseFilterItems {
60
+ type: FilterType.Single;
61
+ options: SelectOption[];
62
+ }
63
+
64
+ export type FilterData =
65
+ | ToggleFilterData
66
+ | DateFilterData
67
+ | MultiSelectFilterData
68
+ | SingleSelectFilterData;
69
+
70
+ type SelectedFilters = Record<string, Array<string | [string, string]>>;
71
+
72
+ export interface FacetFiltersProps extends HTMLProps<HTMLDivElement> {
73
+ title?: string;
74
+ startHeadingLevel?: HeadingProps["level"];
75
+ filters: FilterData[] | null | undefined;
76
+ /**
77
+ * Callback function called when filter option has changed.
78
+ * @param selectedFilters current selected filters at the moment of change
79
+ * @returns
80
+ */
81
+ onFilterChange?: (selectedFilters: SelectedFilters) => void;
82
+ /**
83
+ * Types of filters for which the onFilterChange callback should be debounced. Default: ["date", "single-select"]
84
+ */
85
+ debounceTypes?: Array<FilterType>;
86
+ /**
87
+ * Delay for debouncing the onFilterChange callback, in milliseconds. Default: 600
88
+ */
89
+ debounceDelay?: number;
90
+ }
91
+
92
+ export const getSelectedFilters = (
93
+ filters: FilterData[] | null | undefined,
94
+ withLabels = false,
95
+ ): SelectedFilters => {
96
+ return (
97
+ filters?.reduce((acc, filter) => {
98
+ if (filter.type === FilterType.Multi) {
99
+ const keys: (string | [string, string])[] = filter.options
100
+ ?.filter((option) => option.selected)
101
+ .map((option) =>
102
+ withLabels ? [option.value, option.label] : option.value,
103
+ );
104
+ if (keys?.length > 0) {
105
+ acc[filter.key] = keys;
106
+ }
107
+ } else if (filter.type === FilterType.Toggle && filter.value) {
108
+ acc[filter.key] = withLabels ? [["true", filter.label]] : ["true"];
109
+ } else if (filter.type === FilterType.Date && filter.value) {
110
+ acc[filter.key] = withLabels
111
+ ? [[filter.value, filter.label]]
112
+ : [filter.value];
113
+ } else if (filter.type === FilterType.Single) {
114
+ const selectedOption = filter.options?.find(
115
+ (option) => option.selected,
116
+ );
117
+ if (selectedOption) {
118
+ acc[filter.key] = withLabels
119
+ ? [[selectedOption.value, selectedOption.label]]
120
+ : [selectedOption.value];
121
+ }
122
+ }
123
+ return acc;
124
+ }, {} as SelectedFilters) ?? {}
125
+ );
126
+ };
127
+
128
+ const updateFilters = (
129
+ selectedFilters: SelectedFilters,
130
+ filterKey: string,
131
+ filterValue: string,
132
+ checked: boolean,
133
+ ) => {
134
+ const newSelectedFilters = {
135
+ ...selectedFilters,
136
+ [filterKey]: checked
137
+ ? [...(selectedFilters[filterKey] || []), filterValue]
138
+ : (selectedFilters[filterKey] || []).filter(
139
+ (value) => value !== filterValue,
140
+ ),
141
+ };
142
+ return newSelectedFilters;
143
+ };
144
+
145
+ const debounce = <T extends unknown[]>(
146
+ fn: (...args: T) => void,
147
+ delay: number,
148
+ ) => {
149
+ let timeoutId: ReturnType<typeof setTimeout> | null = null;
150
+ return (...args: T) => {
151
+ if (timeoutId) {
152
+ clearTimeout(timeoutId);
153
+ }
154
+ timeoutId = setTimeout(() => {
155
+ fn(...args);
156
+ }, delay);
157
+ };
158
+ };
159
+
160
+ const FacetFilters = (props: PropsWithChildren<FacetFiltersProps>) => {
161
+ const { t } = useTranslation();
162
+ const thisRef = useRef<HTMLDivElement>(null);
163
+ const {
164
+ title,
165
+ startHeadingLevel = 2,
166
+ filters,
167
+ onFilterChange = () => {},
168
+ debounceTypes = [FilterType.Date, FilterType.Single],
169
+ debounceDelay = 600,
170
+ ...restProps
171
+ } = props;
172
+
173
+ const selectedFilters = getSelectedFilters(filters);
174
+
175
+ // Callback function (for React) and CustomEvent (for non-React) to notify about filter changes
176
+ const emitChange = (newSelectedFilters: SelectedFilters) => {
177
+ onFilterChange(newSelectedFilters);
178
+ const customEvent = new CustomEvent("onFilterChange", {
179
+ detail: newSelectedFilters,
180
+ });
181
+ if (thisRef.current) thisRef.current.dispatchEvent(customEvent);
182
+ };
183
+
184
+ const debouncedEmitChange = useRef(
185
+ debounce(emitChange, debounceDelay),
186
+ ).current;
187
+
188
+ const handleChange = (
189
+ event: ChangeEvent<HTMLInputElement>,
190
+ type: FilterType,
191
+ ) => {
192
+ const newSelectedFilters = updateFilters(
193
+ selectedFilters,
194
+ event.target.name,
195
+ event.target.value,
196
+ event.target.checked,
197
+ );
198
+
199
+ if (debounceTypes.includes(type)) {
200
+ debouncedEmitChange(newSelectedFilters);
201
+ } else {
202
+ emitChange(newSelectedFilters);
203
+ }
204
+ };
205
+
206
+ return (
207
+ <div
208
+ ref={thisRef}
209
+ className={clsx([styles.facetFilters, props.className])}
210
+ {...restProps}
211
+ >
212
+ {title ? (
213
+ <Heading level={startHeadingLevel} appearanceLevel={3}>
214
+ {title}
215
+ </Heading>
216
+ ) : null}
217
+ {/* Temporary filter on `date` types */}
218
+ {filters
219
+ ?.filter(({ type }) => type !== "date")
220
+ .map((facet) => (
221
+ <div className={styles.facet} key={facet.key}>
222
+ <Heading
223
+ level={
224
+ title
225
+ ? clampHeadingLevel(startHeadingLevel + 1)
226
+ : startHeadingLevel
227
+ }
228
+ appearanceLevel={5}
229
+ >
230
+ {facet.label}
231
+ </Heading>
232
+ <Paragraph id={`${facet.key}-label`} purpose="short">
233
+ {facet.description}
234
+ </Paragraph>
235
+ {facet.type === "toggle" ? (
236
+ <FormFieldSwitch
237
+ label=""
238
+ labelledById={`${facet.key}-label`}
239
+ name={facet.key}
240
+ defaultChecked={facet.value}
241
+ value="true"
242
+ amount={facet.count || 0}
243
+ labels={{
244
+ on: t("components.filter-on"),
245
+ off: t("components.filter-off"),
246
+ }}
247
+ onChange={(event) => handleChange(event, facet.type)}
248
+ />
249
+ ) : null}
250
+ {/* TODO: Date selector
251
+ {facet.type === "date" ? <div>TODO</div> : null}
252
+ */}
253
+ {facet.type === "multi-select" ? (
254
+ <FormFieldCheckboxGroup>
255
+ {facet.options?.map((option) => (
256
+ <FormFieldCheckboxOption
257
+ key={option.value}
258
+ label={option.label}
259
+ name={facet.key}
260
+ value={option.value}
261
+ defaultChecked={option.selected}
262
+ amount={option.count}
263
+ onChange={(event) => handleChange(event, facet.type)}
264
+ >
265
+ {option.description ? (
266
+ <ToolTip
267
+ text={option.description}
268
+ aria-label={t("components.info-about", {
269
+ subject: option.label,
270
+ })}
271
+ />
272
+ ) : null}
273
+ </FormFieldCheckboxOption>
274
+ ))}
275
+ </FormFieldCheckboxGroup>
276
+ ) : null}
277
+ {facet.type === "single-select" ? (
278
+ <FormFieldRadioGroup>
279
+ <FormFieldRadioOption
280
+ key="none"
281
+ label={t("components.filter-all")}
282
+ name={facet.key}
283
+ value=""
284
+ onChange={(event) => handleChange(event, facet.type)}
285
+ />
286
+ {facet.options?.map((option) => (
287
+ <FormFieldRadioOption
288
+ key={option.value}
289
+ label={option.label}
290
+ name={facet.key}
291
+ value={option.value}
292
+ defaultChecked={option.selected}
293
+ amount={option.count}
294
+ onChange={(event) => handleChange(event, facet.type)}
295
+ />
296
+ ))}
297
+ </FormFieldRadioGroup>
298
+ ) : null}
299
+ </div>
300
+ ))}
301
+ </div>
302
+ );
303
+ };
304
+
305
+ const TranslatedFacetFilters = (props: FacetFiltersProps) => {
306
+ return (
307
+ <I18nextProvider i18n={i18n}>
308
+ <FacetFilters {...props} />
309
+ </I18nextProvider>
310
+ );
311
+ };
312
+
313
+ export default TranslatedFacetFilters;
@@ -0,0 +1,3 @@
1
+ .facet {
2
+ margin-block-end: 0.5rem;
3
+ }
@@ -0,0 +1,16 @@
1
+ import {
2
+ type FormFieldCheckboxGroupProps,
3
+ FormFieldCheckboxGroup as RHCFormFieldCheckboxGroup,
4
+ } from "@rijkshuisstijl-community/components-react";
5
+ import styles from "./styles.module.css";
6
+
7
+ const FormFieldCheckboxGroup = (props: FormFieldCheckboxGroupProps) => {
8
+ return (
9
+ <RHCFormFieldCheckboxGroup
10
+ className={styles.formFieldCheckboxGroup}
11
+ {...props}
12
+ />
13
+ );
14
+ };
15
+
16
+ export default FormFieldCheckboxGroup;
@@ -0,0 +1,5 @@
1
+ .formFieldCheckboxGroup {
2
+ :global(& > .utrecht-form-field__label) {
3
+ display: none;
4
+ }
5
+ }
@@ -0,0 +1,26 @@
1
+ import {
2
+ FormFieldCheckboxOption as RHCFormFieldCheckboxOption,
3
+ type FormFieldCheckboxOptionProps as RHCFormFieldCheckboxOptionProps,
4
+ } from "@rijkshuisstijl-community/components-react";
5
+ import clsx from "clsx";
6
+ import AmountLabel, { type AmountLabelProps } from "../amountLabel/AmountLabel";
7
+ import styles from "./styles.module.css";
8
+
9
+ export interface FormFieldCheckboxOptionProps
10
+ extends Omit<RHCFormFieldCheckboxOptionProps, "label">,
11
+ AmountLabelProps {}
12
+
13
+ const FormFieldCheckboxOption = (props: FormFieldCheckboxOptionProps) => {
14
+ const { amount, label, className, children, ...restProps } = props;
15
+ return (
16
+ <RHCFormFieldCheckboxOption
17
+ className={clsx(styles.checkbox, className)}
18
+ label={<AmountLabel label={label} amount={amount} />}
19
+ {...restProps}
20
+ >
21
+ <span className={styles.info}>{children}</span>
22
+ </RHCFormFieldCheckboxOption>
23
+ );
24
+ };
25
+
26
+ export default FormFieldCheckboxOption;
@@ -0,0 +1,22 @@
1
+ .checkbox.checkbox {
2
+ --utrecht-form-field-label-margin-block-end: 0;
3
+
4
+ grid-template-areas:
5
+ 'input label info'
6
+ 'input description description'
7
+ 'input error-message error-message'
8
+ 'input status status';
9
+
10
+ :global(.utrecht-form-label) {
11
+ display: flex;
12
+ }
13
+
14
+ :global(.utrecht-checkbox) {
15
+ order: initial;
16
+ margin-block-start: 0;
17
+ }
18
+ }
19
+
20
+ .info {
21
+ grid-area: info;
22
+ }
@@ -0,0 +1,13 @@
1
+ import {
2
+ type FormFieldRadioGroupProps,
3
+ FormFieldRadioGroup as RHCFormFieldRadioGroup,
4
+ } from "@rijkshuisstijl-community/components-react";
5
+ import styles from "./styles.module.css";
6
+
7
+ const FormFieldRadioGroup = (props: FormFieldRadioGroupProps) => {
8
+ return (
9
+ <RHCFormFieldRadioGroup className={styles.formFieldRadioGroup} {...props} />
10
+ );
11
+ };
12
+
13
+ export default FormFieldRadioGroup;
@@ -0,0 +1,5 @@
1
+ .formFieldRadioGroup {
2
+ :global(& > .utrecht-form-field__label) {
3
+ display: none;
4
+ }
5
+ }
@@ -0,0 +1,75 @@
1
+ import {
2
+ type CustomFormFieldProps,
3
+ FormField,
4
+ Radio as RHCRadio,
5
+ } from "@rijkshuisstijl-community/components-react";
6
+ import clsx from "clsx";
7
+ import { Fragment, useId } from "react";
8
+ import AmountLabel, { type AmountLabelProps } from "../amountLabel/AmountLabel";
9
+ import styles from "./styles.module.css";
10
+
11
+ export interface FormFieldRadioOptionProps
12
+ extends Omit<
13
+ CustomFormFieldProps,
14
+ "label" | "statusId" | "errorMessageId" | "descriptionId" | "input"
15
+ >,
16
+ AmountLabelProps {
17
+ name: string;
18
+ value: string;
19
+ checked?: boolean;
20
+ defaultChecked?: boolean;
21
+ statusId?: CustomFormFieldProps["statusId"];
22
+ errorMessageId?: CustomFormFieldProps["errorMessageId"];
23
+ descriptionId?: CustomFormFieldProps["descriptionId"];
24
+ onChange?: React.ChangeEventHandler<HTMLInputElement>;
25
+ }
26
+
27
+ const FormFieldRadioOption = (props: FormFieldRadioOptionProps) => {
28
+ const genId = useId();
29
+ const {
30
+ id = genId,
31
+ statusId = genId,
32
+ errorMessageId = genId,
33
+ descriptionId = genId,
34
+ name,
35
+ value,
36
+ defaultChecked,
37
+ checked,
38
+ amount,
39
+ label,
40
+ className,
41
+ children,
42
+ onChange,
43
+ ...restProps
44
+ } = props;
45
+
46
+ return (
47
+ <FormField
48
+ type="radio" // although not exposed by RHC
49
+ className={clsx("utrecht-form-field--radio", styles.radio, className)}
50
+ statusId={statusId}
51
+ errorMessageId={errorMessageId}
52
+ descriptionId={descriptionId}
53
+ label={
54
+ <Fragment>
55
+ <RHCRadio
56
+ id={id}
57
+ name={name}
58
+ value={value}
59
+ checked={checked}
60
+ defaultChecked={defaultChecked}
61
+ className="utrecht-checkbox--custom utrecht-form-field__input"
62
+ onChange={onChange}
63
+ />
64
+ <AmountLabel label={label} amount={amount} />
65
+ </Fragment>
66
+ }
67
+ input={null}
68
+ {...restProps}
69
+ >
70
+ <span className={styles.info}>{children}</span>
71
+ </FormField>
72
+ );
73
+ };
74
+
75
+ export default FormFieldRadioOption;
@@ -0,0 +1,49 @@
1
+ .radio.radio {
2
+ --utrecht-form-field-label-margin-block-end: 0;
3
+
4
+ grid-template-areas:
5
+ 'input label info'
6
+ 'input description description'
7
+ 'input error-message error-message'
8
+ 'input status status';
9
+
10
+ :global(.utrecht-form-field--radio .utrecht-form-field__label) {
11
+ display: block;
12
+ }
13
+
14
+ :global(.utrecht-form-label) {
15
+ /* like checkbox */
16
+ display: flex;
17
+ font-weight: var(
18
+ --utrecht-form-label-checkbox-font-weight,
19
+ var(--utrecht-form-label-font-weight)
20
+ );
21
+ color: var(
22
+ --utrecht-form-label-checkbox-color,
23
+ var(--utrecht-form-label-color)
24
+ );
25
+ cursor: var(--utrecht-action-activate-cursor, revert);
26
+ }
27
+
28
+ :global(.utrecht-radio-button) {
29
+ order: initial;
30
+ margin-block-start: 0;
31
+ }
32
+
33
+ :global(
34
+ .utrecht-form-field--radio
35
+ .utrecht-form-field__label:has(.utrecht-form-field__input)
36
+ ) {
37
+ margin-inline-start: calc(
38
+ -1 *
39
+ (
40
+ var(--utrecht-radio-button-size) +
41
+ var(--utrecht-checkbox-margin-inline-end, 12px)
42
+ )
43
+ );
44
+ }
45
+ }
46
+
47
+ .info {
48
+ grid-area: info;
49
+ }
@@ -0,0 +1,79 @@
1
+ import {
2
+ type CustomFormFieldProps,
3
+ FormField,
4
+ } from "@rijkshuisstijl-community/components-react";
5
+ import clsx from "clsx";
6
+ import { useId } from "react";
7
+ import AmountLabel, { type AmountLabelProps } from "../amountLabel/AmountLabel";
8
+ import Switch, { type SwitchLabels } from "../switch/Switch";
9
+ import styles from "./styles.module.css";
10
+
11
+ export interface FormFieldSwitchProps
12
+ extends Omit<
13
+ CustomFormFieldProps,
14
+ "label" | "statusId" | "errorMessageId" | "descriptionId" | "input"
15
+ >,
16
+ AmountLabelProps {
17
+ name: string;
18
+ value: string;
19
+ checked?: boolean;
20
+ defaultChecked?: boolean;
21
+ statusId?: CustomFormFieldProps["statusId"];
22
+ errorMessageId?: CustomFormFieldProps["errorMessageId"];
23
+ descriptionId?: CustomFormFieldProps["descriptionId"];
24
+ labelledById?: string;
25
+ labels?: SwitchLabels;
26
+ onChange?: React.ChangeEventHandler<HTMLInputElement>;
27
+ }
28
+
29
+ const FormFieldSwitch = (props: FormFieldSwitchProps) => {
30
+ const genId = useId();
31
+ const {
32
+ id = genId,
33
+ statusId = genId,
34
+ errorMessageId = genId,
35
+ descriptionId = genId,
36
+ labelledById,
37
+ name,
38
+ value,
39
+ defaultChecked,
40
+ checked,
41
+ amount,
42
+ label,
43
+ labels,
44
+ onChange,
45
+ className,
46
+ children,
47
+ ...restProps
48
+ } = props;
49
+
50
+ return (
51
+ <FormField
52
+ id={id}
53
+ type="checkbox"
54
+ className={clsx("utrecht-form-field--checkbox", styles.switch, className)}
55
+ statusId={statusId}
56
+ errorMessageId={errorMessageId}
57
+ descriptionId={descriptionId}
58
+ label={<AmountLabel label={label} amount={amount} />}
59
+ input={
60
+ <Switch
61
+ id={id}
62
+ name={name}
63
+ value={value}
64
+ checked={checked}
65
+ defaultChecked={defaultChecked}
66
+ className="utrecht-form-field__input"
67
+ labels={labels}
68
+ aria-labelledby={`${labelledById} ${id}`}
69
+ onChange={onChange}
70
+ />
71
+ }
72
+ {...restProps}
73
+ >
74
+ <span className={styles.info}>{children}</span>
75
+ </FormField>
76
+ );
77
+ };
78
+
79
+ export default FormFieldSwitch;
@@ -0,0 +1,32 @@
1
+ .switch.switch {
2
+ --utrecht-form-field-label-margin-block-end: 0;
3
+ --utrecht-checkbox-size: var(--utrecht-form-toggle-width);
4
+
5
+ grid-template-areas:
6
+ 'input label info'
7
+ 'input description description'
8
+ 'input error-message error-message'
9
+ 'input status status';
10
+
11
+ :global(.utrecht-form-field--radio .utrecht-form-field__label) {
12
+ display: block;
13
+ }
14
+
15
+ :global(.utrecht-form-label) {
16
+ /* like checkbox */
17
+ display: flex;
18
+ font-weight: var(
19
+ --utrecht-form-label-checkbox-font-weight,
20
+ var(--utrecht-form-label-font-weight)
21
+ );
22
+ color: var(
23
+ --utrecht-form-label-checkbox-color,
24
+ var(--utrecht-form-label-color)
25
+ );
26
+ cursor: var(--utrecht-action-activate-cursor, revert);
27
+ }
28
+ }
29
+
30
+ .info {
31
+ grid-area: info;
32
+ }
@@ -3,6 +3,11 @@ import {
3
3
  Heading as RHCHeading,
4
4
  } from "@rijkshuisstijl-community/components-react";
5
5
 
6
+ export type { HeadingProps } from "@rijkshuisstijl-community/components-react";
7
+
8
+ export const clampHeadingLevel = (headingLevel: number) =>
9
+ Math.max(1, Math.min(headingLevel + 1, 5)) as HeadingProps["level"];
10
+
6
11
  const Heading = (props: HeadingProps) => {
7
12
  return <RHCHeading {...props} />;
8
13
  };
package/src/i18n.ts CHANGED
@@ -7,6 +7,7 @@ const i18nInstance: i18n = createInstance({
7
7
  lng: "nl",
8
8
  fallbackLng: "nl",
9
9
  // debug: true,
10
+ showSupportNotice: false,
10
11
 
11
12
  interpolation: {
12
13
  escapeValue: false, // not needed for react as it escapes by default
@@ -8,6 +8,9 @@ export interface IconBadgeProps extends HTMLProps<HTMLSpanElement> {
8
8
  appearance?: string;
9
9
  }
10
10
 
11
+ /**
12
+ * @deprecated API Register specific component (and not used anymore)
13
+ */
11
14
  export default function IconBadge(props: IconBadgeProps) {
12
15
  const { className, name, appearance, ...restProps } = props;
13
16
  const iconClassName = `don-icon don-icon-${name} ${className || ""}`.trim();