@developer-overheid-nl/don-register-components 1.1.0 → 1.3.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 (89) hide show
  1. package/CHANGELOG.md +118 -43
  2. package/LICENSE.md +291 -291
  3. package/README.md +20 -20
  4. package/package.json +3 -3
  5. package/src/alert/Alert.tsx +19 -19
  6. package/src/alert/styles.module.css +3 -3
  7. package/src/alignBox/AlignBox.tsx +114 -111
  8. package/src/alignBox/styles.module.css +110 -106
  9. package/src/amountLabel/AmountLabel.tsx +16 -0
  10. package/src/amountLabel/styles.module.css +11 -0
  11. package/src/analytics/PiwikPro.tsx +94 -72
  12. package/src/analytics/index.ts +1 -1
  13. package/src/article/Article.tsx +10 -10
  14. package/src/badgeList/BadgeList.tsx +34 -0
  15. package/src/badgeList/styles.module.css +37 -0
  16. package/src/block/Block.tsx +35 -35
  17. package/src/block/styles.module.css +29 -29
  18. package/src/button/Button.tsx +3 -3
  19. package/src/cardAsLink/CardAsLink.tsx +21 -21
  20. package/src/cardAsLink/styles.module.css +23 -23
  21. package/src/cardsList/CardsList.tsx +54 -54
  22. package/src/cardsList/styles.module.css +19 -19
  23. package/src/client.ts +7 -2
  24. package/src/container/Container.tsx +10 -10
  25. package/src/container/styles.module.css +28 -28
  26. package/src/copyButton/CopyButton.tsx +39 -39
  27. package/src/copyButton/styles.module.css +13 -13
  28. package/src/dataBadgeLink/DataBadgeLink.tsx +53 -50
  29. package/src/dataBadgeLink/styles.module.css +89 -43
  30. package/src/dataSummary/DataSummary.tsx +22 -22
  31. package/src/dataSummary/DataSummaryItem.tsx +21 -21
  32. package/src/dataSummary/styles.module.css +75 -70
  33. package/src/facetFilters/FacetFilters.tsx +367 -0
  34. package/src/facetFilters/styles.module.css +3 -0
  35. package/src/fieldset/FieldSet.tsx +3 -3
  36. package/src/filters/Filters.tsx +116 -115
  37. package/src/filters/styles.module.css +26 -26
  38. package/src/footer/Footer.tsx +76 -76
  39. package/src/footer/styles.module.css +103 -103
  40. package/src/formFieldCheckboxGroup/FormFieldCheckboxGroup.tsx +16 -0
  41. package/src/formFieldCheckboxGroup/styles.module.css +5 -0
  42. package/src/formFieldCheckboxOption/FormFieldCheckboxOption.tsx +26 -0
  43. package/src/formFieldCheckboxOption/styles.module.css +22 -0
  44. package/src/formFieldLabel/FormFieldLabel.tsx +23 -23
  45. package/src/formFieldRadioGroup/FormFieldRadioGroup.tsx +13 -0
  46. package/src/formFieldRadioGroup/styles.module.css +5 -0
  47. package/src/formFieldRadioOption/FormFieldRadioOption.tsx +75 -0
  48. package/src/formFieldRadioOption/styles.module.css +49 -0
  49. package/src/formFieldSwitch/FormFieldSwitch.tsx +79 -0
  50. package/src/formFieldSwitch/styles.module.css +32 -0
  51. package/src/formFieldTextInput/FormFieldTextInput.tsx +3 -3
  52. package/src/header/Header.tsx +137 -137
  53. package/src/header/styles.module.css +71 -71
  54. package/src/heading/Heading.tsx +15 -10
  55. package/src/headingGroup/HeadingGroup.tsx +48 -48
  56. package/src/headingGroup/styles.module.css +3 -3
  57. package/src/i18n.ts +25 -25
  58. package/src/iconBadge/IconBadge.tsx +35 -32
  59. package/src/iconBadge/getAppearance.ts +53 -47
  60. package/src/iconBadge/styles.module.css +19 -19
  61. package/src/iconsSprite/Icon.tsx +17 -17
  62. package/src/iconsSprite/IconsSprite.tsx +5 -5
  63. package/src/index.ts +107 -80
  64. package/src/infoButton/InfoButton.tsx +45 -0
  65. package/src/infoButton/styles.module.css +43 -0
  66. package/src/link/Link.tsx +10 -10
  67. package/src/markdown/Markdown.tsx +42 -42
  68. package/src/overlay/Overlay.tsx +18 -0
  69. package/src/overlay/styles.module.css +15 -0
  70. package/src/pagination/Pagination.tsx +267 -144
  71. package/src/pagination/styles.module.css +28 -13
  72. package/src/paragraph/Paragraph.tsx +24 -10
  73. package/src/paragraph/styles.module.css +6 -0
  74. package/src/pillBadge/PillBadge.examples.tsx +107 -107
  75. package/src/pillBadge/PillBadge.tsx +51 -51
  76. package/src/pillBadge/styles.module.css +214 -194
  77. package/src/readOnlyTextInput/ReadOnlyTextInput.tsx +24 -24
  78. package/src/readOnlyTextInput/styles.module.css +19 -19
  79. package/src/scoreBadge/ScoreBadge.tsx +133 -132
  80. package/src/search/Search.tsx +82 -66
  81. package/src/search/styles.module.css +39 -39
  82. package/src/siteLogo/SiteLogo.tsx +24 -24
  83. package/src/switch/Switch.tsx +86 -0
  84. package/src/switch/styles.module.css +7 -0
  85. package/src/toolTip/ToolTip.tsx +55 -0
  86. package/src/toolTip/styles.module.css +49 -0
  87. package/src/topNavigation/TopNavigation.tsx +67 -67
  88. package/src/topNavigation/styles.module.css +54 -54
  89. package/tsconfig.json +121 -121
