@developer-overheid-nl/don-register-components 1.0.0 → 1.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/LICENSE.md +291 -291
  3. package/README.md +20 -20
  4. package/package.json +10 -7
  5. package/src/alert/Alert.tsx +19 -19
  6. package/src/alert/styles.module.css +3 -3
  7. package/src/alignBox/AlignBox.tsx +111 -110
  8. package/src/alignBox/styles.module.css +106 -106
  9. package/src/analytics/PiwikPro.tsx +72 -0
  10. package/src/analytics/index.ts +1 -0
  11. package/src/article/Article.tsx +10 -10
  12. package/src/block/Block.tsx +35 -35
  13. package/src/block/styles.module.css +29 -29
  14. package/src/button/Button.tsx +3 -3
  15. package/src/cardAsLink/CardAsLink.tsx +21 -21
  16. package/src/cardAsLink/styles.module.css +23 -23
  17. package/src/cardsList/CardsList.tsx +54 -54
  18. package/src/cardsList/styles.module.css +19 -19
  19. package/src/client.ts +2 -2
  20. package/src/container/Container.tsx +10 -10
  21. package/src/container/styles.module.css +28 -28
  22. package/src/copyButton/CopyButton.tsx +39 -39
  23. package/src/copyButton/styles.module.css +13 -13
  24. package/src/dataBadgeLink/DataBadgeLink.tsx +50 -50
  25. package/src/dataBadgeLink/styles.module.css +43 -43
  26. package/src/dataSummary/DataSummary.tsx +22 -22
  27. package/src/dataSummary/DataSummaryItem.tsx +21 -21
  28. package/src/dataSummary/styles.module.css +70 -70
  29. package/src/fieldset/FieldSet.tsx +3 -3
  30. package/src/filters/Filters.tsx +115 -115
  31. package/src/filters/styles.module.css +26 -26
  32. package/src/footer/Footer.tsx +76 -76
  33. package/src/footer/styles.module.css +103 -103
  34. package/src/formFieldLabel/FormFieldLabel.tsx +23 -23
  35. package/src/formFieldTextInput/FormFieldTextInput.tsx +3 -3
  36. package/src/header/Header.tsx +137 -137
  37. package/src/header/styles.module.css +71 -71
  38. package/src/heading/Heading.tsx +10 -10
  39. package/src/headingGroup/HeadingGroup.tsx +48 -48
  40. package/src/headingGroup/styles.module.css +3 -3
  41. package/src/i18n.ts +25 -24
  42. package/src/iconBadge/IconBadge.tsx +32 -32
  43. package/src/iconBadge/getAppearance.ts +47 -47
  44. package/src/iconBadge/styles.module.css +19 -19
  45. package/src/iconsSprite/Icon.tsx +17 -17
  46. package/src/iconsSprite/IconsSprite.tsx +5 -5
  47. package/src/index.ts +80 -80
  48. package/src/link/Link.tsx +10 -10
  49. package/src/markdown/Markdown.tsx +42 -42
  50. package/src/pagination/Pagination.tsx +144 -144
  51. package/src/pagination/styles.module.css +13 -13
  52. package/src/paragraph/Paragraph.tsx +10 -10
  53. package/src/pillBadge/PillBadge.examples.tsx +107 -107
  54. package/src/pillBadge/PillBadge.tsx +51 -51
  55. package/src/pillBadge/styles.module.css +194 -194
  56. package/src/readOnlyTextInput/ReadOnlyTextInput.tsx +24 -24
  57. package/src/readOnlyTextInput/styles.module.css +19 -19
  58. package/src/scoreBadge/ScoreBadge.tsx +132 -132
  59. package/src/search/Search.tsx +66 -66
  60. package/src/search/styles.module.css +39 -39
  61. package/src/siteLogo/SiteLogo.tsx +24 -24
  62. package/src/topNavigation/TopNavigation.tsx +67 -64
  63. package/src/topNavigation/styles.module.css +54 -54
  64. package/tsconfig.json +121 -121
