@developer-overheid-nl/don-register-components 1.3.0 → 1.6.1
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/CHANGELOG.md +170 -118
- package/LICENSE.md +291 -291
- package/README.md +20 -20
- package/package.json +10 -8
- package/src/Introduction.mdx +31 -0
- package/src/alert/Alert.stories.tsx +57 -0
- package/src/alert/Alert.tsx +19 -19
- package/src/alert/styles.module.css +3 -3
- package/src/alignBox/AlignBox.stories.tsx +84 -0
- package/src/alignBox/AlignBox.tsx +114 -114
- package/src/alignBox/styles.module.css +110 -110
- package/src/amountLabel/AmountLabel.stories.tsx +28 -0
- package/src/amountLabel/AmountLabel.tsx +21 -16
- package/src/amountLabel/styles.module.css +11 -11
- package/src/analytics/PiwikPro.tsx +94 -94
- package/src/analytics/index.ts +1 -1
- package/src/article/Article.stories.tsx +53 -0
- package/src/article/Article.tsx +10 -10
- package/src/badgeList/BadgeList.tsx +34 -34
- package/src/badgeList/styles.module.css +37 -37
- package/src/block/Block.stories.tsx +58 -0
- package/src/block/Block.tsx +35 -35
- package/src/block/styles.module.css +29 -29
- package/src/button/Button.stories.tsx +56 -0
- package/src/button/Button.tsx +3 -3
- package/src/button/ButtonAction.stories.tsx +62 -0
- package/src/button/ButtonAction.tsx +51 -0
- package/src/cardAsLink/CardAsLink.stories.tsx +81 -0
- package/src/cardAsLink/CardAsLink.tsx +21 -21
- package/src/cardAsLink/styles.module.css +23 -23
- package/src/cardsList/CardsList.tsx +56 -54
- package/src/cardsList/styles.module.css +18 -19
- package/src/client.ts +7 -7
- package/src/container/Container.stories.tsx +21 -0
- package/src/container/Container.tsx +10 -10
- package/src/container/styles.module.css +28 -28
- package/src/copyButton/CopyButton.stories.tsx +41 -0
- package/src/copyButton/CopyButton.tsx +45 -39
- package/src/copyButton/styles.module.css +13 -13
- package/src/dataBadgeLink/DataBadgeLink.stories.tsx +137 -0
- package/src/dataBadgeLink/DataBadgeLink.tsx +59 -53
- package/src/dataBadgeLink/styles.module.css +89 -89
- package/src/dataSummary/DataSummary.tsx +22 -22
- package/src/dataSummary/DataSummaryItem.tsx +21 -21
- package/src/dataSummary/styles.module.css +75 -75
- package/src/facetFilters/FacetFilters.stories.tsx +93 -0
- package/src/facetFilters/FacetFilters.tsx +424 -367
- package/src/facetFilters/styles.module.css +3 -3
- package/src/fieldset/FieldSet.stories.tsx +45 -0
- package/src/fieldset/FieldSet.tsx +3 -3
- package/src/filters/Filters.stories.tsx +45 -0
- package/src/filters/Filters.tsx +116 -116
- package/src/filters/styles.module.css +26 -26
- package/src/footer/Footer.stories.tsx +127 -0
- package/src/footer/Footer.tsx +81 -76
- package/src/footer/styles.module.css +103 -103
- package/src/formFieldCheckboxGroup/FormFieldCheckboxGroup.stories.tsx +48 -0
- package/src/formFieldCheckboxGroup/FormFieldCheckboxGroup.tsx +16 -16
- package/src/formFieldCheckboxGroup/styles.module.css +5 -5
- package/src/formFieldCheckboxOption/FormFieldCheckboxOption.stories.tsx +61 -0
- package/src/formFieldCheckboxOption/FormFieldCheckboxOption.tsx +26 -26
- package/src/formFieldCheckboxOption/styles.module.css +22 -22
- package/src/formFieldLabel/FormFieldLabel.stories.tsx +21 -0
- package/src/formFieldLabel/FormFieldLabel.tsx +23 -23
- package/src/formFieldRadioGroup/FormFieldRadioGroup.stories.tsx +57 -0
- package/src/formFieldRadioGroup/FormFieldRadioGroup.tsx +13 -13
- package/src/formFieldRadioGroup/styles.module.css +5 -5
- package/src/formFieldRadioOption/FormFieldRadioOption.stories.tsx +48 -0
- package/src/formFieldRadioOption/FormFieldRadioOption.tsx +75 -75
- package/src/formFieldRadioOption/styles.module.css +49 -49
- package/src/formFieldSwitch/FormFieldSwitch.stories.tsx +61 -0
- package/src/formFieldSwitch/FormFieldSwitch.tsx +82 -79
- package/src/formFieldSwitch/styles.module.css +32 -32
- package/src/formFieldTextInput/FormFieldTextInput.stories.tsx +45 -0
- package/src/formFieldTextInput/FormFieldTextInput.tsx +3 -3
- package/src/grid/Grid.stories.tsx +37 -0
- package/src/grid/Grid.tsx +48 -0
- package/src/grid/styles.module.css +24 -0
- package/src/header/Header.stories.tsx +54 -0
- package/src/header/Header.tsx +137 -137
- package/src/header/styles.module.css +71 -71
- package/src/heading/Heading.stories.tsx +60 -0
- package/src/heading/Heading.tsx +15 -15
- package/src/headingGroup/HeadingGroup.stories.tsx +57 -0
- package/src/headingGroup/HeadingGroup.tsx +48 -48
- package/src/headingGroup/styles.module.css +3 -3
- package/src/i18n.ts +24 -25
- package/src/iconBadge/IconBadge.stories.tsx +46 -0
- package/src/iconBadge/IconBadge.tsx +35 -35
- package/src/iconBadge/getAppearance.ts +53 -53
- package/src/iconBadge/styles.module.css +19 -19
- package/src/iconsSprite/Icon.stories.tsx +73 -0
- package/src/iconsSprite/Icon.tsx +17 -17
- package/src/iconsSprite/IconsSprite.tsx +5 -5
- package/src/index.ts +117 -107
- package/src/infoButton/InfoButton.stories.tsx +52 -0
- package/src/infoButton/InfoButton.tsx +45 -45
- package/src/infoButton/styles.module.css +43 -43
- package/src/link/Link.stories.tsx +49 -0
- package/src/link/Link.tsx +10 -10
- package/src/markdown/Markdown.stories.tsx +48 -0
- package/src/markdown/Markdown.tsx +42 -42
- package/src/overlay/Overlay.stories.tsx +38 -0
- package/src/overlay/Overlay.tsx +18 -18
- package/src/overlay/styles.module.css +15 -15
- package/src/pagination/Pagination.stories.tsx +91 -0
- package/src/pagination/Pagination.tsx +267 -267
- package/src/pagination/styles.module.css +28 -28
- package/src/paragraph/Paragraph.stories.tsx +45 -0
- package/src/paragraph/Paragraph.tsx +24 -24
- package/src/paragraph/styles.module.css +6 -6
- package/src/pillBadge/PillBadge.examples.tsx +107 -107
- package/src/pillBadge/PillBadge.stories.tsx +257 -0
- package/src/pillBadge/PillBadge.tsx +60 -51
- package/src/pillBadge/styles.module.css +214 -214
- package/src/readOnlyTextInput/ReadOnlyTextInput.stories.tsx +49 -0
- package/src/readOnlyTextInput/ReadOnlyTextInput.tsx +24 -24
- package/src/readOnlyTextInput/styles.module.css +19 -19
- package/src/scoreBadge/ScoreBadge.stories.tsx +45 -0
- package/src/scoreBadge/ScoreBadge.tsx +135 -133
- package/src/search/Search.stories.tsx +65 -0
- package/src/search/Search.tsx +82 -82
- package/src/search/styles.module.css +40 -39
- package/src/siteLogo/ExampleLogo.stories.tsx +40 -0
- package/src/siteLogo/SiteLogo.stories.tsx +28 -0
- package/src/siteLogo/SiteLogo.tsx +24 -24
- package/src/sortForm/SortForm.stories.tsx +111 -0
- package/src/sortForm/SortForm.tsx +121 -0
- package/src/sortForm/styles.module.css +40 -0
- package/src/switch/Switch.stories.tsx +68 -0
- package/src/switch/Switch.tsx +152 -86
- package/src/switch/styles.module.css +54 -7
- package/src/toolTip/ToolTip.stories.tsx +131 -0
- package/src/toolTip/ToolTip.tsx +55 -55
- package/src/toolTip/styles.module.css +49 -49
- package/src/topNavigation/TopNavigation.stories.tsx +71 -0
- package/src/topNavigation/TopNavigation.tsx +67 -67
- package/src/topNavigation/styles.module.css +54 -54
- package/tsconfig.json +122 -121
|
@@ -1,54 +1,56 @@
|
|
|
1
|
-
import type { CardAsLink } from "@rijkshuisstijl-community/components-react";
|
|
2
|
-
import clsx from "clsx";
|
|
3
|
-
import type { HTMLAttributes, PropsWithChildren, ReactNode } from "react";
|
|
4
|
-
import styles from "./styles.module.css";
|
|
5
|
-
|
|
6
|
-
export interface CardsListProps extends HTMLAttributes<HTMLOListElement> {
|
|
7
|
-
/**
|
|
8
|
-
* Array of items to display in the list.
|
|
9
|
-
* This will encapsulate the `CardAsLink`s in `<li>` elements.
|
|
10
|
-
* If not provided, the component will render its children instead and will not wrap them in `<li>` elements.
|
|
11
|
-
* You can then use the `CardsListItem` component to wrap individual items.
|
|
12
|
-
*
|
|
13
|
-
* @type {?Array<React.JSX.Element | string>}
|
|
14
|
-
*/
|
|
15
|
-
items?: Array<typeof CardAsLink>;
|
|
16
|
-
className?: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const CardsList = (props: PropsWithChildren<CardsListProps>) => {
|
|
20
|
-
const { id, items, className, children } = props;
|
|
21
|
-
|
|
22
|
-
return (
|
|
23
|
-
<ol className={clsx(styles.cardsList, className)} id={id}>
|
|
24
|
-
{items && items.length > 0
|
|
25
|
-
? items.map((item, index, array) => (
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
1
|
+
import type { CardAsLink } from "@rijkshuisstijl-community/components-react";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
import type { HTMLAttributes, PropsWithChildren, ReactNode } from "react";
|
|
4
|
+
import styles from "./styles.module.css";
|
|
5
|
+
|
|
6
|
+
export interface CardsListProps extends HTMLAttributes<HTMLOListElement> {
|
|
7
|
+
/**
|
|
8
|
+
* Array of items to display in the list.
|
|
9
|
+
* This will encapsulate the `CardAsLink`s in `<li>` elements.
|
|
10
|
+
* If not provided, the component will render its children instead and will not wrap them in `<li>` elements.
|
|
11
|
+
* You can then use the `CardsListItem` component to wrap individual items.
|
|
12
|
+
*
|
|
13
|
+
* @type {?Array<React.JSX.Element | string>}
|
|
14
|
+
*/
|
|
15
|
+
items?: Array<typeof CardAsLink>;
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const CardsList = (props: PropsWithChildren<CardsListProps>) => {
|
|
20
|
+
const { id, items, className, children } = props;
|
|
21
|
+
|
|
22
|
+
return (
|
|
23
|
+
<ol className={clsx(styles.cardsList, className)} id={id}>
|
|
24
|
+
{items && items.length > 0
|
|
25
|
+
? items.map((item, index, array) => (
|
|
26
|
+
// biome-ignore-start lint/suspicious/noArrayIndexKey: no stable ID's https://legacy.reactjs.org/docs/lists-and-keys.html#keys
|
|
27
|
+
<CardsListItem
|
|
28
|
+
key={`${id || "don-cards"}_${index}`}
|
|
29
|
+
index={index}
|
|
30
|
+
setsize={array.length}
|
|
31
|
+
>
|
|
32
|
+
{item as unknown as ReactNode}
|
|
33
|
+
</CardsListItem>
|
|
34
|
+
// biome-ignore-end lint/suspicious/noArrayIndexKey: no stable ID's https://legacy.reactjs.org/docs/lists-and-keys.html#keys
|
|
35
|
+
))
|
|
36
|
+
: children}
|
|
37
|
+
</ol>
|
|
38
|
+
);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export interface CardsListItemProps {
|
|
42
|
+
index: number;
|
|
43
|
+
setsize: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const CardsListItem = ({
|
|
47
|
+
index,
|
|
48
|
+
setsize,
|
|
49
|
+
children,
|
|
50
|
+
}: PropsWithChildren<CardsListItemProps>) => (
|
|
51
|
+
<li aria-posinset={index + 1} aria-setsize={setsize}>
|
|
52
|
+
{children}
|
|
53
|
+
</li>
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
export default CardsList;
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
.cardsList {
|
|
2
|
-
--rhc-card-as-link-inline-size: 100%;
|
|
3
|
-
--rhc-card-as-link-active-text-decoration: none;
|
|
4
|
-
display: flex;
|
|
5
|
-
flex-direction: column;
|
|
6
|
-
row-gap: var(--rhc-space-200);
|
|
7
|
-
padding-inline-start: 0;
|
|
8
|
-
list-style-type: none;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
:global(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
1
|
+
.cardsList {
|
|
2
|
+
--rhc-card-as-link-inline-size: 100%;
|
|
3
|
+
--rhc-card-as-link-active-text-decoration: none;
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
row-gap: var(--rhc-space-200);
|
|
7
|
+
padding-inline-start: 0;
|
|
8
|
+
list-style-type: none;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
:global(
|
|
12
|
+
.rhc-card-as-link:hover .rhc-card-as-link__heading.rhc-card-as-link__heading
|
|
13
|
+
) {
|
|
14
|
+
/* TODO: specifity */
|
|
15
|
+
:global(.nl-heading) {
|
|
16
|
+
text-decoration: underline;
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/client.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
// Barrel export for client-side components
|
|
2
|
-
export { default as CopyButton } from "./copyButton/CopyButton";
|
|
3
|
-
export {
|
|
4
|
-
default as FacetFilters,
|
|
5
|
-
type FacetFiltersProps,
|
|
6
|
-
type FilterData,
|
|
7
|
-
} from "./facetFilters/FacetFilters";
|
|
1
|
+
// Barrel export for client-side components
|
|
2
|
+
export { default as CopyButton } from "./copyButton/CopyButton";
|
|
3
|
+
export {
|
|
4
|
+
default as FacetFilters,
|
|
5
|
+
type FacetFiltersProps,
|
|
6
|
+
type FilterData,
|
|
7
|
+
} from "./facetFilters/FacetFilters";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import Container from "./Container";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Container centreert zijn inhoud en beperkt deze tot de maximale
|
|
6
|
+
* paginabreedte, met responsieve inline-padding. Wordt bijvoorbeeld gebruikt
|
|
7
|
+
* om de Header op dezelfde breedte te houden als de rest van de pagina.
|
|
8
|
+
*/
|
|
9
|
+
const meta = {
|
|
10
|
+
title: "Components/Container",
|
|
11
|
+
component: Container,
|
|
12
|
+
tags: ["autodocs", "custom"],
|
|
13
|
+
args: {
|
|
14
|
+
children: "Dit is de inhoud van de container.",
|
|
15
|
+
},
|
|
16
|
+
} satisfies Meta<typeof Container>;
|
|
17
|
+
|
|
18
|
+
export default meta;
|
|
19
|
+
type Story = StoryObj<typeof meta>;
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import styles from "./styles.module.css";
|
|
2
|
-
|
|
3
|
-
export default function Container(props: React.HTMLProps<HTMLDivElement>) {
|
|
4
|
-
const { children, className, ...restProps } = props || {};
|
|
5
|
-
return (
|
|
6
|
-
<div className={`${styles.container} ${className || ""}`} {...restProps}>
|
|
7
|
-
{children}
|
|
8
|
-
</div>
|
|
9
|
-
);
|
|
10
|
-
}
|
|
1
|
+
import styles from "./styles.module.css";
|
|
2
|
+
|
|
3
|
+
export default function Container(props: React.HTMLProps<HTMLDivElement>) {
|
|
4
|
+
const { children, className, ...restProps } = props || {};
|
|
5
|
+
return (
|
|
6
|
+
<div className={`${styles.container} ${className || ""}`} {...restProps}>
|
|
7
|
+
{children}
|
|
8
|
+
</div>
|
|
9
|
+
);
|
|
10
|
+
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
.container {
|
|
2
|
-
display: flex;
|
|
3
|
-
align-items: center;
|
|
4
|
-
justify-content: center;
|
|
5
|
-
inline-size: var(--rhc-nav-bar-container-inline-size);
|
|
6
|
-
|
|
7
|
-
> * {
|
|
8
|
-
flex: 1;
|
|
9
|
-
max-inline-size: var(--rhc-nav-bar-max-inline-size);
|
|
10
|
-
padding-inline-start: var(--rhc-nav-bar-link-padding-inline-start);
|
|
11
|
-
padding-inline-end: var(--rhc-nav-bar-link-padding-inline-end);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
@media (--xs-and-below-viewport) {
|
|
16
|
-
.container {
|
|
17
|
-
> * {
|
|
18
|
-
padding-inline-start: calc(
|
|
19
|
-
var(--rhc-nav-bar-link-padding-inline-start) *
|
|
20
|
-
0.5
|
|
21
|
-
);
|
|
22
|
-
padding-inline-end: calc(
|
|
23
|
-
var(--rhc-nav-bar-link-padding-inline-end) *
|
|
24
|
-
0.5
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
1
|
+
.container {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
inline-size: var(--rhc-nav-bar-container-inline-size);
|
|
6
|
+
|
|
7
|
+
> * {
|
|
8
|
+
flex: 1;
|
|
9
|
+
max-inline-size: var(--rhc-nav-bar-max-inline-size);
|
|
10
|
+
padding-inline-start: var(--rhc-nav-bar-link-padding-inline-start);
|
|
11
|
+
padding-inline-end: var(--rhc-nav-bar-link-padding-inline-end);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@media (--xs-and-below-viewport) {
|
|
16
|
+
.container {
|
|
17
|
+
> * {
|
|
18
|
+
padding-inline-start: calc(
|
|
19
|
+
var(--rhc-nav-bar-link-padding-inline-start) *
|
|
20
|
+
0.5
|
|
21
|
+
);
|
|
22
|
+
padding-inline-end: calc(
|
|
23
|
+
var(--rhc-nav-bar-link-padding-inline-end) *
|
|
24
|
+
0.5
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import { expect, fn } from "storybook/test";
|
|
3
|
+
|
|
4
|
+
import CopyButton from "./CopyButton";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* CopyButton kopieert de opgegeven `text` naar het klembord via de browser
|
|
8
|
+
* Clipboard API wanneer erop geklikt wordt. Rendert niets als er geen tekst
|
|
9
|
+
* is opgegeven.
|
|
10
|
+
*/
|
|
11
|
+
const meta: Meta<typeof CopyButton> = {
|
|
12
|
+
title: "Components/CopyButton",
|
|
13
|
+
component: CopyButton,
|
|
14
|
+
tags: ["autodocs", "beta", "custom"],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default meta;
|
|
18
|
+
|
|
19
|
+
type Story = StoryObj<typeof meta>;
|
|
20
|
+
|
|
21
|
+
export const Default: Story = {
|
|
22
|
+
args: {
|
|
23
|
+
text: "This text will be copied!",
|
|
24
|
+
},
|
|
25
|
+
play: async ({ canvas, userEvent, args }) => {
|
|
26
|
+
const cpButton = canvas.getByTitle("Kopieer naar klembord");
|
|
27
|
+
|
|
28
|
+
const writeTextMock = fn();
|
|
29
|
+
Object.defineProperty(navigator, "clipboard", {
|
|
30
|
+
value: { writeText: writeTextMock },
|
|
31
|
+
writable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
await userEvent.click(cpButton);
|
|
36
|
+
|
|
37
|
+
await expect(writeTextMock).toHaveBeenCalledWith(args.text);
|
|
38
|
+
|
|
39
|
+
writeTextMock.mockRestore();
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -1,39 +1,45 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
|
|
3
|
-
import { SecondaryActionButton } from "@rijkshuisstijl-community/components-react";
|
|
4
|
-
import clsx from "clsx";
|
|
5
|
-
import Icon from "../iconsSprite/Icon";
|
|
6
|
-
import styles from "./styles.module.css";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { SecondaryActionButton } from "@rijkshuisstijl-community/components-react";
|
|
4
|
+
import clsx from "clsx";
|
|
5
|
+
import Icon from "../iconsSprite/Icon";
|
|
6
|
+
import styles from "./styles.module.css";
|
|
7
|
+
|
|
8
|
+
/** A button that copies the given `text` to the clipboard when clicked. */
|
|
9
|
+
interface CopyButtonProps
|
|
10
|
+
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
11
|
+
/** The text to copy to the clipboard. Renders nothing if not set. */
|
|
12
|
+
text?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const CopyButton = ({ text, className, ...restProps }: CopyButtonProps) => {
|
|
16
|
+
const handleCopy = async () => {
|
|
17
|
+
if ("clipboard" in navigator) {
|
|
18
|
+
await navigator.clipboard.writeText(
|
|
19
|
+
text || "Sorry, no text to copy was set...",
|
|
20
|
+
);
|
|
21
|
+
} else {
|
|
22
|
+
console.warn("Clipboard API not supported");
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
text && (
|
|
28
|
+
<SecondaryActionButton
|
|
29
|
+
className={clsx([className, styles.button])}
|
|
30
|
+
onClick={handleCopy}
|
|
31
|
+
title="Kopieer naar klembord"
|
|
32
|
+
aria-label="Kopieer naar klembord"
|
|
33
|
+
{...restProps}
|
|
34
|
+
>
|
|
35
|
+
<Icon
|
|
36
|
+
className={styles.icon}
|
|
37
|
+
name="kopieer-inline"
|
|
38
|
+
aria-hidden="true"
|
|
39
|
+
/>
|
|
40
|
+
</SecondaryActionButton>
|
|
41
|
+
)
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default CopyButton;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
.button {
|
|
2
|
-
--utrecht-button-padding-block-end: 0.125rem;
|
|
3
|
-
--utrecht-button-padding-block-start: 0.125rem;
|
|
4
|
-
--utrecht-button-padding-inline-end: 0.125rem;
|
|
5
|
-
--utrecht-button-padding-inline-start: 0.125rem;
|
|
6
|
-
--utrecht-button-min-block-size: 36px;
|
|
7
|
-
--utrecht-button-min-inline-size: 36px;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.icon {
|
|
11
|
-
width: 1.5rem;
|
|
12
|
-
height: 1.5rem;
|
|
13
|
-
}
|
|
1
|
+
.button {
|
|
2
|
+
--utrecht-button-padding-block-end: 0.125rem;
|
|
3
|
+
--utrecht-button-padding-block-start: 0.125rem;
|
|
4
|
+
--utrecht-button-padding-inline-end: 0.125rem;
|
|
5
|
+
--utrecht-button-padding-inline-start: 0.125rem;
|
|
6
|
+
--utrecht-button-min-block-size: 36px;
|
|
7
|
+
--utrecht-button-min-inline-size: 36px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.icon {
|
|
11
|
+
width: 1.5rem;
|
|
12
|
+
height: 1.5rem;
|
|
13
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react-vite";
|
|
2
|
+
import Block from "../block/Block";
|
|
3
|
+
import DataBadgeLink from "./DataBadgeLink";
|
|
4
|
+
|
|
5
|
+
const CrossIcon = () => (
|
|
6
|
+
<svg
|
|
7
|
+
aria-hidden="true"
|
|
8
|
+
width="12"
|
|
9
|
+
height="12"
|
|
10
|
+
viewBox="0 0 12 12"
|
|
11
|
+
fill="none"
|
|
12
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
13
|
+
>
|
|
14
|
+
<path
|
|
15
|
+
d="M1 1L11 11M11 1L1 11"
|
|
16
|
+
stroke="currentColor"
|
|
17
|
+
strokeWidth="1.5"
|
|
18
|
+
strokeLinecap="round"
|
|
19
|
+
/>
|
|
20
|
+
</svg>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* DataBadgeLink toont een badge die als link fungeert, bijvoorbeeld voor een
|
|
25
|
+
* downloadlink of een actief filter.
|
|
26
|
+
*
|
|
27
|
+
* ## Wijzigingen tov RHC:
|
|
28
|
+
* - Gebruikt RHC's `DataBadgeButton`, maar rendert de inhoud als `<a>` in
|
|
29
|
+
* plaats van als knop; de toggle-knop-semantiek (`pressed`/`aria-pressed`)
|
|
30
|
+
* is daarom verwijderd.
|
|
31
|
+
* - Voegt een `appearance`-prop toe (`primary`, `outlined`, `subtle`, `link`).
|
|
32
|
+
*/
|
|
33
|
+
const meta = {
|
|
34
|
+
title: "Components/DataBadgeLink",
|
|
35
|
+
component: DataBadgeLink,
|
|
36
|
+
tags: ["autodocs", "remixed"],
|
|
37
|
+
argTypes: {
|
|
38
|
+
appearance: {
|
|
39
|
+
control: "select",
|
|
40
|
+
options: ["primary", "outlined", "subtle", "link"],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
args: {
|
|
44
|
+
href: "#",
|
|
45
|
+
appearance: "primary",
|
|
46
|
+
children: "OAS 3.1 (.json)",
|
|
47
|
+
},
|
|
48
|
+
decorators: [
|
|
49
|
+
(Story) => (
|
|
50
|
+
<Block layout="flex-row" appearance="clear">
|
|
51
|
+
<Story />
|
|
52
|
+
</Block>
|
|
53
|
+
),
|
|
54
|
+
],
|
|
55
|
+
} satisfies Meta<typeof DataBadgeLink>;
|
|
56
|
+
|
|
57
|
+
export default meta;
|
|
58
|
+
|
|
59
|
+
type Story = StoryObj<typeof meta>;
|
|
60
|
+
|
|
61
|
+
export const Primary: Story = {};
|
|
62
|
+
|
|
63
|
+
export const Outlined: Story = {
|
|
64
|
+
args: {
|
|
65
|
+
appearance: "outlined",
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export const Subtle: Story = {
|
|
70
|
+
args: {
|
|
71
|
+
appearance: "subtle",
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const LinkAppearance: Story = {
|
|
76
|
+
name: "Link",
|
|
77
|
+
args: {
|
|
78
|
+
appearance: "link",
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const WithIcon: Story = {
|
|
83
|
+
args: {
|
|
84
|
+
appearance: "subtle",
|
|
85
|
+
icon: <CrossIcon />,
|
|
86
|
+
children: "Kadaster",
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export const WithHelperText: Story = {
|
|
91
|
+
args: {
|
|
92
|
+
appearance: "subtle",
|
|
93
|
+
icon: <CrossIcon />,
|
|
94
|
+
helperText: "Verwijder filter",
|
|
95
|
+
children: "Kadaster",
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export const AllAppearances: Story = {
|
|
100
|
+
args: {
|
|
101
|
+
children: "",
|
|
102
|
+
},
|
|
103
|
+
render: () => (
|
|
104
|
+
<>
|
|
105
|
+
<DataBadgeLink href="#" appearance="primary">
|
|
106
|
+
Primary
|
|
107
|
+
</DataBadgeLink>
|
|
108
|
+
<DataBadgeLink href="#" appearance="outlined">
|
|
109
|
+
Outlined
|
|
110
|
+
</DataBadgeLink>
|
|
111
|
+
<DataBadgeLink href="#" appearance="subtle">
|
|
112
|
+
Subtle
|
|
113
|
+
</DataBadgeLink>
|
|
114
|
+
<DataBadgeLink href="#" appearance="link">
|
|
115
|
+
Link
|
|
116
|
+
</DataBadgeLink>
|
|
117
|
+
</>
|
|
118
|
+
),
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export const FilterExample: Story = {
|
|
122
|
+
name: "Actief filter (voorbeeld)",
|
|
123
|
+
args: {
|
|
124
|
+
appearance: "subtle",
|
|
125
|
+
icon: <CrossIcon />,
|
|
126
|
+
helperText: "Verwijder filter",
|
|
127
|
+
role: "menuitem",
|
|
128
|
+
children: "Geonovum",
|
|
129
|
+
},
|
|
130
|
+
render: (args) => (
|
|
131
|
+
<div role="menu" aria-label="Actieve filters">
|
|
132
|
+
<div role="none">
|
|
133
|
+
<DataBadgeLink {...args} />
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
),
|
|
137
|
+
};
|
|
@@ -1,53 +1,59 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DataBadgeButton,
|
|
3
|
-
type DataBadgeButtonProps,
|
|
4
|
-
} from "@rijkshuisstijl-community/components-react";
|
|
5
|
-
import clsx from "clsx";
|
|
6
|
-
import styles from "./styles.module.css";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
1
|
+
import {
|
|
2
|
+
DataBadgeButton,
|
|
3
|
+
type DataBadgeButtonProps,
|
|
4
|
+
} from "@rijkshuisstijl-community/components-react";
|
|
5
|
+
import clsx from "clsx";
|
|
6
|
+
import styles from "./styles.module.css";
|
|
7
|
+
|
|
8
|
+
/** A data badge that acts as a link instead of a toggle button. */
|
|
9
|
+
export interface DataBadgeLinkProps
|
|
10
|
+
extends Omit<DataBadgeButtonProps, "aria-pressed" | "pressed"> {
|
|
11
|
+
/** The link target. */
|
|
12
|
+
href: string;
|
|
13
|
+
/** The badge's content. */
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
/** The anchor's `target` attribute. */
|
|
16
|
+
target?: React.HTMLAttributeAnchorTarget;
|
|
17
|
+
/** The anchor's `rel` attribute. */
|
|
18
|
+
rel?: string;
|
|
19
|
+
className?: string;
|
|
20
|
+
role?: string;
|
|
21
|
+
/** Visual style of the badge. */
|
|
22
|
+
appearance?: "primary" | "outlined" | "subtle" | "link";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const DataBadgeLink = (props: DataBadgeLinkProps) => {
|
|
26
|
+
const {
|
|
27
|
+
href,
|
|
28
|
+
target,
|
|
29
|
+
rel,
|
|
30
|
+
children,
|
|
31
|
+
className,
|
|
32
|
+
role,
|
|
33
|
+
tabIndex = undefined,
|
|
34
|
+
appearance = "primary",
|
|
35
|
+
...restProps
|
|
36
|
+
} = props;
|
|
37
|
+
return (
|
|
38
|
+
<DataBadgeButton
|
|
39
|
+
className={clsx(className, styles.donDataBadge, styles[appearance])}
|
|
40
|
+
/* biome-ignore lint/a11y/useValidAriaValues: {null} is needed to remove it */
|
|
41
|
+
aria-pressed={undefined}
|
|
42
|
+
role={role}
|
|
43
|
+
/* RHC DataBadgeButton had a tabindex=0 on the span, and a focus ring, but no interaction */
|
|
44
|
+
tabIndex={tabIndex}
|
|
45
|
+
{...restProps}
|
|
46
|
+
>
|
|
47
|
+
<a
|
|
48
|
+
className={clsx(styles.badgeLink)}
|
|
49
|
+
href={href}
|
|
50
|
+
target={target}
|
|
51
|
+
rel={rel}
|
|
52
|
+
>
|
|
53
|
+
{children}
|
|
54
|
+
</a>
|
|
55
|
+
</DataBadgeButton>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default DataBadgeLink;
|