@developer-overheid-nl/don-register-components 1.3.1 → 1.6.2

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 (139) hide show
  1. package/CHANGELOG.md +176 -130
  2. package/LICENSE.md +291 -291
  3. package/README.md +20 -20
  4. package/package.json +10 -8
  5. package/src/Introduction.mdx +52 -0
  6. package/src/alert/Alert.stories.tsx +57 -0
  7. package/src/alert/Alert.tsx +19 -19
  8. package/src/alert/styles.module.css +3 -3
  9. package/src/alignBox/AlignBox.stories.tsx +84 -0
  10. package/src/alignBox/AlignBox.tsx +114 -114
  11. package/src/alignBox/styles.module.css +110 -110
  12. package/src/amountLabel/AmountLabel.stories.tsx +28 -0
  13. package/src/amountLabel/AmountLabel.tsx +21 -16
  14. package/src/amountLabel/styles.module.css +11 -11
  15. package/src/analytics/PiwikPro.tsx +94 -94
  16. package/src/analytics/index.ts +1 -1
  17. package/src/article/Article.stories.tsx +53 -0
  18. package/src/article/Article.tsx +10 -10
  19. package/src/badgeList/BadgeList.tsx +34 -34
  20. package/src/badgeList/styles.module.css +37 -37
  21. package/src/block/Block.stories.tsx +58 -0
  22. package/src/block/Block.tsx +35 -35
  23. package/src/block/styles.module.css +29 -29
  24. package/src/button/Button.stories.tsx +56 -0
  25. package/src/button/Button.tsx +3 -3
  26. package/src/button/ButtonAction.stories.tsx +62 -0
  27. package/src/button/ButtonAction.tsx +51 -0
  28. package/src/cardAsLink/CardAsLink.stories.tsx +81 -0
  29. package/src/cardAsLink/CardAsLink.tsx +21 -21
  30. package/src/cardAsLink/styles.module.css +23 -23
  31. package/src/cardsList/CardsList.tsx +56 -56
  32. package/src/cardsList/styles.module.css +18 -19
  33. package/src/client.ts +7 -7
  34. package/src/container/Container.stories.tsx +21 -0
  35. package/src/container/Container.tsx +10 -10
  36. package/src/container/styles.module.css +28 -28
  37. package/src/copyButton/CopyButton.stories.tsx +41 -0
  38. package/src/copyButton/CopyButton.tsx +45 -39
  39. package/src/copyButton/styles.module.css +13 -13
  40. package/src/dataBadgeLink/DataBadgeLink.stories.tsx +137 -0
  41. package/src/dataBadgeLink/DataBadgeLink.tsx +59 -53
  42. package/src/dataBadgeLink/styles.module.css +89 -89
  43. package/src/dataSummary/DataSummary.tsx +22 -22
  44. package/src/dataSummary/DataSummaryItem.tsx +21 -21
  45. package/src/dataSummary/styles.module.css +75 -75
  46. package/src/facetFilters/FacetFilters.stories.tsx +93 -0
  47. package/src/facetFilters/FacetFilters.tsx +424 -419
  48. package/src/facetFilters/styles.module.css +3 -3
  49. package/src/fieldset/FieldSet.stories.tsx +45 -0
  50. package/src/fieldset/FieldSet.tsx +3 -3
  51. package/src/filters/Filters.stories.tsx +45 -0
  52. package/src/filters/Filters.tsx +116 -116
  53. package/src/filters/styles.module.css +26 -26
  54. package/src/footer/Footer.stories.tsx +127 -0
  55. package/src/footer/Footer.tsx +81 -76
  56. package/src/footer/styles.module.css +103 -103
  57. package/src/formFieldCheckboxGroup/FormFieldCheckboxGroup.stories.tsx +48 -0
  58. package/src/formFieldCheckboxGroup/FormFieldCheckboxGroup.tsx +16 -16
  59. package/src/formFieldCheckboxGroup/styles.module.css +5 -5
  60. package/src/formFieldCheckboxOption/FormFieldCheckboxOption.stories.tsx +61 -0
  61. package/src/formFieldCheckboxOption/FormFieldCheckboxOption.tsx +26 -26
  62. package/src/formFieldCheckboxOption/styles.module.css +22 -22
  63. package/src/formFieldLabel/FormFieldLabel.stories.tsx +21 -0
  64. package/src/formFieldLabel/FormFieldLabel.tsx +23 -23
  65. package/src/formFieldRadioGroup/FormFieldRadioGroup.stories.tsx +57 -0
  66. package/src/formFieldRadioGroup/FormFieldRadioGroup.tsx +13 -13
  67. package/src/formFieldRadioGroup/styles.module.css +5 -5
  68. package/src/formFieldRadioOption/FormFieldRadioOption.stories.tsx +48 -0
  69. package/src/formFieldRadioOption/FormFieldRadioOption.tsx +75 -75
  70. package/src/formFieldRadioOption/styles.module.css +49 -49
  71. package/src/formFieldSwitch/FormFieldSwitch.stories.tsx +61 -0
  72. package/src/formFieldSwitch/FormFieldSwitch.tsx +82 -79
  73. package/src/formFieldSwitch/styles.module.css +32 -32
  74. package/src/formFieldTextInput/FormFieldTextInput.stories.tsx +45 -0
  75. package/src/formFieldTextInput/FormFieldTextInput.tsx +3 -3
  76. package/src/grid/Grid.stories.tsx +37 -0
  77. package/src/grid/Grid.tsx +48 -0
  78. package/src/grid/styles.module.css +24 -0
  79. package/src/header/Header.stories.tsx +54 -0
  80. package/src/header/Header.tsx +137 -137
  81. package/src/header/styles.module.css +71 -71
  82. package/src/heading/Heading.stories.tsx +60 -0
  83. package/src/heading/Heading.tsx +15 -15
  84. package/src/headingGroup/HeadingGroup.stories.tsx +57 -0
  85. package/src/headingGroup/HeadingGroup.tsx +48 -48
  86. package/src/headingGroup/styles.module.css +3 -3
  87. package/src/i18n.ts +24 -25
  88. package/src/iconBadge/IconBadge.stories.tsx +46 -0
  89. package/src/iconBadge/IconBadge.tsx +35 -35
  90. package/src/iconBadge/getAppearance.ts +53 -53
  91. package/src/iconBadge/styles.module.css +19 -19
  92. package/src/iconsSprite/Icon.stories.tsx +73 -0
  93. package/src/iconsSprite/Icon.tsx +17 -17
  94. package/src/iconsSprite/IconsSprite.tsx +5 -5
  95. package/src/index.ts +117 -107
  96. package/src/infoButton/InfoButton.stories.tsx +52 -0
  97. package/src/infoButton/InfoButton.tsx +45 -45
  98. package/src/infoButton/styles.module.css +43 -43
  99. package/src/link/Link.stories.tsx +49 -0
  100. package/src/link/Link.tsx +10 -10
  101. package/src/markdown/Markdown.stories.tsx +48 -0
  102. package/src/markdown/Markdown.tsx +42 -42
  103. package/src/overlay/Overlay.stories.tsx +38 -0
  104. package/src/overlay/Overlay.tsx +18 -18
  105. package/src/overlay/styles.module.css +15 -15
  106. package/src/pagination/Pagination.stories.tsx +91 -0
  107. package/src/pagination/Pagination.tsx +267 -267
  108. package/src/pagination/styles.module.css +28 -28
  109. package/src/paragraph/Paragraph.stories.tsx +45 -0
  110. package/src/paragraph/Paragraph.tsx +24 -24
  111. package/src/paragraph/styles.module.css +6 -6
  112. package/src/pillBadge/PillBadge.examples.tsx +107 -107
  113. package/src/pillBadge/PillBadge.stories.tsx +257 -0
  114. package/src/pillBadge/PillBadge.tsx +60 -51
  115. package/src/pillBadge/styles.module.css +214 -214
  116. package/src/readOnlyTextInput/ReadOnlyTextInput.stories.tsx +49 -0
  117. package/src/readOnlyTextInput/ReadOnlyTextInput.tsx +24 -24
  118. package/src/readOnlyTextInput/styles.module.css +19 -19
  119. package/src/scoreBadge/ScoreBadge.stories.tsx +45 -0
  120. package/src/scoreBadge/ScoreBadge.tsx +135 -133
  121. package/src/search/Search.stories.tsx +65 -0
  122. package/src/search/Search.tsx +82 -82
  123. package/src/search/styles.module.css +40 -39
  124. package/src/siteLogo/ExampleLogo.stories.tsx +40 -0
  125. package/src/siteLogo/SiteLogo.stories.tsx +28 -0
  126. package/src/siteLogo/SiteLogo.tsx +24 -24
  127. package/src/sortForm/SortForm.stories.tsx +111 -0
  128. package/src/sortForm/SortForm.tsx +121 -0
  129. package/src/sortForm/styles.module.css +40 -0
  130. package/src/switch/Switch.stories.tsx +68 -0
  131. package/src/switch/Switch.tsx +152 -86
  132. package/src/switch/styles.module.css +54 -7
  133. package/src/toolTip/ToolTip.stories.tsx +131 -0
  134. package/src/toolTip/ToolTip.tsx +55 -55
  135. package/src/toolTip/styles.module.css +49 -49
  136. package/src/topNavigation/TopNavigation.stories.tsx +71 -0
  137. package/src/topNavigation/TopNavigation.tsx +67 -67
  138. package/src/topNavigation/styles.module.css +54 -54
  139. package/tsconfig.json +122 -121