@@ -1,132 +1,133 @@
1
- import clsx from "clsx";
2
-
3
- export interface ScoreBadgeProps {
4
- className?: string;
5
- name: string;
6
- ariaLabelPrefix?: string;
7
- score?: number | null;
8
- max?: number;
9
- showScore?: boolean;
10
- showMax?: boolean;
11
- inPercentage?: boolean;
12
- colors?: {
13
- background: string;
14
- gradient: string[];
15
- arrow: [string, string];
16
- text: string;
17
- };
18
- }
19
-
20
- export default function ScoreBadge(props: ScoreBadgeProps) {
21
- const defaultcolors: ScoreBadgeProps["colors"] = {
22
- background: "#CBD5E1",
23
- gradient: ["#FEE9B7", "#FDDE94", "#A5C991", "#6AA549", "#39870C"],
24
- arrow: ["#D52B1E", "#F9DFDD"],
25
- text: "#334155",
26
- };
27
- const {
28
- className,
29
- name,
30
- ariaLabelPrefix,
31
- score,
32
- max = 10,
33
- showScore = true,
34
- showMax = false,
35
- inPercentage = false,
36
- colors = defaultcolors,
37
- ...restProps
38
- } = props;
39
-
40
- return (
41
- <span
42
- className={clsx(["score-badge", `score-badge--${score}`, className])}
43
- {...restProps}
44
- >
45
- <svg
46
- width="5rem"
47
- height="2.5rem"
48
- viewBox="0 0 32 16"
49
- name={name}
50
- role="img"
51
- aria-label={`${ariaLabelPrefix || ""}${score + (inPercentage ? "%" : "") || "onbekend"}`}
52
- >
53
- <defs>
54
- <linearGradient id="gradient">
55
- {colors.gradient?.map((color, index) => (
56
- <stop
57
- key={`grd-${color}`}
58
- offset={`${(index * 100) / (colors.gradient.length - 1)}%`}
59
- style={{ stopColor: color, stopOpacity: 1 }}
60
- />
61
- ))}
62
- </linearGradient>
63
- <linearGradient id="arrow" gradientTransform="rotate(90)">
64
- {colors.arrow?.map((color, index) => (
65
- <stop
66
- key={`arr-${color}`}
67
- offset={index}
68
- style={{ stopColor: color }}
69
- />
70
- ))}
71
- </linearGradient>
72
- <filter id="glow">
73
- <feDropShadow
74
- dx="0.25"
75
- dy="0.25"
76
- stdDeviation="0.5"
77
- floodColor="#fff"
78
- floodOpacity="1"
79
- />
80
- </filter>
81
- </defs>
82
- <circle
83
- cx="16"
84
- cy="13"
85
- r="10"
86
- fill="none"
87
- stroke={colors.background}
88
- strokeWidth="5"
89
- strokeDasharray={`${Math.PI * 10} 1000`}
90
- strokeDashoffset={-1 * Math.PI * 10}
91
- strokeLinecap="round"
92
- />
93
- {score && score > 0 && (
94
- <>
95
- <circle
96
- cx="16"
97
- cy="13"
98
- r="10"
99
- fill="none"
100
- stroke="url(#gradient)"
101
- strokeWidth="5"
102
- strokeDasharray={`${(Math.PI * 10 * score) / max} 1000`}
103
- strokeDashoffset={-1 * Math.PI * 10}
104
- strokeLinecap="round"
105
- />
106
- <polygon
107
- points="16,15 14,13 16,2 18,13"
108
- transform={`rotate(${-90 + score * 1.8}, 16, 13)`}
109
- fill="url(#arrow)"
110
- />
111
- </>
112
- )}
113
- {showScore && (
114
- <text
115
- x="16"
116
- y="15"
117
- textAnchor="middle"
118
- fontSize="0.4rem"
119
- fontWeight={600}
120
- fill={colors.text}
121
- lengthAdjust="spacing"
122
- filter="url(#glow)"
123
- >
124
- {typeof score === "number"
125
- ? `${score}${showMax ? `/${max}` : ""}${inPercentage ? "%" : ""}`
126
- : "–"}
127
- </text>
128
- )}
129
- </svg>
130
- </span>
131
- );
132
- }
1
+ import clsx from "clsx";
2
+
3
+ export interface ScoreBadgeProps {
4
+ className?: string;
5
+ name: string;
6
+ ariaLabelPrefix?: string;
7
+ score?: number | null;
8
+ max?: number;
9
+ showScore?: boolean;
10
+ showMax?: boolean;
11
+ inPercentage?: boolean;
12
+ colors?: {
13
+ background: string;
14
+ gradient: string[];
15
+ arrow: [string, string];
16
+ text: string;
17
+ };
18
+ }
19
+
20
+ /** @deprecated */
21
+ export default function ScoreBadge(props: ScoreBadgeProps) {
22
+ const defaultcolors: ScoreBadgeProps["colors"] = {
23
+ background: "#CBD5E1",
24
+ gradient: ["#FEE9B7", "#FDDE94", "#A5C991", "#6AA549", "#39870C"],
25
+ arrow: ["#D52B1E", "#F9DFDD"],
26
+ text: "#334155",
27
+ };
28
+ const {
29
+ className,
30
+ name,
31
+ ariaLabelPrefix,
32
+ score,
33
+ max = 10,
34
+ showScore = true,
35
+ showMax = false,
36
+ inPercentage = false,
37
+ colors = defaultcolors,
38
+ ...restProps
39
+ } = props;
40
+
41
+ return (
42
+ <span
43
+ className={clsx(["score-badge", `score-badge--${score}`, className])}
44
+ {...restProps}
45
+ >
46
+ <svg
47
+ width="5rem"
48
+ height="2.5rem"
49
+ viewBox="0 0 32 16"
50
+ name={name}
51
+ role="img"
52
+ aria-label={`${ariaLabelPrefix || ""}${score + (inPercentage ? "%" : "") || "onbekend"}`}
53
+ >
54
+ <defs>
55
+ <linearGradient id="gradient">
56
+ {colors.gradient?.map((color, index) => (
57
+ <stop
58
+ key={`grd-${color}`}
59
+ offset={`${(index * 100) / (colors.gradient.length - 1)}%`}
60
+ style={{ stopColor: color, stopOpacity: 1 }}
61
+ />
62
+ ))}
63
+ </linearGradient>
64
+ <linearGradient id="arrow" gradientTransform="rotate(90)">
65
+ {colors.arrow?.map((color, index) => (
66
+ <stop
67
+ key={`arr-${color}`}
68
+ offset={index}
69
+ style={{ stopColor: color }}
70
+ />
71
+ ))}
72
+ </linearGradient>
73
+ <filter id="glow">
74
+ <feDropShadow
75
+ dx="0.25"
76
+ dy="0.25"
77
+ stdDeviation="0.5"
78
+ floodColor="#fff"
79
+ floodOpacity="1"
80
+ />
81
+ </filter>
82
+ </defs>
83
+ <circle
84
+ cx="16"
85
+ cy="13"
86
+ r="10"
87
+ fill="none"
88
+ stroke={colors.background}
89
+ strokeWidth="5"
90
+ strokeDasharray={`${Math.PI * 10} 1000`}
91
+ strokeDashoffset={-1 * Math.PI * 10}
92
+ strokeLinecap="round"
93
+ />
94
+ {score && score > 0 && (
95
+ <>
96
+ <circle
97
+ cx="16"
98
+ cy="13"
99
+ r="10"
100
+ fill="none"
101
+ stroke="url(#gradient)"
102
+ strokeWidth="5"
103
+ strokeDasharray={`${(Math.PI * 10 * score) / max} 1000`}
104
+ strokeDashoffset={-1 * Math.PI * 10}
105
+ strokeLinecap="round"
106
+ />
107
+ <polygon
108
+ points="16,15 14,13 16,2 18,13"
109
+ transform={`rotate(${-90 + score * 1.8}, 16, 13)`}
110
+ fill="url(#arrow)"
111
+ />
112
+ </>
113
+ )}
114
+ {showScore && (
115
+ <text
116
+ x="16"
117
+ y="15"
118
+ textAnchor="middle"
119
+ fontSize="0.4rem"
120
+ fontWeight={600}
121
+ fill={colors.text}
122
+ lengthAdjust="spacing"
123
+ filter="url(#glow)"
124
+ >
125
+ {typeof score === "number"
126
+ ? `${score}${showMax ? `/${max}` : ""}${inPercentage ? "%" : ""}`
127
+ : "–"}
128
+ </text>
129
+ )}
130
+ </svg>
131
+ </span>
132
+ );
133
+ }
@@ -1,66 +1,82 @@
1
- import {
2
- FormFieldTextInput,
3
- PrimaryActionButton,
4
- } from "@rijkshuisstijl-community/components-react";
5
- import clsx from "clsx";
6
- import type { PropsWithChildren } from "react";
7
- import { I18nextProvider, useTranslation } from "react-i18next";
8
- import Heading from "../heading/Heading";
9
- import i18n from "../i18n";
10
- import Icon from "../iconsSprite/Icon";
11
- import styles from "./styles.module.css";
12
-
13
- export interface SearchProps {
14
- searchUrl: string;
15
- searchKey?: string;
16
- searchTerm?: string;
17
- className?: string;
18
- }
19
-
20
- const Search = (props: SearchProps) => {
21
- const { t } = useTranslation();
22
- const { searchUrl, searchKey = "q", searchTerm, className } = props;
23
-
24
- return (
25
- <search
26
- aria-labelledby="search-heading"
27
- className={clsx(styles.search, className)}
28
- >
29
- <Heading id="search-heading" level={2} appearanceLevel={3}>
30
- {t("components.search")}
31
- </Heading>
32
- <form action={searchUrl} method="GET" className={styles.form}>
33
- <FormFieldTextInput
34
- className={styles.input}
35
- aria-describedby="search-help"
36
- label={t("components.search-label")}
37
- name={searchKey}
38
- type="text"
39
- defaultValue={searchTerm}
40
- >
41
- <div className="sr-only" id="search-help">
42
- {t("components.search-help")}
43
- </div>
44
- </FormFieldTextInput>
45
-
46
- <PrimaryActionButton
47
- aria-label={t("components.search-button")}
48
- className={styles.button}
49
- type="submit"
50
- >
51
- <Icon name="zoek-inline" width="1.5rem" height="1.5rem" />
52
- </PrimaryActionButton>
53
- </form>
54
- </search>
55
- );
56
- };
57
-
58
- const TranslatedSearch = (props: PropsWithChildren<SearchProps>) => {
59
- return (
60
- <I18nextProvider i18n={i18n}>
61
- <Search {...props} />
62
- </I18nextProvider>
63
- );
64
- };
65
-
66
- export default TranslatedSearch;
1
+ import {
2
+ FormFieldTextInput,
3
+ PrimaryActionButton,
4
+ } from "@rijkshuisstijl-community/components-react";
5
+ import clsx from "clsx";
6
+ import type { PropsWithChildren } from "react";
7
+ import { I18nextProvider, useTranslation } from "react-i18next";
8
+ import Heading from "../heading/Heading";
9
+ import i18n from "../i18n";
10
+ import Icon from "../iconsSprite/Icon";
11
+ import styles from "./styles.module.css";
12
+
13
+ export interface SearchProps {
14
+ searchUrl: string;
15
+ searchKey?: string;
16
+ searchTerm?: string;
17
+ hiddenFields?: [string, string][];
18
+ className?: string;
19
+ }
20
+
21
+ const Search = (props: SearchProps) => {
22
+ const { t } = useTranslation();
23
+ const {
24
+ searchUrl,
25
+ searchKey = "q",
26
+ searchTerm,
27
+ hiddenFields = [],
28
+ className,
29
+ } = props;
30
+
31
+ return (
32
+ <search
33
+ aria-labelledby="search-heading"
34
+ className={clsx(styles.search, className)}
35
+ >
36
+ <Heading id="search-heading" level={2} appearanceLevel={3}>
37
+ {t("components.search")}
38
+ </Heading>
39
+ <form action={searchUrl} method="GET" className={styles.form}>
40
+ {hiddenFields.map(([name, value], index) => (
41
+ <input
42
+ // biome-ignore lint/suspicious/noArrayIndexKey: duplicate query params can share name and value
43
+ key={`${name}-${value}-${index}`}
44
+ type="hidden"
45
+ name={name}
46
+ value={value}
47
+ />
48
+ ))}
49
+ <FormFieldTextInput
50
+ className={styles.input}
51
+ aria-describedby="search-help"
52
+ label={t("components.search-label")}
53
+ name={searchKey}
54
+ type="text"
55
+ defaultValue={searchTerm}
56
+ >
57
+ <div className="sr-only" id="search-help">
58
+ {t("components.search-help")}
59
+ </div>
60
+ </FormFieldTextInput>
61
+
62
+ <PrimaryActionButton
63
+ aria-label={t("components.search-button")}
64
+ className={styles.button}
65
+ type="submit"
66
+ >
67
+ <Icon name="zoek-inline" width="1.5rem" height="1.5rem" />
68
+ </PrimaryActionButton>
69
+ </form>
70
+ </search>
71
+ );
72
+ };
73
+
74
+ const TranslatedSearch = (props: PropsWithChildren<SearchProps>) => {
75
+ return (
76
+ <I18nextProvider i18n={i18n}>
77
+ <Search {...props} />
78
+ </I18nextProvider>
79
+ );
80
+ };
81
+
82
+ export default TranslatedSearch;
@@ -1,39 +1,39 @@
1
- .search {
2
- --utrecht-textbox-border-width: 2px;
3
- --utrecht-textbox-border-radius: 5px;
4
- --utrecht-textbox-border-color: var(--rhc-color-cool-grey-900);
5
- }
6
-
7
- .form {
8
- display: grid;
9
- grid-template-areas: 'input button';
10
- grid-template-columns: auto min-content;
11
- gap: 0;
12
- align-items: end;
13
- }
14
-
15
- @media (--xxs-and-below-viewport) {
16
- .form {
17
- justify-content: center;
18
- }
19
- }
20
-
21
- .input {
22
- grid-area: input;
23
-
24
- :global(.utrecht-textbox) {
25
- border-top-right-radius: 0;
26
- border-bottom-right-radius: 0;
27
- }
28
-
29
- :global(.utrecht-textbox--html-input:focus-visible) {
30
- position: relative;
31
- z-index: 1;
32
- }
33
- }
34
-
35
- .button:global(.utrecht-button) {
36
- grid-area: button;
37
- border-top-left-radius: 0;
38
- border-bottom-left-radius: 0;
39
- }
1
+ .search {
2
+ --utrecht-textbox-border-width: 2px;
3
+ --utrecht-textbox-border-radius: 5px;
4
+ --utrecht-textbox-border-color: var(--rhc-color-cool-grey-900);
5
+ }
6
+
7
+ .form {
8
+ display: grid;
9
+ grid-template-areas: 'input button';
10
+ grid-template-columns: auto min-content;
11
+ gap: 0;
12
+ align-items: end;
13
+ }
14
+
15
+ @media (--xxs-and-below-viewport) {
16
+ .form {
17
+ justify-content: center;
18
+ }
19
+ }
20
+
21
+ .input {
22
+ grid-area: input;
23
+
24
+ :global(.utrecht-textbox) {
25
+ border-top-right-radius: 0;
26
+ border-bottom-right-radius: 0;
27
+ }
28
+
29
+ :global(.utrecht-textbox--html-input:focus-visible) {
30
+ position: relative;
31
+ z-index: 1;
32
+ }
33
+ }
34
+
35
+ .button:global(.utrecht-button) {
36
+ grid-area: button;
37
+ border-top-left-radius: 0;
38
+ border-bottom-left-radius: 0;
39
+ }
@@ -1,24 +1,24 @@
1
- import { Logo } from "@developer-overheid-nl/proprietary";
2
- import type { JSX } from "react";
3
-
4
- export default function SiteLogo({
5
- isRoot,
6
- href,
7
- }: {
8
- isRoot: boolean;
9
- href: string;
10
- }) {
11
- const element = !isRoot ? "a" : "div";
12
- const props = {
13
- className: "site-logo",
14
- ...(!isRoot ? { href } : {}),
15
- };
16
-
17
- const Element = element as keyof JSX.IntrinsicElements;
18
-
19
- return (
20
- <Element {...props}>
21
- <Logo forced="light" />
22
- </Element>
23
- );
24
- }
1
+ import { Logo } from "@developer-overheid-nl/proprietary";
2
+ import type { JSX } from "react";
3
+
4
+ export default function SiteLogo({
5
+ isRoot,
6
+ href,
7
+ }: {
8
+ isRoot: boolean;
9
+ href: string;
10
+ }) {
11
+ const element = !isRoot ? "a" : "div";
12
+ const props = {
13
+ className: "site-logo",
14
+ ...(!isRoot ? { href } : {}),
15
+ };
16
+
17
+ const Element = element as keyof JSX.IntrinsicElements;
18
+
19
+ return (
20
+ <Element {...props}>
21
+ <Logo forced="light" />
22
+ </Element>
23
+ );
24
+ }
@@ -0,0 +1,86 @@
1
+ import clsx from "clsx";
2
+ import {
3
+ type ForwardedRef,
4
+ forwardRef,
5
+ type InputHTMLAttributes,
6
+ useId,
7
+ } from "react";
8
+ import styles from "./styles.module.css";
9
+
10
+ export interface SwitchLabels {
11
+ on: string;
12
+ off: string;
13
+ }
14
+
15
+ export interface SwitchProps
16
+ extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "readOnly"> {
17
+ invalid?: boolean;
18
+ labels?: SwitchLabels;
19
+ }
20
+
21
+ const Switch = forwardRef(
22
+ (props: SwitchProps, ref: ForwardedRef<HTMLInputElement>) => {
23
+ const genId = useId();
24
+ const {
25
+ id = genId,
26
+ disabled,
27
+ invalid,
28
+ required,
29
+ hidden,
30
+ checked,
31
+ defaultChecked,
32
+ role,
33
+ tabIndex,
34
+ className,
35
+ labels = { on: "ON", off: "OFF" },
36
+ ...restProps
37
+ } = props;
38
+
39
+ return (
40
+ <div
41
+ className={clsx(
42
+ "utrecht-form-toggle",
43
+ "utrecht-form-toggle--html-checkbox",
44
+ {
45
+ "utrecht-form-toggle--disabled": disabled,
46
+ "utrecht-form-toggle--invalid": invalid,
47
+ "utrecht-form-toggle--required": required,
48
+ },
49
+ styles.switch,
50
+ className,
51
+ )}
52
+ hidden={hidden}
53
+ >
54
+ <input
55
+ id={id}
56
+ aria-invalid={invalid || undefined}
57
+ type="checkbox"
58
+ className="utrecht-form-toggle__checkbox"
59
+ checked={checked}
60
+ defaultChecked={defaultChecked || undefined}
61
+ disabled={disabled || undefined}
62
+ required={required}
63
+ ref={ref}
64
+ role={role}
65
+ tabIndex={tabIndex}
66
+ {...restProps}
67
+ />
68
+ <label
69
+ htmlFor={id}
70
+ className={clsx(
71
+ "utrecht-form-toggle__track",
72
+ "utrecht-form-toggle__track--html-label",
73
+ )}
74
+ >
75
+ <div className="utrecht-form-toggle__thumb">
76
+ <span className="sr-only">
77
+ {checked || defaultChecked ? labels.on : labels.off}
78
+ </span>
79
+ </div>
80
+ </label>
81
+ </div>
82
+ );
83
+ },
84
+ );
85
+
86
+ export default Switch;
@@ -0,0 +1,7 @@
1
+ .switch {
2
+ &:hover {
3
+ :global(.utrecht-form-toggle__track) {
4
+ background-color: var(--utrecht-form-toggle-hover-background-color);
5
+ }
6
+ }
7
+ }