@@ -1,132 +1,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
- 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
+ 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,66 +1,66 @@
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
+ 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,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
+ }
@@ -1,64 +1,67 @@
1
- import {
2
- type IconProps,
3
- NavBar,
4
- type NavBarItemProps,
5
- } from "@rijkshuisstijl-community/components-react";
6
- import type { ReactElement } from "react";
7
- import Icon from "../iconsSprite/Icon";
8
- import styles from "./styles.module.css";
9
-
10
- export interface NavBarItem {
11
- id: string;
12
- label: string;
13
- href: string;
14
- current?: boolean;
15
- icon?: string | ReactElement<IconProps>;
16
- }
17
-
18
- export interface TopNavigationProps {
19
- items: Array<NavBarItem>;
20
- endItems?: Array<NavBarItem>;
21
- }
22
-
23
- const processIcon = (
24
- icon: NavBarItem["icon"],
25
- ): ReactElement<IconProps> | undefined => {
26
- if (typeof icon === "string") {
27
- switch (icon) {
28
- case "_add":
29
- return <Icon name="plus-cirkel-inline" />;
30
- case "_external":
31
- return (
32
- <Icon name="externe-link-inline" aria-label={`Externe link naar`} />
33
- );
34
- }
35
- } else {
36
- return icon;
37
- }
38
- };
39
-
40
- export const processNavBarItems = (
41
- items: Array<NavBarItem>,
42
- ): NavBarItemProps[] => {
43
- return items.map((item) => ({
44
- ...item,
45
- // TODO: remove current from this output. Issue #188
46
- bold: item.current,
47
- icon: processIcon(item.icon),
48
- }));
49
- };
50
-
51
- export default function TopNavigation({ items, endItems }: TopNavigationProps) {
52
- const processedItems = processNavBarItems(items);
53
- const processedEndItems = endItems && processNavBarItems(endItems);
54
-
55
- return (
56
- <div className={styles.container}>
57
- <NavBar
58
- items={processedItems}
59
- endItems={processedEndItems}
60
- className={styles.navbar}
61
- />
62
- </div>
63
- );
64
- }
1
+ import {
2
+ type IconProps,
3
+ NavBar,
4
+ type NavBarItemProps,
5
+ } from "@rijkshuisstijl-community/components-react";
6
+ import type { ReactElement } from "react";
7
+ import Icon from "../iconsSprite/Icon";
8
+ import styles from "./styles.module.css";
9
+
10
+ export interface NavBarItem {
11
+ id: string;
12
+ label: string;
13
+ href: string;
14
+ current?: boolean;
15
+ icon?: string | ReactElement<IconProps>;
16
+ }
17
+
18
+ export interface TopNavigationProps {
19
+ items: Array<NavBarItem>;
20
+ endItems?: Array<NavBarItem>;
21
+ }
22
+
23
+ const processIcon = (
24
+ icon: NavBarItem["icon"],
25
+ ): ReactElement<IconProps> | undefined => {
26
+ if (typeof icon === "string") {
27
+ switch (icon) {
28
+ case "_add":
29
+ return <Icon name="plus-cirkel-inline" />;
30
+ case "_external":
31
+ return (
32
+ <Icon name="externe-link-inline" aria-label={`Externe link naar`} />
33
+ );
34
+ }
35
+ } else {
36
+ return icon;
37
+ }
38
+ };
39
+
40
+ export const processNavBarItems = (
41
+ items: Array<NavBarItem>,
42
+ ): NavBarItemProps[] => {
43
+ return items.map((item) => {
44
+ const { current, ...rest } = item;
45
+
46
+ return {
47
+ ...rest,
48
+ bold: current,
49
+ icon: processIcon(item.icon),
50
+ };
51
+ });
52
+ };
53
+
54
+ export default function TopNavigation({ items, endItems }: TopNavigationProps) {
55
+ const processedItems = processNavBarItems(items);
56
+ const processedEndItems = endItems && processNavBarItems(endItems);
57
+
58
+ return (
59
+ <div className={styles.container}>
60
+ <NavBar
61
+ items={processedItems}
62
+ endItems={processedEndItems}
63
+ className={styles.navbar}
64
+ />
65
+ </div>
66
+ );
67
+ }