@@ -1,3 +1,3 @@
1
- .facet {
2
- margin-block-end: 0.5rem;
3
- }
1
+ .facet {
2
+ margin-block-end: 0.5rem;
3
+ }
@@ -0,0 +1,45 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import FieldSet from "./FieldSet";
3
+
4
+ /**
5
+ * FieldSet groepeert gerelateerde formuliervelden onder een gezamenlijke
6
+ * legenda (`legend`), met ondersteuning voor een sectie-variant en een
7
+ * disabled- of invalid-status.
8
+ */
9
+ const meta = {
10
+ title: "Components/Form/FieldSet",
11
+ component: FieldSet,
12
+ tags: ["autodocs", "re-export"],
13
+ args: {
14
+ legend: "Contactgegevens",
15
+ children: "Veldinhoud van de fieldset.",
16
+ },
17
+ argTypes: {
18
+ disabled: { control: "boolean" },
19
+ invalid: { control: "boolean" },
20
+ section: { control: "boolean" },
21
+ },
22
+ } satisfies Meta<typeof FieldSet>;
23
+
24
+ export default meta;
25
+ type Story = StoryObj<typeof meta>;
26
+
27
+ export const Default: Story = {};
28
+
29
+ export const Section: Story = {
30
+ args: {
31
+ section: true,
32
+ },
33
+ };
34
+
35
+ export const Disabled: Story = {
36
+ args: {
37
+ disabled: true,
38
+ },
39
+ };
40
+
41
+ export const Invalid: Story = {
42
+ args: {
43
+ invalid: true,
44
+ },
45
+ };
@@ -1,3 +1,3 @@
1
- import { Fieldset } from "@rijkshuisstijl-community/components-react";
2
-
3
- export default Fieldset;
1
+ import { Fieldset } from "@rijkshuisstijl-community/components-react";
2
+
3
+ export default Fieldset;
@@ -0,0 +1,45 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import Filters from "./Filters";
3
+
4
+ const routing = {
5
+ url: "https://developer.overheid.nl/apis",
6
+ query: { organisation: "kadaster" },
7
+ };
8
+
9
+ const organisations = [
10
+ { uri: "kadaster", label: "Kadaster" },
11
+ { uri: "geonovum", label: "Geonovum" },
12
+ { uri: "logius", label: "Logius" },
13
+ ];
14
+
15
+ /**
16
+ * Filters toont een lijst van organisaties als navigatielinks en markeert de
17
+ * organisatie uit de `routing`-query als actief filter.
18
+ *
19
+ * Verouderd: gebruik `FacetFilters` in plaats van dit component.
20
+ */
21
+ const meta = {
22
+ title: "Components/Filters",
23
+ component: Filters,
24
+ tags: ["autodocs", "custom", "deprecated"],
25
+ args: {
26
+ data: organisations,
27
+ headers: {},
28
+ error: null,
29
+ routing,
30
+ },
31
+ } satisfies Meta<typeof Filters>;
32
+
33
+ export default meta;
34
+ type Story = StoryObj<typeof meta>;
35
+
36
+ export const Default: Story = {};
37
+
38
+ export const WithError: Story = {
39
+ args: {
40
+ data: [],
41
+ error: { message: "Kan filters niet laden." },
42
+ status: 500,
43
+ statusText: "Internal Server Error",
44
+ },
45
+ };
@@ -1,116 +1,116 @@
1
- // 'use client';
2
- /* biome-ignore-all lint: TODO: filters needs a refactor anyway */
3
-
4
- import {
5
- Heading,
6
- LinkList,
7
- LinkListLink,
8
- } from "@rijkshuisstijl-community/components-react";
9
- import clsx from "clsx";
10
- import type { HTMLProps, PropsWithChildren } from "react";
11
- import { I18nextProvider, useTranslation } from "react-i18next";
12
- import Alert from "../alert/Alert";
13
- import DataBadgeLink from "../dataBadgeLink/DataBadgeLink";
14
- import i18n from "../i18n";
15
- import Icon from "../iconsSprite/Icon";
16
- import styles from "./styles.module.css";
17
-
18
- export interface FiltersProps extends HTMLProps<HTMLDivElement> {
19
- routing?: Record<string, any>;
20
- data: any;
21
- headers: any;
22
- error: any;
23
- status?: number;
24
- statusText?: string;
25
- }
26
-
27
- const ListLinkIcon = ({ isActive }: { isActive: boolean }) => {
28
- return (
29
- <Icon
30
- className={clsx([styles.icon, isActive && styles.active])}
31
- name={isActive ? "active" : "delta-naar-rechts-inline"}
32
- />
33
- );
34
- };
35
-
36
- /**
37
- * @deprecated Use FacetFilters component. This component will be removed in a later version.
38
- */
39
- const Filters = (props: PropsWithChildren<FiltersProps>) => {
40
- const { t } = useTranslation();
41
- const { data, error, status, statusText, className, routing } = props;
42
- const organisations = data && !data.message ? data : [];
43
- const currentOrganisation =
44
- organisations &&
45
- organisations.find((org: any) => org?.uri === routing?.query?.organisation);
46
-
47
- return (
48
- <div className={clsx([styles.filters, className])}>
49
- {currentOrganisation && (
50
- <div
51
- className={clsx("utrecht-badge-list", styles.currentFilter)}
52
- role="list"
53
- >
54
- <Heading level={2} appearanceLevel={3}>
55
- {t("components.current-filters")}
56
- </Heading>
57
- <DataBadgeLink
58
- role="listitem"
59
- aria-pressed={null}
60
- helperText={t("components.remove-filter")}
61
- icon={<Icon name="kruis-inline" />}
62
- href={new URL(`../`, routing?.url).toString()}
63
- >
64
- {styles.badgeLink}
65
- {currentOrganisation?.label}
66
- </DataBadgeLink>
67
- </div>
68
- )}
69
- <Heading level={2} appearanceLevel={3}>
70
- {t("components.filter-by", { type: "organisatie" })}
71
- </Heading>
72
- <LinkList>
73
- {organisations &&
74
- organisations.map((organisation: any) => (
75
- <LinkListLink
76
- className={clsx([
77
- organisation.uri === routing?.query?.organisation &&
78
- styles.active,
79
- ])}
80
- key={organisation.uri}
81
- href={new URL(
82
- `../?organisation=${organisation.uri}`,
83
- routing?.url,
84
- ).toString()}
85
- icon={
86
- <ListLinkIcon
87
- isActive={organisation.uri === routing?.query?.organisation}
88
- />
89
- }
90
- >
91
- {organisation.label}
92
- </LinkListLink>
93
- ))}
94
- </LinkList>
95
-
96
- {error && (
97
- <Alert type="error">
98
- {(error as unknown as any).message ||
99
- (error as unknown as any).error_msg ||
100
- `${status}: ${statusText}` ||
101
- t("components.fuzz-error")}
102
- </Alert>
103
- )}
104
- </div>
105
- );
106
- };
107
-
108
- const TranslatedFilters = (props: PropsWithChildren<FiltersProps>) => {
109
- return (
110
- <I18nextProvider i18n={i18n}>
111
- <Filters {...props} />
112
- </I18nextProvider>
113
- );
114
- };
115
-
116
- export default TranslatedFilters;
1
+ // 'use client';
2
+ /* biome-ignore-all lint: TODO: filters needs a refactor anyway */
3
+
4
+ import {
5
+ Heading,
6
+ LinkList,
7
+ LinkListLink,
8
+ } from "@rijkshuisstijl-community/components-react";
9
+ import clsx from "clsx";
10
+ import type { HTMLProps, PropsWithChildren } from "react";
11
+ import { I18nextProvider, useTranslation } from "react-i18next";
12
+ import Alert from "../alert/Alert";
13
+ import DataBadgeLink from "../dataBadgeLink/DataBadgeLink";
14
+ import i18n from "../i18n";
15
+ import Icon from "../iconsSprite/Icon";
16
+ import styles from "./styles.module.css";
17
+
18
+ export interface FiltersProps extends HTMLProps<HTMLDivElement> {
19
+ routing?: Record<string, any>;
20
+ data: any;
21
+ headers: any;
22
+ error: any;
23
+ status?: number;
24
+ statusText?: string;
25
+ }
26
+
27
+ const ListLinkIcon = ({ isActive }: { isActive: boolean }) => {
28
+ return (
29
+ <Icon
30
+ className={clsx([styles.icon, isActive && styles.active])}
31
+ name={isActive ? "active" : "delta-naar-rechts-inline"}
32
+ />
33
+ );
34
+ };
35
+
36
+ /**
37
+ * @deprecated Use FacetFilters component. This component will be removed in a later version.
38
+ */
39
+ const Filters = (props: PropsWithChildren<FiltersProps>) => {
40
+ const { t } = useTranslation();
41
+ const { data, error, status, statusText, className, routing } = props;
42
+ const organisations = data && !data.message ? data : [];
43
+ const currentOrganisation =
44
+ organisations &&
45
+ organisations.find((org: any) => org?.uri === routing?.query?.organisation);
46
+
47
+ return (
48
+ <div className={clsx([styles.filters, className])}>
49
+ {currentOrganisation && (
50
+ <div
51
+ className={clsx("utrecht-badge-list", styles.currentFilter)}
52
+ role="list"
53
+ >
54
+ <Heading level={2} appearanceLevel={3}>
55
+ {t("components.current-filters")}
56
+ </Heading>
57
+ <DataBadgeLink
58
+ role="listitem"
59
+ aria-pressed={null}
60
+ helperText={t("components.remove-filter")}
61
+ icon={<Icon name="kruis-inline" />}
62
+ href={new URL(`../`, routing?.url).toString()}
63
+ >
64
+ {styles.badgeLink}
65
+ {currentOrganisation?.label}
66
+ </DataBadgeLink>
67
+ </div>
68
+ )}
69
+ <Heading level={2} appearanceLevel={3}>
70
+ {t("components.filter-by", { type: "organisatie" })}
71
+ </Heading>
72
+ <LinkList>
73
+ {organisations &&
74
+ organisations.map((organisation: any) => (
75
+ <LinkListLink
76
+ className={clsx([
77
+ organisation.uri === routing?.query?.organisation &&
78
+ styles.active,
79
+ ])}
80
+ key={organisation.uri}
81
+ href={new URL(
82
+ `../?organisation=${organisation.uri}`,
83
+ routing?.url,
84
+ ).toString()}
85
+ icon={
86
+ <ListLinkIcon
87
+ isActive={organisation.uri === routing?.query?.organisation}
88
+ />
89
+ }
90
+ >
91
+ {organisation.label}
92
+ </LinkListLink>
93
+ ))}
94
+ </LinkList>
95
+
96
+ {error && (
97
+ <Alert type="error">
98
+ {(error as unknown as any).message ||
99
+ (error as unknown as any).error_msg ||
100
+ `${status}: ${statusText}` ||
101
+ t("components.fuzz-error")}
102
+ </Alert>
103
+ )}
104
+ </div>
105
+ );
106
+ };
107
+
108
+ const TranslatedFilters = (props: PropsWithChildren<FiltersProps>) => {
109
+ return (
110
+ <I18nextProvider i18n={i18n}>
111
+ <Filters {...props} />
112
+ </I18nextProvider>
113
+ );
114
+ };
115
+
116
+ export default TranslatedFilters;
@@ -1,26 +1,26 @@
1
- .filters {
2
- display: flex;
3
- flex-direction: column;
4
- row-gap: var(--rhc-space-200);
5
- }
6
-
7
- .currentFilter {
8
- flex-direction: column;
9
- }
10
-
11
- .active {
12
- font-weight: bold;
13
- }
14
-
15
- .icon {
16
- flex-shrink: 0;
17
- transition: transform 0.2s ease-in-out;
18
- }
19
-
20
- :global(.utrecht-link-list__link:hover) .icon:not(.active) {
21
- transform: translateX(0.125rem);
22
- }
23
-
24
- .icon.active {
25
- transform: scale(1.5);
26
- }
1
+ .filters {
2
+ display: flex;
3
+ flex-direction: column;
4
+ row-gap: var(--rhc-space-200);
5
+ }
6
+
7
+ .currentFilter {
8
+ flex-direction: column;
9
+ }
10
+
11
+ .active {
12
+ font-weight: bold;
13
+ }
14
+
15
+ .icon {
16
+ flex-shrink: 0;
17
+ transition: transform 0.2s ease-in-out;
18
+ }
19
+
20
+ :global(.utrecht-link-list__link:hover) .icon:not(.active) {
21
+ transform: translateX(0.125rem);
22
+ }
23
+
24
+ .icon.active {
25
+ transform: scale(1.5);
26
+ }
@@ -0,0 +1,127 @@
1
+ import type { Meta, StoryObj } from "@storybook/react-vite";
2
+ import Footer from "./Footer";
3
+
4
+ const registersColumn = {
5
+ title: "Registers",
6
+ items: [
7
+ {
8
+ id: "add-apis",
9
+ label: "API's toevoegen",
10
+ href: "/apis/toevoegen",
11
+ },
12
+ {
13
+ id: "add-repositories",
14
+ label: "Repositories toevoegen",
15
+ href: "https://oss.developer.overheid.nl/repositories/toevoegen",
16
+ },
17
+ {
18
+ id: "statistics",
19
+ label: "API-statistieken",
20
+ href: "https://apis.developer.overheid.nl/api-statistieken",
21
+ },
22
+ {
23
+ id: "api-archive",
24
+ label: "Sitearchief API-register",
25
+ href: "https://minbzk.sitearchief.nl/?subsite=devoverheidapis",
26
+ icon: "_external",
27
+ },
28
+ ],
29
+ };
30
+
31
+ const communityColumn = {
32
+ title: "Community",
33
+ items: [
34
+ {
35
+ id: "slack",
36
+ label: "Slack",
37
+ href: "https://codefornl.slack.com/archives/CFV4B3XE2",
38
+ icon: "_external",
39
+ },
40
+ {
41
+ id: "github",
42
+ label: "Github",
43
+ href: "https://github.com/developer-overheid-nl",
44
+ icon: "_external",
45
+ },
46
+ {
47
+ id: "mastodon",
48
+ label: "Mastodon",
49
+ href: "https://social.overheid.nl/@developer",
50
+ icon: "_external",
51
+ },
52
+ ],
53
+ };
54
+
55
+ const overigColumn = {
56
+ title: "Overig",
57
+ items: [
58
+ {
59
+ id: "bijdragen",
60
+ label: "Bijdragen",
61
+ href: "https://developer.overheid.nl/contributing",
62
+ },
63
+ {
64
+ id: "contact",
65
+ label: "Contact",
66
+ href: "https://developer.overheid.nl/contact",
67
+ },
68
+ {
69
+ id: "privacy",
70
+ label: "Privacyverklaring",
71
+ href: "https://developer.overheid.nl/privacy",
72
+ },
73
+ {
74
+ id: "toegankelijkheid",
75
+ label: "Toegankelijkheid",
76
+ href: "https://developer.overheid.nl/toegankelijkheid",
77
+ },
78
+ ],
79
+ };
80
+
81
+ const sponsorsColumn = {
82
+ title: "Mede mogelijk gemaakt door",
83
+ text: "Ministerie van BZK, VNG en Forum Standaardisatie.",
84
+ };
85
+
86
+ /**
87
+ * De Footer toont de voettekst van de website, met optioneel kolommen met
88
+ * tekst en/of links.
89
+ *
90
+ * ## Wijzigingen tov RHC:
91
+ * - `background` staat altijd op `primary-outlined`
92
+ * - `preFooter` staat altijd aan
93
+ * - Een `columns`-prop (titel, tekst en/of links) in plaats van los
94
+ * samengestelde secties
95
+ */
96
+ const meta = {
97
+ title: "Components/Footer",
98
+ component: Footer,
99
+ tags: ["autodocs", "remixed"],
100
+ args: {
101
+ columns: [registersColumn, communityColumn, overigColumn],
102
+ },
103
+ } satisfies Meta<typeof Footer>;
104
+
105
+ export default meta;
106
+
107
+ type Story = StoryObj<typeof meta>;
108
+
109
+ export const Default: Story = {};
110
+
111
+ export const WithSponsorText: Story = {
112
+ args: {
113
+ columns: [sponsorsColumn, registersColumn, communityColumn, overigColumn],
114
+ },
115
+ };
116
+
117
+ export const SingleColumn: Story = {
118
+ args: {
119
+ columns: [registersColumn],
120
+ },
121
+ };
122
+
123
+ export const NoColumns: Story = {
124
+ args: {
125
+ columns: [],
126
+ },
127
+ };
@@ -1,76 +1,81 @@
1
- import {
2
- LinkList,
3
- LinkListLink,
4
- Footer as RHCFooter,
5
- } from "@rijkshuisstijl-community/components-react";
6
- import clsx from "clsx";
7
- import { type PropsWithChildren, useId } from "react";
8
- import Heading from "../heading/Heading";
9
- import Markdown from "../markdown/Markdown";
10
- import {
11
- type NavBarItem,
12
- processNavBarItems,
13
- } from "../topNavigation/TopNavigation";
14
- import styles from "./styles.module.css";
15
-
16
- export interface ColumnProps {
17
- title: string;
18
- items?: NavBarItem[];
19
- text?: string;
20
- }
21
-
22
- export interface FooterProps extends React.HTMLAttributes<HTMLElement> {
23
- className?: string;
24
- columns?: ColumnProps[];
25
- }
26
-
27
- // TODO: refactor icons together with TopNavigation
28
- const FooterColumns = (props: ColumnProps) => {
29
- const id = useId();
30
- const { title, items, text } = props;
31
- const processedItems = items && processNavBarItems(items);
32
-
33
- return (
34
- <nav className={styles.column} aria-describedby={id}>
35
- <Heading level={2} appearanceLevel={5} id={id}>
36
- {title}
37
- </Heading>
38
- {text && <Markdown>{text}</Markdown>}
39
- {processedItems && (
40
- <LinkList>
41
- {processedItems.map((item, index) => (
42
- <LinkListLink
43
- key={item.id || index}
44
- href={item.href}
45
- icon={item.icon}
46
- >
47
- {item.label}
48
- </LinkListLink>
49
- ))}
50
- </LinkList>
51
- )}
52
- </nav>
53
- );
54
- };
55
-
56
- const Footer = (props: PropsWithChildren<FooterProps>) => {
57
- const { className, columns, ...restProps } = props;
58
- const columnsClass = `numColumns${Math.min(Number(columns?.length), 4)}`;
59
-
60
- return (
61
- <RHCFooter
62
- className={clsx(className, styles.footer, styles[columnsClass])}
63
- background="primary-outlined"
64
- preFooter
65
- {...restProps}
66
- >
67
- {columns &&
68
- columns.length > 0 &&
69
- columns.map((column, index) => (
70
- <FooterColumns key={column.title || index} {...column} />
71
- ))}
72
- </RHCFooter>
73
- );
74
- };
75
-
76
- export default Footer;
1
+ import {
2
+ LinkList,
3
+ LinkListLink,
4
+ Footer as RHCFooter,
5
+ } from "@rijkshuisstijl-community/components-react";
6
+ import clsx from "clsx";
7
+ import { type PropsWithChildren, useId } from "react";
8
+ import Heading from "../heading/Heading";
9
+ import Markdown from "../markdown/Markdown";
10
+ import {
11
+ type NavBarItem,
12
+ processNavBarItems,
13
+ } from "../topNavigation/TopNavigation";
14
+ import styles from "./styles.module.css";
15
+
16
+ /** A column in the footer, with a title and optional text and/or links. */
17
+ export interface ColumnProps {
18
+ /** Title of the column, shown as a heading. */
19
+ title: string;
20
+ /** Navigation links, shown as a list below the title. */
21
+ items?: NavBarItem[];
22
+ /** Markdown text, shown below the title (e.g. for sponsor logos). */
23
+ text?: string;
24
+ }
25
+
26
+ export interface FooterProps extends React.HTMLAttributes<HTMLElement> {
27
+ className?: string;
28
+ /** Columns with a title, text and/or links, shown in the footer. */
29
+ columns?: ColumnProps[];
30
+ }
31
+
32
+ // TODO: refactor icons together with TopNavigation
33
+ const FooterColumns = (props: ColumnProps) => {
34
+ const id = useId();
35
+ const { title, items, text } = props;
36
+ const processedItems = items && processNavBarItems(items);
37
+
38
+ return (
39
+ <nav className={styles.column} aria-labelledby={id}>
40
+ <Heading level={2} appearanceLevel={5} id={id}>
41
+ {title}
42
+ </Heading>
43
+ {text && <Markdown>{text}</Markdown>}
44
+ {processedItems && (
45
+ <LinkList>
46
+ {processedItems.map((item, index) => (
47
+ <LinkListLink
48
+ key={item.id || index}
49
+ href={item.href}
50
+ icon={item.icon}
51
+ >
52
+ {item.label}
53
+ </LinkListLink>
54
+ ))}
55
+ </LinkList>
56
+ )}
57
+ </nav>
58
+ );
59
+ };
60
+
61
+ const Footer = (props: PropsWithChildren<FooterProps>) => {
62
+ const { className, columns, ...restProps } = props;
63
+ const columnsClass = `numColumns${Math.min(Number(columns?.length), 4)}`;
64
+
65
+ return (
66
+ <RHCFooter
67
+ className={clsx(className, styles.footer, styles[columnsClass])}
68
+ background="primary-outlined"
69
+ preFooter
70
+ {...restProps}
71
+ >
72
+ {columns &&
73
+ columns.length > 0 &&
74
+ columns.map((column, index) => (
75
+ <FooterColumns key={column.title || index} {...column} />
76
+ ))}
77
+ </RHCFooter>
78
+ );
79
+ };
80
+
81
+ export default Footer;