@amsterdam/design-system-react 2.2.0 → 3.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.
- package/README.md +1 -1
- package/dist/Accordion/Accordion.js +1 -1
- package/dist/Accordion/AccordionContext.d.ts +1 -2
- package/dist/Accordion/AccordionContext.js +3 -4
- package/dist/Accordion/AccordionSection.js +1 -1
- package/dist/Badge/Badge.d.ts +5 -0
- package/dist/Badge/Badge.js +3 -2
- package/dist/Checkbox/Checkbox.d.ts +5 -4
- package/dist/Column/Column.d.ts +1 -1
- package/dist/Grid/Grid.d.ts +1 -1
- package/dist/Grid/GridCell.d.ts +1 -1
- package/dist/ImageSlider/ImageSlider.d.ts +3 -22
- package/dist/ImageSlider/ImageSlider.js +31 -86
- package/dist/ImageSlider/ImageSliderControl.d.ts +2 -0
- package/dist/ImageSlider/ImageSliderControl.js +5 -0
- package/dist/ImageSlider/ImageSliderThumbnails.d.ts +5 -6
- package/dist/ImageSlider/ImageSliderThumbnails.js +7 -12
- package/dist/ImageSlider/index.d.ts +0 -1
- package/dist/ImageSlider/utils/debounce.d.ts +1 -0
- package/dist/ImageSlider/utils/debounce.js +8 -0
- package/dist/ImageSlider/utils/index.d.ts +4 -0
- package/dist/ImageSlider/utils/index.js +4 -0
- package/dist/ImageSlider/utils/scrollToCurrentSlideOnResize.d.ts +7 -0
- package/dist/ImageSlider/utils/scrollToCurrentSlideOnResize.js +11 -0
- package/dist/ImageSlider/utils/scrollToSlide.d.ts +2 -0
- package/dist/ImageSlider/utils/scrollToSlide.js +9 -0
- package/dist/ImageSlider/utils/setCurrentSlideIdToVisibleSlide.d.ts +8 -0
- package/dist/ImageSlider/utils/setCurrentSlideIdToVisibleSlide.js +10 -0
- package/dist/Logo/Logo.d.ts +10 -5
- package/dist/Logo/Logo.js +17 -9
- package/dist/PageFooter/PageFooter.d.ts +4 -1
- package/dist/PageFooter/PageFooterMenu.d.ts +27 -2
- package/dist/PageFooter/PageFooterMenu.js +6 -2
- package/dist/PageHeader/PageHeader.d.ts +19 -5
- package/dist/PageHeader/PageHeader.js +3 -2
- package/dist/PageHeader/PageHeaderGridCellNarrowWindowOnly.js +2 -1
- package/dist/Paragraph/Paragraph.d.ts +2 -2
- package/dist/Paragraph/Paragraph.js +8 -1
- package/dist/ProgressList/ProgressList.d.ts +43 -0
- package/dist/ProgressList/ProgressList.js +19 -0
- package/dist/ProgressList/ProgressListContext.d.ts +10 -0
- package/dist/ProgressList/ProgressListContext.js +11 -0
- package/dist/ProgressList/ProgressListStep.d.ts +23 -0
- package/dist/ProgressList/ProgressListStep.js +12 -0
- package/dist/ProgressList/ProgressListSubstep.d.ts +16 -0
- package/dist/ProgressList/ProgressListSubstep.js +7 -0
- package/dist/ProgressList/ProgressListSubsteps.d.ts +9 -0
- package/dist/ProgressList/ProgressListSubsteps.js +5 -0
- package/dist/ProgressList/index.d.ts +9 -0
- package/dist/ProgressList/index.js +5 -0
- package/dist/Radio/Radio.d.ts +5 -4
- package/dist/Row/Row.d.ts +1 -1
- package/dist/Spotlight/Spotlight.d.ts +1 -1
- package/dist/common/useIsAfterBreakpoint.d.ts +4 -4
- package/dist/common/useIsAfterBreakpoint.js +12 -13
- package/dist/index.cjs.js +734 -663
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +150 -77
- package/dist/index.esm.js +736 -666
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +13 -18
- package/dist/ImageSlider/ImageSliderContext.d.ts +0 -13
- package/dist/ImageSlider/ImageSliderContext.js +0 -14
- package/dist/ImageSlider/ImageSliderControls.d.ts +0 -17
- package/dist/ImageSlider/ImageSliderControls.js +0 -13
- package/dist/ImageSlider/ImageSliderItem.d.ts +0 -15
- package/dist/ImageSlider/ImageSliderItem.js +0 -11
- package/dist/ImageSlider/ImageSliderScroller.d.ts +0 -9
- package/dist/ImageSlider/ImageSliderScroller.js +0 -5
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Amsterdam Design System: React components
|
|
4
4
|
|
|
5
5
|
This package provides all React components from the [Amsterdam Design System](https://designsystem.amsterdam).
|
|
6
|
-
Use it to compose pages in your
|
|
6
|
+
Use it to compose pages in your websites.
|
|
7
7
|
|
|
8
8
|
## Introduction
|
|
9
9
|
|
|
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
3
|
import { forwardRef, useImperativeHandle, useRef } from 'react';
|
|
4
4
|
import { useKeyboardFocus } from '../common/useKeyboardFocus';
|
|
5
|
-
import AccordionContext from './AccordionContext';
|
|
5
|
+
import { AccordionContext } from './AccordionContext';
|
|
6
6
|
import { AccordionSection } from './AccordionSection';
|
|
7
7
|
const AccordionRoot = forwardRef(({ children, className, headingLevel, sectionAs = 'section' }, ref) => {
|
|
8
8
|
const innerRef = useRef(null);
|
|
@@ -7,5 +7,4 @@ export type AccordionContextValue = {
|
|
|
7
7
|
headingLevel: AccordionProps['headingLevel'];
|
|
8
8
|
sectionAs?: AccordionProps['sectionAs'];
|
|
9
9
|
};
|
|
10
|
-
declare const AccordionContext: import("react").Context<AccordionContextValue>;
|
|
11
|
-
export default AccordionContext;
|
|
10
|
+
export declare const AccordionContext: import("react").Context<AccordionContextValue>;
|
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { createContext } from 'react';
|
|
6
6
|
const defaultValues = {
|
|
7
|
-
//
|
|
8
|
-
//
|
|
7
|
+
// Default value for type safety.
|
|
8
|
+
// The actual value is always provided via Accordion’s required headingLevel prop.
|
|
9
9
|
headingLevel: 2,
|
|
10
10
|
};
|
|
11
|
-
const AccordionContext = createContext(defaultValues);
|
|
12
|
-
export default AccordionContext;
|
|
11
|
+
export const AccordionContext = createContext(defaultValues);
|
|
@@ -4,7 +4,7 @@ import { clsx } from 'clsx';
|
|
|
4
4
|
import { forwardRef, useContext, useId, useState } from 'react';
|
|
5
5
|
import { Heading } from '../Heading';
|
|
6
6
|
import { Icon } from '../Icon/Icon';
|
|
7
|
-
import AccordionContext from './AccordionContext';
|
|
7
|
+
import { AccordionContext } from './AccordionContext';
|
|
8
8
|
// The 'ams-accordion__header' class is @deprecated and will be removed in a future release.
|
|
9
9
|
export const AccordionSection = forwardRef(({ children, className, expanded = false, label, ...restProps }, ref) => {
|
|
10
10
|
const { headingLevel, sectionAs } = useContext(AccordionContext);
|
package/dist/Badge/Badge.d.ts
CHANGED
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
* Copyright Gemeente Amsterdam
|
|
4
4
|
*/
|
|
5
5
|
import type { HTMLAttributes } from 'react';
|
|
6
|
+
import type { IconProps } from '../Icon';
|
|
6
7
|
export declare const badgeColors: readonly ["azure", "lime", "magenta", "orange", "purple", "red", "yellow"];
|
|
7
8
|
type BadgeColor = (typeof badgeColors)[number];
|
|
8
9
|
export type BadgeProps = {
|
|
9
10
|
/** The background colour. */
|
|
10
11
|
color?: BadgeColor;
|
|
12
|
+
/** The icon to show before the badge text. */
|
|
13
|
+
icon?: IconProps['svg'];
|
|
11
14
|
/** The text content. */
|
|
12
15
|
label: string | number;
|
|
13
16
|
} & HTMLAttributes<HTMLElement>;
|
|
@@ -17,6 +20,8 @@ export type BadgeProps = {
|
|
|
17
20
|
export declare const Badge: import("react").ForwardRefExoticComponent<{
|
|
18
21
|
/** The background colour. */
|
|
19
22
|
color?: BadgeColor;
|
|
23
|
+
/** The icon to show before the badge text. */
|
|
24
|
+
icon?: IconProps["svg"];
|
|
20
25
|
/** The text content. */
|
|
21
26
|
label: string | number;
|
|
22
27
|
} & HTMLAttributes<HTMLElement> & import("react").RefAttributes<HTMLElement>>;
|
package/dist/Badge/Badge.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
3
|
import { forwardRef } from 'react';
|
|
4
|
+
import { Icon } from '../Icon';
|
|
4
5
|
export const badgeColors = ['azure', 'lime', 'magenta', 'orange', 'purple', 'red', 'yellow'];
|
|
5
6
|
/**
|
|
6
7
|
* @see {@link https://designsystem.amsterdam/?path=/docs/components-feedback-badge--docs Badge docs at Amsterdam Design System}
|
|
7
8
|
*/
|
|
8
|
-
export const Badge = forwardRef(({ className, color, label, ...restProps }, ref) => (
|
|
9
|
+
export const Badge = forwardRef(({ className, color, icon, label, ...restProps }, ref) => (_jsxs("span", { ...restProps, className: clsx('ams-badge', color && `ams-badge--${color}`, className), ref: ref, children: [icon && _jsx(Icon, { svg: icon }), label] })));
|
|
9
10
|
Badge.displayName = 'Badge';
|
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
* @license EUPL-1.2+
|
|
3
3
|
* Copyright Gemeente Amsterdam
|
|
4
4
|
*/
|
|
5
|
-
import type { InputHTMLAttributes, PropsWithChildren
|
|
5
|
+
import type { InputHTMLAttributes, PropsWithChildren } from 'react';
|
|
6
|
+
import type { IconProps } from '../Icon';
|
|
6
7
|
export type CheckboxProps = {
|
|
7
8
|
/**
|
|
8
9
|
* An icon to display instead of the default icon.
|
|
9
10
|
* @default CheckboxIcon
|
|
10
11
|
*/
|
|
11
|
-
icon?:
|
|
12
|
+
icon?: IconProps['svg'];
|
|
12
13
|
/** Allows being neither checked nor unchecked. */
|
|
13
14
|
indeterminate?: boolean;
|
|
14
15
|
/** Whether the value fails a validation rule. */
|
|
@@ -22,11 +23,11 @@ export declare const Checkbox: import("react").ForwardRefExoticComponent<{
|
|
|
22
23
|
* An icon to display instead of the default icon.
|
|
23
24
|
* @default CheckboxIcon
|
|
24
25
|
*/
|
|
25
|
-
icon?:
|
|
26
|
+
icon?: IconProps["svg"];
|
|
26
27
|
/** Allows being neither checked nor unchecked. */
|
|
27
28
|
indeterminate?: boolean;
|
|
28
29
|
/** Whether the value fails a validation rule. */
|
|
29
30
|
invalid?: boolean;
|
|
30
31
|
} & Omit<InputHTMLAttributes<HTMLInputElement>, "aria-invalid" | "type"> & {
|
|
31
|
-
children?: ReactNode | undefined;
|
|
32
|
+
children?: import("react").ReactNode | undefined;
|
|
32
33
|
} & import("react").RefAttributes<HTMLInputElement>>;
|
package/dist/Column/Column.d.ts
CHANGED
|
@@ -56,5 +56,5 @@ export declare const Column: import("react").ForwardRefExoticComponent<{
|
|
|
56
56
|
gap?: ColumnGap;
|
|
57
57
|
} & HTMLAttributes<HTMLElement> & {
|
|
58
58
|
children?: import("react").ReactNode | undefined;
|
|
59
|
-
} & import("react").RefAttributes<
|
|
59
|
+
} & import("react").RefAttributes<any>>;
|
|
60
60
|
export {};
|
package/dist/Grid/Grid.d.ts
CHANGED
|
@@ -38,6 +38,6 @@ export type GridProps = {
|
|
|
38
38
|
* @see {@link https://designsystem.amsterdam/?path=/docs/components-layout-grid--docs Grid docs at Amsterdam Design System}
|
|
39
39
|
*/
|
|
40
40
|
export declare const Grid: import("react").ForwardRefExoticComponent<GridProps & import("react").RefAttributes<any>> & {
|
|
41
|
-
Cell: import("react").ForwardRefExoticComponent<import("./GridCell").GridCellProps & import("react").RefAttributes<
|
|
41
|
+
Cell: import("react").ForwardRefExoticComponent<import("./GridCell").GridCellProps & import("react").RefAttributes<any>>;
|
|
42
42
|
};
|
|
43
43
|
export {};
|
package/dist/Grid/GridCell.d.ts
CHANGED
|
@@ -21,5 +21,5 @@ export type GridCellProps = {
|
|
|
21
21
|
/** The HTML tag to use. */
|
|
22
22
|
as?: GridCellTag;
|
|
23
23
|
} & PropsWithChildren<HTMLAttributes<HTMLElement>> & (GridCellSpanAllProp | GridCellSpanAndStartProps);
|
|
24
|
-
export declare const GridCell: import("react").ForwardRefExoticComponent<GridCellProps & import("react").RefAttributes<
|
|
24
|
+
export declare const GridCell: import("react").ForwardRefExoticComponent<GridCellProps & import("react").RefAttributes<any>>;
|
|
25
25
|
export {};
|
|
@@ -4,31 +4,18 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { HTMLAttributes } from 'react';
|
|
6
6
|
import type { ImageProps } from '../Image/Image';
|
|
7
|
-
export type ImageSliderImageProps = ImageProps;
|
|
8
7
|
export type ImageSliderProps = {
|
|
9
8
|
/** Display buttons to navigate to the previous or next image. */
|
|
10
9
|
controls?: boolean;
|
|
11
10
|
/** Label for the image if you need to translate the alt text. */
|
|
12
11
|
imageLabel?: string;
|
|
13
12
|
/** The set of images to display. */
|
|
14
|
-
images:
|
|
13
|
+
images: ImageProps[];
|
|
15
14
|
/** The label for the ‘next’ button */
|
|
16
15
|
nextLabel?: string;
|
|
17
16
|
/** The label for the ‘previous’ button */
|
|
18
17
|
previousLabel?: string;
|
|
19
18
|
} & HTMLAttributes<HTMLDivElement>;
|
|
20
|
-
export declare const ImageSliderRoot: import("react").ForwardRefExoticComponent<{
|
|
21
|
-
/** Display buttons to navigate to the previous or next image. */
|
|
22
|
-
controls?: boolean;
|
|
23
|
-
/** Label for the image if you need to translate the alt text. */
|
|
24
|
-
imageLabel?: string;
|
|
25
|
-
/** The set of images to display. */
|
|
26
|
-
images: ImageSliderImageProps[];
|
|
27
|
-
/** The label for the ‘next’ button */
|
|
28
|
-
nextLabel?: string;
|
|
29
|
-
/** The label for the ‘previous’ button */
|
|
30
|
-
previousLabel?: string;
|
|
31
|
-
} & HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
|
|
32
19
|
/**
|
|
33
20
|
* @see {@link https://designsystem.amsterdam/?path=/docs/components-media-image-slider--docs Image Slider docs at Amsterdam Design System}
|
|
34
21
|
*/
|
|
@@ -38,15 +25,9 @@ export declare const ImageSlider: import("react").ForwardRefExoticComponent<{
|
|
|
38
25
|
/** Label for the image if you need to translate the alt text. */
|
|
39
26
|
imageLabel?: string;
|
|
40
27
|
/** The set of images to display. */
|
|
41
|
-
images:
|
|
28
|
+
images: ImageProps[];
|
|
42
29
|
/** The label for the ‘next’ button */
|
|
43
30
|
nextLabel?: string;
|
|
44
31
|
/** The label for the ‘previous’ button */
|
|
45
32
|
previousLabel?: string;
|
|
46
|
-
} & HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement
|
|
47
|
-
Item: import("react").ForwardRefExoticComponent<{
|
|
48
|
-
slideId: number;
|
|
49
|
-
} & HTMLAttributes<HTMLDivElement> & {
|
|
50
|
-
children?: import("react").ReactNode | undefined;
|
|
51
|
-
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
52
|
-
};
|
|
33
|
+
} & HTMLAttributes<HTMLDivElement> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -1,97 +1,42 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { ChevronBackwardIcon, ChevronForwardIcon } from '@amsterdam/design-system-react-icons';
|
|
2
3
|
import { clsx } from 'clsx';
|
|
3
|
-
import { forwardRef,
|
|
4
|
+
import { forwardRef, useEffect, useRef, useState } from 'react';
|
|
4
5
|
import { Image } from '../Image/Image';
|
|
5
|
-
import {
|
|
6
|
-
import { ImageSliderControls } from './ImageSliderControls';
|
|
7
|
-
import { ImageSliderItem } from './ImageSliderItem';
|
|
8
|
-
import { ImageSliderScroller } from './ImageSliderScroller';
|
|
6
|
+
import { ImageSliderControl } from './ImageSliderControl';
|
|
9
7
|
import { ImageSliderThumbnails } from './ImageSliderThumbnails';
|
|
10
|
-
|
|
8
|
+
import { debounce, scrollToCurrentSlideOnResize, scrollToSlide, setCurrentSlideIdToVisibleSlide } from './utils';
|
|
9
|
+
/**
|
|
10
|
+
* @see {@link https://designsystem.amsterdam/?path=/docs/components-media-image-slider--docs Image Slider docs at Amsterdam Design System}
|
|
11
|
+
*/
|
|
12
|
+
export const ImageSlider = forwardRef(({ className, controls, imageLabel = 'Afbeelding', images, nextLabel = 'Volgende', previousLabel = 'Vorige', ...restProps }, ref) => {
|
|
13
|
+
if (images.length === 0)
|
|
14
|
+
return null;
|
|
11
15
|
const [currentSlideId, setCurrentSlideId] = useState(0);
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const observerRef = useRef(null);
|
|
16
|
-
const inView = useCallback((observations) => {
|
|
17
|
-
const images = Array.from(targetRef.current?.children || []);
|
|
18
|
-
observations.forEach((observation) => {
|
|
19
|
-
if (observation.isIntersecting) {
|
|
20
|
-
setCurrentSlideId(images.indexOf(observation.target));
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
}, []);
|
|
24
|
-
const observerOptions = useMemo(() => ({
|
|
25
|
-
root: targetRef.current,
|
|
26
|
-
threshold: 0.6,
|
|
27
|
-
}), []);
|
|
28
|
-
const updateControls = useCallback(() => {
|
|
29
|
-
const sliderScrollerElement = targetRef.current;
|
|
30
|
-
if (!sliderScrollerElement)
|
|
31
|
-
return;
|
|
32
|
-
const { firstElementChild: firstElement, lastElementChild: lastElement } = sliderScrollerElement;
|
|
33
|
-
setIsAtStart(firstElement === sliderScrollerElement?.children[currentSlideId]);
|
|
34
|
-
setIsAtEnd(lastElement === sliderScrollerElement?.children[currentSlideId]);
|
|
35
|
-
}, [currentSlideId]);
|
|
16
|
+
const scrollerRef = useRef(null);
|
|
17
|
+
const isAtStart = currentSlideId === 0;
|
|
18
|
+
const isAtEnd = currentSlideId === images.length - 1;
|
|
36
19
|
useEffect(() => {
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
return undefined;
|
|
50
|
-
}, [inView, observerOptions, updateControls]);
|
|
51
|
-
const synchronise = useCallback(() => updateControls(), [updateControls]);
|
|
52
|
-
const goToSlide = useCallback((element) => {
|
|
53
|
-
const sliderScrollerElement = targetRef.current;
|
|
54
|
-
if (!sliderScrollerElement || !element)
|
|
55
|
-
return;
|
|
56
|
-
sliderScrollerElement.scrollTo({
|
|
57
|
-
left: element.offsetLeft,
|
|
58
|
-
});
|
|
20
|
+
if (!scrollerRef.current)
|
|
21
|
+
return undefined;
|
|
22
|
+
const observerOptions = {
|
|
23
|
+
root: scrollerRef.current,
|
|
24
|
+
threshold: 0.6,
|
|
25
|
+
};
|
|
26
|
+
const observer = new IntersectionObserver((observations) => setCurrentSlideIdToVisibleSlide({ observations, ref: scrollerRef, setCurrentSlideId }), observerOptions);
|
|
27
|
+
const slides = Array.from(scrollerRef.current.children);
|
|
28
|
+
slides.forEach((slide) => observer.observe(slide));
|
|
29
|
+
return () => observer.disconnect();
|
|
59
30
|
}, []);
|
|
60
|
-
const goToSlideId = useCallback((id) => {
|
|
61
|
-
const element = targetRef.current?.children[id];
|
|
62
|
-
if (element)
|
|
63
|
-
goToSlide(element);
|
|
64
|
-
}, [goToSlide]);
|
|
65
|
-
const goToNextSlide = useCallback(() => {
|
|
66
|
-
const element = targetRef.current?.children[currentSlideId];
|
|
67
|
-
const nextElement = element?.nextElementSibling;
|
|
68
|
-
if (nextElement)
|
|
69
|
-
goToSlide(nextElement);
|
|
70
|
-
}, [currentSlideId, goToSlide]);
|
|
71
|
-
const goToPreviousSlide = useCallback(() => {
|
|
72
|
-
const element = targetRef.current?.children[currentSlideId];
|
|
73
|
-
const previousElement = element?.previousElementSibling;
|
|
74
|
-
if (previousElement)
|
|
75
|
-
goToSlide(previousElement);
|
|
76
|
-
}, [currentSlideId, goToSlide]);
|
|
77
31
|
useEffect(() => {
|
|
78
|
-
const handleResize = () => {
|
|
79
|
-
const sliderScrollerElement = targetRef.current;
|
|
80
|
-
const currentSlideElement = targetRef.current?.children[currentSlideId];
|
|
81
|
-
if (!sliderScrollerElement || !currentSlideElement)
|
|
82
|
-
return;
|
|
83
|
-
const expectedScrollLeft = currentSlideElement.offsetLeft;
|
|
84
|
-
if (Math.abs(sliderScrollerElement.scrollLeft - expectedScrollLeft) < 1)
|
|
85
|
-
return;
|
|
86
|
-
goToSlide(currentSlideElement);
|
|
87
|
-
};
|
|
32
|
+
const handleResize = debounce(() => scrollToCurrentSlideOnResize({ currentSlideId, ref: scrollerRef }), 100);
|
|
88
33
|
window.addEventListener('resize', handleResize);
|
|
89
34
|
return () => window.removeEventListener('resize', handleResize);
|
|
90
|
-
}, [currentSlideId
|
|
91
|
-
return (
|
|
35
|
+
}, [currentSlideId]);
|
|
36
|
+
return (_jsxs("div", { ...restProps, "aria-roledescription": "carousel", className: clsx('ams-image-slider',
|
|
37
|
+
// The 'ams-image-slider--controls' class is @deprecated and will be removed in a future release.
|
|
38
|
+
controls && 'ams-image-slider--controls', className), ref: ref, children: [controls && (_jsxs("div", { className: "ams-image-slider__controls", children: [_jsx(ImageSliderControl, { disabled: isAtStart, icon: ChevronBackwardIcon, iconOnly: true, onClick: () => scrollToSlide(currentSlideId - 1, scrollerRef), children: previousLabel }), _jsx(ImageSliderControl, { disabled: isAtEnd, icon: ChevronForwardIcon, iconOnly: true, onClick: () => scrollToSlide(currentSlideId + 1, scrollerRef), children: nextLabel })] })), _jsx("div", { "aria-live": "polite", className: "ams-image-slider__scroller", ref: scrollerRef, role: "group", tabIndex: 0, children: images.map(({ alt, aspectRatio, sizes, src, srcSet }, index) => (_jsx(Image, { alt: alt, "aria-hidden": index !== currentSlideId ? true : undefined, aspectRatio: aspectRatio, className: clsx('ams-image-slider__item',
|
|
39
|
+
// The 'ams-image-slider__item--in-view' class is @deprecated and will be removed in a future release.
|
|
40
|
+
index === currentSlideId && 'ams-image-slider__item--in-view'), sizes: sizes, src: src, srcSet: srcSet }, `${index}-${src}`))) }), _jsx(ImageSliderThumbnails, { currentSlideId: currentSlideId, imageLabel: imageLabel, scrollToSlide: (id) => scrollToSlide(id, scrollerRef), thumbnails: images })] }));
|
|
92
41
|
});
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* @see {@link https://designsystem.amsterdam/?path=/docs/components-media-image-slider--docs Image Slider docs at Amsterdam Design System}
|
|
96
|
-
*/
|
|
97
|
-
export const ImageSlider = Object.assign(ImageSliderRoot, { Item: ImageSliderItem });
|
|
42
|
+
ImageSlider.displayName = 'ImageSlider';
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
* Copyright Gemeente Amsterdam
|
|
4
4
|
*/
|
|
5
5
|
import type { HTMLAttributes } from 'react';
|
|
6
|
-
import type {
|
|
6
|
+
import type { ImageSliderProps } from './ImageSlider';
|
|
7
7
|
export type ImageSliderThumbnailsProps = {
|
|
8
|
+
currentSlideId: number;
|
|
8
9
|
imageLabel?: string;
|
|
9
|
-
|
|
10
|
+
scrollToSlide: (id: number) => void;
|
|
11
|
+
thumbnails: ImageSliderProps['images'];
|
|
10
12
|
} & HTMLAttributes<HTMLElement>;
|
|
11
|
-
export declare const ImageSliderThumbnails: import("react").
|
|
12
|
-
imageLabel?: string;
|
|
13
|
-
thumbnails: ImageSliderImageProps[];
|
|
14
|
-
} & HTMLAttributes<HTMLElement> & import("react").RefAttributes<HTMLElement>>;
|
|
13
|
+
export declare const ImageSliderThumbnails: ({ currentSlideId, imageLabel, scrollToSlide, thumbnails, }: ImageSliderThumbnailsProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,28 +1,23 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
|
-
import { forwardRef, useCallback, useContext, useMemo } from 'react';
|
|
4
3
|
import { generateAspectRatioClass } from '../Image/generateAspectRatioClass';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const { currentSlideId, goToNextSlide, goToPreviousSlide, goToSlideId } = useContext(ImageSliderContext);
|
|
8
|
-
const handleKeyDown = useCallback((event) => {
|
|
4
|
+
export const ImageSliderThumbnails = ({ currentSlideId, imageLabel, scrollToSlide, thumbnails, }) => {
|
|
5
|
+
const handleKeyDown = (event) => {
|
|
9
6
|
const element = event.currentTarget.children[currentSlideId];
|
|
10
7
|
if (event.key === 'ArrowRight') {
|
|
11
8
|
const nextElement = element?.nextElementSibling;
|
|
12
9
|
if (nextElement) {
|
|
13
10
|
nextElement.focus();
|
|
14
|
-
|
|
11
|
+
scrollToSlide(currentSlideId + 1);
|
|
15
12
|
}
|
|
16
13
|
}
|
|
17
14
|
if (event.key === 'ArrowLeft') {
|
|
18
15
|
const previousElement = element?.previousElementSibling;
|
|
19
16
|
if (previousElement) {
|
|
20
17
|
previousElement.focus();
|
|
21
|
-
|
|
18
|
+
scrollToSlide(currentSlideId - 1);
|
|
22
19
|
}
|
|
23
20
|
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
});
|
|
28
|
-
ImageSliderThumbnails.displayName = 'ImageSlider.Thumbnails';
|
|
21
|
+
};
|
|
22
|
+
return (_jsx("nav", { className: "ams-image-slider__thumbnails", onKeyDown: handleKeyDown, role: "tablist", children: thumbnails.map(({ alt, aspectRatio, src }, index) => (_jsx("button", { "aria-label": `${imageLabel} ${index + 1}: ${alt}`, "aria-posinset": index + 1, "aria-selected": currentSlideId === index ? 'true' : 'false', "aria-setsize": thumbnails.length, className: clsx('ams-image-slider__thumbnail', currentSlideId === index && 'ams-image-slider__thumbnail--in-view', generateAspectRatioClass(aspectRatio)), onClick: () => scrollToSlide(index), role: "tab", style: { backgroundImage: `url(${src})` }, tabIndex: currentSlideId === index ? 0 : -1, type: "button" }, `${index}-${src}`))) }));
|
|
23
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function debounce<F extends (...args: unknown[]) => void>(fn: F, delay: number): (...args: Parameters<F>) => void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { scrollToSlide } from './scrollToSlide';
|
|
2
|
+
export const scrollToCurrentSlideOnResize = ({ currentSlideId, ref }) => {
|
|
3
|
+
const scrollerElement = ref.current;
|
|
4
|
+
const currentSlideElement = ref.current?.children[currentSlideId];
|
|
5
|
+
if (!scrollerElement || !currentSlideElement)
|
|
6
|
+
return;
|
|
7
|
+
const expectedScrollLeft = currentSlideElement.offsetLeft;
|
|
8
|
+
if (Math.abs(scrollerElement.scrollLeft - expectedScrollLeft) < 1)
|
|
9
|
+
return;
|
|
10
|
+
scrollToSlide(currentSlideId, ref);
|
|
11
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RefObject } from 'react';
|
|
2
|
+
type Args = {
|
|
3
|
+
observations: IntersectionObserverEntry[];
|
|
4
|
+
ref: RefObject<HTMLDivElement>;
|
|
5
|
+
setCurrentSlideId: (id: number) => void;
|
|
6
|
+
};
|
|
7
|
+
export declare const setCurrentSlideIdToVisibleSlide: ({ observations, ref, setCurrentSlideId }: Args) => void;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const setCurrentSlideIdToVisibleSlide = ({ observations, ref, setCurrentSlideId }) => {
|
|
2
|
+
const images = Array.from(ref.current?.children || []);
|
|
3
|
+
if (images.length === 0)
|
|
4
|
+
return;
|
|
5
|
+
observations.forEach((observation) => {
|
|
6
|
+
if (observation.isIntersecting) {
|
|
7
|
+
setCurrentSlideId(images.indexOf(observation.target));
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
};
|
package/dist/Logo/Logo.d.ts
CHANGED
|
@@ -2,13 +2,18 @@
|
|
|
2
2
|
* @license EUPL-1.2+
|
|
3
3
|
* Copyright Gemeente Amsterdam
|
|
4
4
|
*/
|
|
5
|
-
import type {
|
|
6
|
-
export
|
|
5
|
+
import type { ComponentType, SVGProps } from 'react';
|
|
6
|
+
export declare const logoBrands: readonly ["amsterdam", "ggd-amsterdam", "museum-weesp", "stadsarchief", "stadsbank-van-lening", "vga-verzekeringen"];
|
|
7
|
+
export type LogoBrand = (typeof logoBrands)[number];
|
|
7
8
|
export type LogoProps = {
|
|
8
|
-
/** The name of the brand for which to display the logo. */
|
|
9
|
-
brand?: LogoBrand;
|
|
9
|
+
/** The name of the brand for which to display the logo, or configuration for a custom logo. */
|
|
10
|
+
brand?: LogoBrand | LogoBrandConfig;
|
|
10
11
|
} & SVGProps<SVGSVGElement>;
|
|
12
|
+
export type LogoBrandConfig = {
|
|
13
|
+
label: string;
|
|
14
|
+
svg: ComponentType<SVGProps<SVGSVGElement>>;
|
|
15
|
+
};
|
|
11
16
|
/**
|
|
12
17
|
* @see {@link https://designsystem.amsterdam/?path=/docs/components-media-logo--docs Logo docs at Amsterdam Design System}
|
|
13
18
|
*/
|
|
14
|
-
export declare const Logo: ForwardRefExoticComponent<Omit<LogoProps, "ref"> & RefAttributes<SVGSVGElement>>;
|
|
19
|
+
export declare const Logo: import("react").ForwardRefExoticComponent<Omit<LogoProps, "ref"> & import("react").RefAttributes<SVGSVGElement>>;
|
package/dist/Logo/Logo.js
CHANGED
|
@@ -2,38 +2,46 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
3
|
import { forwardRef } from 'react';
|
|
4
4
|
import { LogoAmsterdam, LogoGgdAmsterdam, LogoMuseumWeesp, LogoStadsarchief, LogoStadsbankVanLening, LogoVgaVerzekeringen, } from './brand';
|
|
5
|
+
export const logoBrands = [
|
|
6
|
+
'amsterdam',
|
|
7
|
+
'ggd-amsterdam',
|
|
8
|
+
'museum-weesp',
|
|
9
|
+
'stadsarchief',
|
|
10
|
+
'stadsbank-van-lening',
|
|
11
|
+
'vga-verzekeringen',
|
|
12
|
+
];
|
|
5
13
|
const logoConfig = {
|
|
6
14
|
amsterdam: {
|
|
7
15
|
label: 'Gemeente Amsterdam logo',
|
|
8
|
-
|
|
16
|
+
svg: LogoAmsterdam,
|
|
9
17
|
},
|
|
10
18
|
'ggd-amsterdam': {
|
|
11
19
|
label: 'GGD Amsterdam logo',
|
|
12
|
-
|
|
20
|
+
svg: LogoGgdAmsterdam,
|
|
13
21
|
},
|
|
14
22
|
'museum-weesp': {
|
|
15
23
|
label: 'Gemeente Amsterdam Museum Weesp logo',
|
|
16
|
-
|
|
24
|
+
svg: LogoMuseumWeesp,
|
|
17
25
|
},
|
|
18
26
|
stadsarchief: {
|
|
19
27
|
label: 'Gemeente Amsterdam Stadsarchief logo',
|
|
20
|
-
|
|
28
|
+
svg: LogoStadsarchief,
|
|
21
29
|
},
|
|
22
30
|
'stadsbank-van-lening': {
|
|
23
31
|
label: 'Gemeente Amsterdam Stadsbank van Lening logo',
|
|
24
|
-
|
|
32
|
+
svg: LogoStadsbankVanLening,
|
|
25
33
|
},
|
|
26
34
|
'vga-verzekeringen': {
|
|
27
35
|
label: 'Gemeente Amsterdam VGA Verzekeringen logo',
|
|
28
|
-
|
|
36
|
+
svg: LogoVgaVerzekeringen,
|
|
29
37
|
},
|
|
30
38
|
};
|
|
31
39
|
/**
|
|
32
40
|
* @see {@link https://designsystem.amsterdam/?path=/docs/components-media-logo--docs Logo docs at Amsterdam Design System}
|
|
33
41
|
*/
|
|
34
42
|
export const Logo = forwardRef(({ 'aria-label': ariaLabel, brand = 'amsterdam', className, ...restProps }, ref) => {
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
return (_jsx(LogoComponent, { ...restProps, "aria-label": ariaLabel ||
|
|
43
|
+
const config = typeof brand === 'string' ? logoConfig[brand] : brand;
|
|
44
|
+
const { label, svg: LogoComponent } = config;
|
|
45
|
+
return (_jsx(LogoComponent, { ...restProps, "aria-label": ariaLabel || label, className: clsx('ams-logo', className), ref: ref }));
|
|
38
46
|
});
|
|
39
47
|
Logo.displayName = 'Logo';
|
|
@@ -10,7 +10,10 @@ export type PageFooterProps = PropsWithChildren<HTMLAttributes<HTMLElement>>;
|
|
|
10
10
|
export declare const PageFooter: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLElement> & {
|
|
11
11
|
children?: import("react").ReactNode | undefined;
|
|
12
12
|
} & import("react").RefAttributes<HTMLElement>> & {
|
|
13
|
-
Menu: import("react").ForwardRefExoticComponent<
|
|
13
|
+
Menu: import("react").ForwardRefExoticComponent<{
|
|
14
|
+
heading?: string;
|
|
15
|
+
headingLevel?: import("..").HeadingProps["level"];
|
|
16
|
+
} & HTMLAttributes<HTMLUListElement> & {
|
|
14
17
|
children?: import("react").ReactNode | undefined;
|
|
15
18
|
} & import("react").RefAttributes<HTMLUListElement>>;
|
|
16
19
|
MenuLink: import("react").ForwardRefExoticComponent<import("react").AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
@@ -3,7 +3,32 @@
|
|
|
3
3
|
* Copyright Gemeente Amsterdam
|
|
4
4
|
*/
|
|
5
5
|
import type { HTMLAttributes, PropsWithChildren } from 'react';
|
|
6
|
-
|
|
7
|
-
export
|
|
6
|
+
import type { HeadingProps } from '../Heading';
|
|
7
|
+
export type PageFooterMenuProps = {
|
|
8
|
+
/**
|
|
9
|
+
* Describes the menu for users of assistive technology.
|
|
10
|
+
* The heading gets visually hidden – sighted users can infer the meaning of the menu from its appearance.
|
|
11
|
+
* @default Over deze website
|
|
12
|
+
*/
|
|
13
|
+
heading?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The hierarchical level of the Footer Menu’s Heading within the document.
|
|
16
|
+
* The default value is 2. This will almost always be correct – but verify this yourself.
|
|
17
|
+
*/
|
|
18
|
+
headingLevel?: HeadingProps['level'];
|
|
19
|
+
} & PropsWithChildren<HTMLAttributes<HTMLUListElement>>;
|
|
20
|
+
export declare const PageFooterMenu: import("react").ForwardRefExoticComponent<{
|
|
21
|
+
/**
|
|
22
|
+
* Describes the menu for users of assistive technology.
|
|
23
|
+
* The heading gets visually hidden – sighted users can infer the meaning of the menu from its appearance.
|
|
24
|
+
* @default Over deze website
|
|
25
|
+
*/
|
|
26
|
+
heading?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The hierarchical level of the Footer Menu’s Heading within the document.
|
|
29
|
+
* The default value is 2. This will almost always be correct – but verify this yourself.
|
|
30
|
+
*/
|
|
31
|
+
headingLevel?: HeadingProps["level"];
|
|
32
|
+
} & HTMLAttributes<HTMLUListElement> & {
|
|
8
33
|
children?: import("react").ReactNode | undefined;
|
|
9
34
|
} & import("react").RefAttributes<HTMLUListElement>>;
|