@scottish-government/designsystem-react 0.12.1 → 0.13.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/.storybook/main.ts +6 -6
- package/.storybook/sgdsArgTypes.ts +84 -43
- package/CHANGELOG.md +26 -0
- package/eslint.config.mjs +32 -0
- package/package.json +8 -3
- package/src/common/AbstractNotificationBanner/AbstractNotificationBanner.tsx +5 -4
- package/src/common/AbstractNotificationBanner/types.ts +15 -0
- package/src/common/ActionLink/ActionLink.tsx +3 -1
- package/src/common/ActionLink/types.ts +8 -0
- package/src/common/ConditionalWrapper/ConditionalWrapper.tsx +10 -2
- package/src/common/ConditionalWrapper/types.ts +4 -0
- package/src/common/FileIcon/FileIcon.tsx +2 -1
- package/src/common/FileIcon/types.ts +7 -0
- package/src/common/HintText/HintText.test.tsx +3 -15
- package/src/common/HintText/HintText.tsx +4 -4
- package/src/common/HintText/types.ts +4 -0
- package/src/common/Icon/Icon.tsx +2 -1
- package/src/common/Icon/types.ts +9 -0
- package/src/common/ScreenReaderText/ScreenReaderText.tsx +1 -1
- package/src/common/WrapperTag/WrapperTag.tsx +5 -3
- package/src/common/WrapperTag/types.ts +3 -0
- package/src/components/Accordion/Accordion.Item.stories.tsx +1 -5
- package/src/components/Accordion/Accordion.stories.tsx +5 -5
- package/src/components/Accordion/Accordion.tsx +5 -4
- package/src/components/Accordion/types.ts +13 -0
- package/src/components/AspectBox/AspectBox.stories.tsx +1 -2
- package/src/components/AspectBox/AspectBox.tsx +5 -4
- package/src/components/AspectBox/types.ts +3 -0
- package/src/components/BackToTop/BackToTop.tsx +3 -2
- package/src/components/BackToTop/types.ts +3 -0
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +4 -2
- package/src/components/Breadcrumbs/types.ts +6 -0
- package/src/components/Button/Button.tsx +2 -1
- package/src/components/Button/ButtonGroup.tsx +3 -1
- package/src/components/Button/types.ts +21 -0
- package/src/components/CategoryItem/CategoryItem.tsx +7 -4
- package/src/components/CategoryItem/types.ts +10 -0
- package/src/components/CategoryList/CategoryList.tsx +4 -2
- package/src/components/CategoryList/types.ts +5 -0
- package/src/components/Checkbox/Checkbox.stories.tsx +3 -3
- package/src/components/Checkbox/Checkbox.tsx +5 -4
- package/src/components/Checkbox/CheckboxGroup.tsx +3 -3
- package/src/components/Checkbox/types.ts +9 -0
- package/src/components/ConfirmationMessage/ConfirmationMessage.tsx +2 -1
- package/src/components/ConfirmationMessage/types.ts +7 -0
- package/src/components/ContentsNav/ContentsNav.stories.tsx +5 -1
- package/src/components/ContentsNav/ContentsNav.tsx +3 -2
- package/src/components/ContentsNav/types.ts +11 -0
- package/src/components/CookieBanner/CookieBanner.Buttons.stories.tsx +3 -3
- package/src/components/CookieBanner/CookieBanner.stories.tsx +6 -6
- package/src/components/CookieBanner/CookieBanner.test.tsx +6 -0
- package/src/components/CookieBanner/CookieBanner.tsx +13 -3
- package/src/components/DatePicker/DatePicker.test.tsx +0 -5
- package/src/components/DatePicker/DatePicker.tsx +3 -2
- package/src/components/DatePicker/types.ts +20 -0
- package/src/components/Details/Details.stories.tsx +1 -1
- package/src/components/Details/Details.tsx +3 -1
- package/src/components/Details/types.ts +4 -0
- package/src/components/ErrorMessage/ErrorMessage.tsx +3 -1
- package/src/components/ErrorMessage/types.ts +3 -0
- package/src/components/ErrorSummary/ErrorSummary.test.tsx +1 -1
- package/src/components/ErrorSummary/ErrorSummary.tsx +3 -2
- package/src/components/ErrorSummary/types.ts +11 -0
- package/src/components/FileDownload/FileDownload.tsx +2 -1
- package/src/components/FileDownload/types.ts +11 -0
- package/src/components/HideThisPage/HideThisPage.tsx +3 -2
- package/src/components/HideThisPage/types.ts +3 -0
- package/src/components/InsetText/InsetText.tsx +1 -1
- package/src/components/NotificationBanner/NotificationBanner.stories.tsx +2 -2
- package/src/components/NotificationBanner/NotificationBanner.tsx +5 -4
- package/src/components/NotificationPanel/NotificationPanel.tsx +2 -1
- package/src/components/NotificationPanel/types.ts +7 -0
- package/src/components/PageHeader/PageHeader.tsx +3 -1
- package/src/components/PageHeader/types.ts +5 -0
- package/src/components/PageMetadata/PageMetadata.stories.tsx +1 -1
- package/src/components/PageMetadata/PageMetadata.tsx +5 -3
- package/src/components/PageMetadata/types.ts +7 -0
- package/src/components/Pagination/Pagination.tsx +5 -3
- package/src/components/Pagination/types.ts +20 -0
- package/src/components/PhaseBanner/PhaseBanner.stories.tsx +1 -4
- package/src/components/PhaseBanner/PhaseBanner.tsx +2 -1
- package/src/components/PhaseBanner/types.ts +3 -0
- package/src/components/Question/Question.tsx +3 -2
- package/src/components/Question/types.ts +9 -0
- package/src/components/RadioButton/RadioButton.tsx +5 -4
- package/src/components/RadioButton/RadioGroup.tsx +2 -1
- package/src/components/RadioButton/types.ts +12 -0
- package/src/components/SearchFacets/SearchFacets.Group.stories.tsx +2 -3
- package/src/components/SearchFacets/SearchFacets.stories.tsx +1 -1
- package/src/components/SearchFacets/SearchFacets.tsx +7 -6
- package/src/components/SearchFacets/types.ts +14 -0
- package/src/components/SearchFilters/SearchFilters.Panel.stories.tsx +18 -7
- package/src/components/SearchFilters/SearchFilters.stories.tsx +1 -1
- package/src/components/SearchFilters/SearchFilters.tsx +4 -3
- package/src/components/SearchFilters/types.ts +14 -0
- package/src/components/SearchResult/SearchResult.stories.tsx +9 -10
- package/src/components/SearchResult/SearchResult.tsx +9 -8
- package/src/components/SearchResult/types.ts +13 -0
- package/src/components/SearchSort/SearchSort.stories.tsx +2 -1
- package/src/components/SearchSort/SearchSort.tsx +2 -1
- package/src/components/SearchSort/types.ts +7 -0
- package/src/components/Select/Select.tsx +5 -4
- package/src/components/Select/types.ts +7 -0
- package/src/components/SequentialNavigation/SequentialNavigation.tsx +6 -4
- package/src/components/SequentialNavigation/types.ts +12 -0
- package/src/components/SideNavigation/SideNavigation.tsx +5 -4
- package/src/components/SideNavigation/types.ts +16 -0
- package/src/components/SiteFooter/SiteFooter.tsx +7 -6
- package/src/components/SiteFooter/types.ts +20 -0
- package/src/components/SiteHeader/SiteHeader.stories.tsx +4 -3
- package/src/components/SiteHeader/SiteHeader.tsx +10 -9
- package/src/components/SiteHeader/types.ts +22 -0
- package/src/components/SiteNavigation/SiteNavigation.tsx +4 -2
- package/src/components/SiteNavigation/types.ts +11 -0
- package/src/components/SiteSearch/SiteSearch.stories.tsx +4 -2
- package/src/components/SiteSearch/SiteSearch.tsx +6 -5
- package/src/components/SiteSearch/types.ts +13 -0
- package/src/components/SkipLinks/SkipLinks.stories.tsx +3 -3
- package/src/components/SkipLinks/SkipLinks.tsx +4 -4
- package/src/components/SkipLinks/types.ts +9 -0
- package/src/components/SummaryCard/SummaryCard.test.tsx +0 -11
- package/src/components/SummaryCard/SummaryCard.tsx +6 -4
- package/src/components/SummaryCard/types.ts +6 -0
- package/src/components/SummaryList/SummaryList.Item.stories.tsx +5 -5
- package/src/components/SummaryList/SummaryList.stories.tsx +1 -1
- package/src/components/SummaryList/SummaryList.test.tsx +1 -6
- package/src/components/SummaryList/SummaryList.tsx +8 -6
- package/src/components/SummaryList/types.ts +7 -0
- package/src/components/Table/Table.tsx +3 -2
- package/src/components/Table/types.ts +6 -0
- package/src/components/Tabs/Tabs.Item.stories.tsx +7 -7
- package/src/components/Tabs/Tabs.stories.tsx +3 -3
- package/src/components/Tabs/Tabs.tsx +7 -5
- package/src/components/Tabs/types.ts +19 -0
- package/src/components/Tag/Tag.tsx +3 -1
- package/src/components/Tag/types.ts +5 -0
- package/src/components/TaskList/TaskList.Group.stories.tsx +0 -5
- package/src/components/TaskList/TaskList.stories.tsx +0 -1
- package/src/components/TaskList/TaskList.tsx +12 -9
- package/src/components/TaskList/types.ts +20 -0
- package/src/components/TextInput/TextInput.tsx +6 -6
- package/src/components/TextInput/types.ts +12 -0
- package/src/components/Textarea/Textarea.tsx +6 -5
- package/src/components/WarningText/WarningText.tsx +1 -1
- package/src/hooks/useTracking/useTracking.test.tsx +5 -7
- package/src/hooks/useTracking/useTracking.ts +1 -1
- package/src/images/icons/arrow_upward.tsx +10 -10
- package/src/images/icons/calendar_today.tsx +10 -10
- package/src/images/icons/cancel.tsx +8 -8
- package/src/images/icons/check_circle.tsx +10 -10
- package/src/images/icons/chevron_left.tsx +10 -10
- package/src/images/icons/chevron_right.tsx +10 -10
- package/src/images/icons/close.tsx +10 -10
- package/src/images/icons/description.tsx +10 -10
- package/src/images/icons/double_chevron_left.tsx +8 -8
- package/src/images/icons/double_chevron_right.tsx +8 -8
- package/src/images/icons/error.tsx +10 -10
- package/src/images/icons/expand_less.tsx +10 -10
- package/src/images/icons/expand_more.tsx +10 -10
- package/src/images/icons/list.tsx +13 -13
- package/src/images/icons/menu.tsx +10 -10
- package/src/images/icons/priority_high.tsx +11 -11
- package/src/images/icons/search.tsx +10 -10
- package/src/shared-types.ts +40 -0
- package/vite.config.ts +2 -1
- package/@types/common/AbstractNotificationBanner.d.ts +0 -17
- package/@types/common/ActionLink.d.ts +0 -8
- package/@types/common/ConditionalWrapper.d.ts +0 -6
- package/@types/common/FileIcon.d.ts +0 -7
- package/@types/common/HintText.d.ts +0 -6
- package/@types/common/Icon.d.ts +0 -9
- package/@types/common/ScreenReaderText.d.ts +0 -4
- package/@types/common/WrapperTag.d.ts +0 -5
- package/@types/components/Accordion.d.ts +0 -15
- package/@types/components/AspectBox.d.ts +0 -5
- package/@types/components/BackToTop.d.ts +0 -5
- package/@types/components/Breadcrumbs.d.ts +0 -11
- package/@types/components/Button.d.ts +0 -17
- package/@types/components/ButtonGroup.d.ts +0 -5
- package/@types/components/CategoryItem.d.ts +0 -10
- package/@types/components/CategoryList.d.ts +0 -7
- package/@types/components/Checkbox.d.ts +0 -11
- package/@types/components/ConfirmationMessage.d.ts +0 -7
- package/@types/components/ContentsNav.d.ts +0 -13
- package/@types/components/DatePicker.d.ts +0 -20
- package/@types/components/Details.d.ts +0 -6
- package/@types/components/ErrorMessage.d.ts +0 -5
- package/@types/components/ErrorSummary.d.ts +0 -12
- package/@types/components/FileDownload.d.ts +0 -11
- package/@types/components/HideThisPage.d.ts +0 -5
- package/@types/components/InsetText.d.ts +0 -5
- package/@types/components/Metadata.d.ts +0 -11
- package/@types/components/NotificationPanel.d.ts +0 -7
- package/@types/components/PageHeader.d.ts +0 -7
- package/@types/components/Pagination.d.ts +0 -22
- package/@types/components/PhaseBanner.d.ts +0 -5
- package/@types/components/Question.d.ts +0 -11
- package/@types/components/RadioButton.d.ts +0 -14
- package/@types/components/SearchFacets.d.ts +0 -18
- package/@types/components/SearchFilters.d.ts +0 -14
- package/@types/components/SearchResult.d.ts +0 -30
- package/@types/components/SearchSort.d.ts +0 -9
- package/@types/components/Select.d.ts +0 -7
- package/@types/components/SequentialNavigation.d.ts +0 -14
- package/@types/components/SideNavigation.d.ts +0 -18
- package/@types/components/SiteFooter.d.ts +0 -25
- package/@types/components/SiteHeader.d.ts +0 -20
- package/@types/components/SiteNavigation.d.ts +0 -13
- package/@types/components/SiteSearch.d.ts +0 -14
- package/@types/components/SkipLinks.d.ts +0 -13
- package/@types/components/SummaryCard.d.ts +0 -6
- package/@types/components/SummaryList.d.ts +0 -14
- package/@types/components/Table.d.ts +0 -8
- package/@types/components/Tabs.d.ts +0 -21
- package/@types/components/Tag.d.ts +0 -5
- package/@types/components/TaskList.d.ts +0 -22
- package/@types/components/TextInput.d.ts +0 -12
- package/@types/components/Textarea.d.ts +0 -4
- package/@types/components/WarningText.d.ts +0 -5
- package/@types/global.d.ts +0 -1
- package/@types/sgds.d.ts +0 -49
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -40
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/components/FeatureHeader/FeatureHeader.stories.tsx +0 -60
- package/src/components/FeatureHeader/FeatureHeader.tsx +0 -94
- package/src/components/FeatureHeader/index.ts +0 -1
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React, { createContext, useContext, useEffect, useRef, useId } from 'react';
|
|
2
2
|
import WrapperTag from '../../common/WrapperTag';
|
|
3
|
-
// @ts-
|
|
3
|
+
// @ts-expect-error no types from core SGDS
|
|
4
4
|
import DSAccordion from '@scottish-government/design-system/src/components/accordion/accordion';
|
|
5
|
+
import { AccordionItemProps, AccordionProps } from './types';
|
|
5
6
|
|
|
6
7
|
let accordionItemCounter = 0;
|
|
7
8
|
const AccordionHeadingLevelContext = createContext('h3');
|
|
@@ -14,11 +15,11 @@ const AccordionItem = ({
|
|
|
14
15
|
heading,
|
|
15
16
|
title,
|
|
16
17
|
...props
|
|
17
|
-
}:
|
|
18
|
+
}: AccordionItemProps) => {
|
|
18
19
|
accordionItemCounter = accordionItemCounter + 1;
|
|
19
20
|
const processedId = rawId || `accordion-item-${useId()}`;
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
const headingLevel = useContext(AccordionHeadingLevelContext);
|
|
22
23
|
|
|
23
24
|
if (title) {
|
|
24
25
|
console.warn(
|
|
@@ -77,7 +78,7 @@ const Accordion = ({
|
|
|
77
78
|
hideOpenAll,
|
|
78
79
|
isSmall,
|
|
79
80
|
...props
|
|
80
|
-
}:
|
|
81
|
+
}: AccordionProps) => {
|
|
81
82
|
const ref = useRef(null);
|
|
82
83
|
|
|
83
84
|
useEffect(() => {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HeadingLevel } from "../../shared-types";
|
|
2
|
+
|
|
3
|
+
export interface AccordionItemProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
4
|
+
id?: string;
|
|
5
|
+
heading: string | React.ReactNode;
|
|
6
|
+
isOpen?: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface AccordionProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
10
|
+
headingLevel?: HeadingLevel;
|
|
11
|
+
hideOpenAll?: boolean;
|
|
12
|
+
isSmall?: boolean;
|
|
13
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
2
|
import argTypes from '../../../.storybook/sgdsArgTypes';
|
|
3
|
-
|
|
4
|
-
// @ts-ignore
|
|
3
|
+
// @ts-expect-error no types
|
|
5
4
|
import coo from '../../../static/images/highland-cow.jpg';
|
|
6
5
|
import AspectBox from './AspectBox';
|
|
7
6
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React, { Children, useEffect, useRef } from 'react';
|
|
2
|
-
// @ts-
|
|
2
|
+
// @ts-expect-error no types from core SGDS
|
|
3
3
|
import DSAspectBox from '@scottish-government/design-system/src/components/aspect-box/aspect-box-fallback';
|
|
4
|
+
import { AspectBoxProps } from './types';
|
|
4
5
|
|
|
5
6
|
const AspectBox = ({
|
|
6
7
|
children,
|
|
7
8
|
className,
|
|
8
9
|
ratio,
|
|
9
10
|
...props
|
|
10
|
-
}:
|
|
11
|
+
}: AspectBoxProps) => {
|
|
11
12
|
const ref = useRef(null);
|
|
12
13
|
|
|
13
14
|
useEffect(() => {
|
|
@@ -16,7 +17,7 @@ const AspectBox = ({
|
|
|
16
17
|
}
|
|
17
18
|
}, [ref]);
|
|
18
19
|
|
|
19
|
-
function processChild(child:
|
|
20
|
+
function processChild(child: React.JSX.Element) {
|
|
20
21
|
if (['img', 'svg', 'picture'].includes(child.type)) {
|
|
21
22
|
return React.cloneElement(child, { className: 'ds_aspect-box__inner' });
|
|
22
23
|
}
|
|
@@ -49,7 +50,7 @@ const AspectBox = ({
|
|
|
49
50
|
ref={ref}
|
|
50
51
|
{...props}
|
|
51
52
|
>
|
|
52
|
-
{Children.map(children, child => processChild(child))}
|
|
53
|
+
{Children.map(children, child => processChild(child as React.JSX.Element))}
|
|
53
54
|
</div>
|
|
54
55
|
);
|
|
55
56
|
};
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
2
|
import Icon from '../../common/Icon';
|
|
3
|
-
// @ts-
|
|
3
|
+
// @ts-expect-error no types from core SGDS
|
|
4
4
|
import DSBackToTop from '@scottish-government/design-system/src/components/back-to-top/back-to-top';
|
|
5
|
+
import { BackToTopProps } from './types';
|
|
5
6
|
|
|
6
7
|
const BackToTop = ({
|
|
7
8
|
className,
|
|
8
9
|
href = '#page-top',
|
|
9
10
|
...props
|
|
10
|
-
}:
|
|
11
|
+
}: BackToTopProps) => {
|
|
11
12
|
const ref = useRef(null);
|
|
12
13
|
|
|
13
14
|
useEffect(() => {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { BreadcrumbItemProps } from "./types";
|
|
2
|
+
|
|
1
3
|
const BreadcrumbItem = ({
|
|
2
4
|
children,
|
|
3
5
|
isHidden,
|
|
4
6
|
href,
|
|
5
7
|
linkComponent,
|
|
6
8
|
...props
|
|
7
|
-
}:
|
|
9
|
+
}: BreadcrumbItemProps) => {
|
|
8
10
|
const BREADCRUMB_LINK_CLASSNAME = 'ds_breadcrumbs__link';
|
|
9
11
|
|
|
10
12
|
function processChildren(children: React.ReactNode) {
|
|
@@ -32,7 +34,7 @@ const BreadcrumbItem = ({
|
|
|
32
34
|
const Breadcrumbs = ({
|
|
33
35
|
children,
|
|
34
36
|
...props
|
|
35
|
-
}:
|
|
37
|
+
}: React.AllHTMLAttributes<HTMLElement>) => {
|
|
36
38
|
return (
|
|
37
39
|
<nav
|
|
38
40
|
aria-label="Breadcrumb"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Icon from '../../common/Icon';
|
|
2
2
|
import ScreenReaderText from '../../common/ScreenReaderText';
|
|
3
3
|
import WrapperTag from '../../common/WrapperTag';
|
|
4
|
+
import { ButtonProps } from './types';
|
|
4
5
|
|
|
5
6
|
const Button = ({
|
|
6
7
|
buttonStyle,
|
|
@@ -15,7 +16,7 @@ const Button = ({
|
|
|
15
16
|
type = 'button',
|
|
16
17
|
width,
|
|
17
18
|
...props
|
|
18
|
-
}:
|
|
19
|
+
}: ButtonProps) => {
|
|
19
20
|
// determine which HTML tag to use
|
|
20
21
|
let tagName = 'button';
|
|
21
22
|
if (href) {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { IconName } from '../../shared-types';
|
|
2
|
+
|
|
3
|
+
type ButtonStyle = 'primary' | 'secondary';
|
|
4
|
+
type ButtonType = 'submit' | 'reset' | 'button';
|
|
5
|
+
type ButtonWidth = 'fluid' | 'fixed' | 'max';
|
|
6
|
+
|
|
7
|
+
export interface ButtonProps extends React.AllHTMLAttributes<HTMLButtonElement> {
|
|
8
|
+
hasLinkStyle?: boolean;
|
|
9
|
+
href?: string;
|
|
10
|
+
icon?: IconName;
|
|
11
|
+
isIconLeft?: boolean;
|
|
12
|
+
isIconOnly?: boolean;
|
|
13
|
+
isSmall?: boolean;
|
|
14
|
+
buttonStyle?: ButtonStyle;
|
|
15
|
+
type?: ButtonType;
|
|
16
|
+
width?: ButtonWidth;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface ButtonGroupProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
20
|
+
isInline?: boolean;
|
|
21
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ConditionalWrapper from "../../common/ConditionalWrapper";
|
|
2
2
|
import WrapperTag from "../../common/WrapperTag";
|
|
3
|
+
import { CategoryItemProps } from "./types";
|
|
3
4
|
|
|
4
5
|
const CategoryItem = ({
|
|
5
6
|
children,
|
|
@@ -10,15 +11,17 @@ const CategoryItem = ({
|
|
|
10
11
|
tagName = 'div',
|
|
11
12
|
title,
|
|
12
13
|
...props
|
|
13
|
-
}:
|
|
14
|
+
}: CategoryItemProps) => {
|
|
14
15
|
const LINK_CLASS = 'ds_category-item__link';
|
|
15
16
|
|
|
16
17
|
function getLinkElement(children: React.ReactNode) {
|
|
18
|
+
let linkElement;
|
|
17
19
|
if (linkComponent) {
|
|
18
|
-
|
|
19
|
-
} else
|
|
20
|
-
|
|
20
|
+
linkElement = linkComponent({ className: LINK_CLASS, href, children });
|
|
21
|
+
} else {
|
|
22
|
+
linkElement = <a href={href} className={LINK_CLASS}>{children}</a>;
|
|
21
23
|
}
|
|
24
|
+
return linkElement as React.JSX.Element;
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
return (
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HeadingLevel, LinkComponent } from '../../shared-types';
|
|
2
|
+
|
|
3
|
+
export interface CategoryItemProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
4
|
+
className?: string;
|
|
5
|
+
headingLevel?: HeadingLevel;
|
|
6
|
+
href?: string;
|
|
7
|
+
linkComponent?: LinkComponent;
|
|
8
|
+
tagName?: string;
|
|
9
|
+
title: string;
|
|
10
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import React, { Children } from 'react';
|
|
2
2
|
import WrapperTag from "../../common/WrapperTag";
|
|
3
|
+
import { CategoryListProps } from './types';
|
|
4
|
+
import { CategoryItemProps } from '../CategoryItem/types';
|
|
3
5
|
|
|
4
6
|
const CategoryList = ({
|
|
5
7
|
children,
|
|
@@ -7,9 +9,9 @@ const CategoryList = ({
|
|
|
7
9
|
isGrid,
|
|
8
10
|
isOrdered,
|
|
9
11
|
...props
|
|
10
|
-
}:
|
|
12
|
+
}: CategoryListProps) => {
|
|
11
13
|
function processChild(child: React.ReactNode) {
|
|
12
|
-
const thisChild = child as React.ReactElement<
|
|
14
|
+
const thisChild = child as React.ReactElement<CategoryItemProps>
|
|
13
15
|
return React.cloneElement(thisChild, {tagName: 'li'})
|
|
14
16
|
}
|
|
15
17
|
|
|
@@ -12,18 +12,18 @@ const meta = {
|
|
|
12
12
|
description: 'The checkbox is checked on load'
|
|
13
13
|
},
|
|
14
14
|
hintText: argTypes.hintText,
|
|
15
|
-
|
|
15
|
+
isExclusive: {
|
|
16
16
|
control: 'boolean',
|
|
17
17
|
description: 'Whether the checkbox is exclusive (e.g. a \'none\' option)'
|
|
18
18
|
},
|
|
19
19
|
id: argTypes.id(),
|
|
20
|
+
isSmall: argTypes.isSmall(),
|
|
20
21
|
label: argTypes.label(),
|
|
21
22
|
name: {
|
|
22
23
|
type: 'string'
|
|
23
24
|
},
|
|
24
25
|
onBlur: argTypes.onBlur(),
|
|
25
|
-
onChange: argTypes.onChange()
|
|
26
|
-
small: argTypes.isSmall()
|
|
26
|
+
onChange: argTypes.onChange()
|
|
27
27
|
},
|
|
28
28
|
args: {
|
|
29
29
|
label: 'Benefits and grants',
|
|
@@ -2,6 +2,7 @@ import { useContext } from 'react';
|
|
|
2
2
|
import { CheckboxRadioContext } from '../../utils/context';
|
|
3
3
|
|
|
4
4
|
import HintText from '../../common/HintText';
|
|
5
|
+
import { CheckboxProps } from './types';
|
|
5
6
|
|
|
6
7
|
const Checkbox = ({
|
|
7
8
|
checked,
|
|
@@ -13,17 +14,17 @@ const Checkbox = ({
|
|
|
13
14
|
name,
|
|
14
15
|
onBlur,
|
|
15
16
|
onChange
|
|
16
|
-
}:
|
|
17
|
+
}: CheckboxProps) => {
|
|
17
18
|
const hintTextId = `hint-text-${id}`;
|
|
18
19
|
const behaviour = isExclusive && 'exclusive';
|
|
19
20
|
|
|
20
|
-
function handleBlur(event: React.FocusEvent) {
|
|
21
|
+
function handleBlur(event: React.FocusEvent<HTMLInputElement>) {
|
|
21
22
|
if (typeof onBlur === 'function') {
|
|
22
23
|
onBlur(event);
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
function handleChange(event: React.ChangeEvent) {
|
|
27
|
+
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
27
28
|
if (typeof onChange === 'function') {
|
|
28
29
|
onChange(event);
|
|
29
30
|
}
|
|
@@ -54,7 +55,7 @@ const Checkbox = ({
|
|
|
54
55
|
className="ds_checkbox__label"
|
|
55
56
|
htmlFor={id}
|
|
56
57
|
>{label}</label>
|
|
57
|
-
{hintText && <HintText id={hintTextId}
|
|
58
|
+
{hintText && <HintText id={hintTextId}>{hintText}</HintText>}
|
|
58
59
|
</div>
|
|
59
60
|
</>
|
|
60
61
|
);
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import React, { useEffect, useRef } from 'react';
|
|
2
2
|
import { CheckboxRadioContext } from '../../utils/context';
|
|
3
|
-
|
|
4
|
-
// @ts-ignore
|
|
3
|
+
// @ts-expect-error no types from core SGDS
|
|
5
4
|
import DSCheckboxes from '@scottish-government/design-system/src/forms/checkbox/checkboxes'
|
|
5
|
+
import { CheckboxGroupProps } from './types';
|
|
6
6
|
|
|
7
7
|
export const CheckboxGroup = ({
|
|
8
8
|
children,
|
|
9
9
|
className,
|
|
10
10
|
isSmall,
|
|
11
11
|
...props
|
|
12
|
-
}:
|
|
12
|
+
}: CheckboxGroupProps) => {
|
|
13
13
|
const ref = useRef(null);
|
|
14
14
|
|
|
15
15
|
useEffect(() => {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CheckboxRadioBase } from '../../shared-types';
|
|
2
|
+
|
|
3
|
+
export interface CheckboxGroupProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
4
|
+
isSmall?: boolean;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface CheckboxProps extends CheckboxRadioBase<HTMLInputElement> {
|
|
8
|
+
isExclusive?: boolean;
|
|
9
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import Icon from '../../common/Icon';
|
|
2
2
|
import WrapperTag from '../../common/WrapperTag';
|
|
3
|
+
import { ConfirmationMessageProps } from './types';
|
|
3
4
|
|
|
4
5
|
const ConfirmationMessage = ({
|
|
5
6
|
ariaLive = 'polite',
|
|
@@ -8,7 +9,7 @@ const ConfirmationMessage = ({
|
|
|
8
9
|
headingLevel = 'h3',
|
|
9
10
|
title,
|
|
10
11
|
...props
|
|
11
|
-
}:
|
|
12
|
+
}: ConfirmationMessageProps) => {
|
|
12
13
|
return (
|
|
13
14
|
<div
|
|
14
15
|
aria-live={ariaLive}
|
|
@@ -16,7 +16,7 @@ const meta = {
|
|
|
16
16
|
},
|
|
17
17
|
args: {
|
|
18
18
|
children: <>
|
|
19
|
-
<ContentsNav.Item
|
|
19
|
+
<ContentsNav.Item isCurrent>
|
|
20
20
|
Apply for Blue Badge
|
|
21
21
|
</ContentsNav.Item>
|
|
22
22
|
<ContentsNav.Item href="#2">
|
|
@@ -39,4 +39,8 @@ export default meta;
|
|
|
39
39
|
type Story = StoryObj<typeof meta>;
|
|
40
40
|
|
|
41
41
|
export const Default: Story = {
|
|
42
|
+
args: {
|
|
43
|
+
ariaLabel: 'Contents navigation',
|
|
44
|
+
title: 'Contents'
|
|
45
|
+
}
|
|
42
46
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { ContentsNavItemProps, ContentsNavProps } from './types';
|
|
2
3
|
|
|
3
4
|
const ContentsNavItem = ({
|
|
4
5
|
children,
|
|
5
6
|
isCurrent,
|
|
6
7
|
href,
|
|
7
8
|
linkComponent
|
|
8
|
-
}:
|
|
9
|
+
}: ContentsNavItemProps) => {
|
|
9
10
|
const classNames = ['ds_contents-nav__link'];
|
|
10
11
|
let ariaCurrent: React.AriaAttributes["aria-current"];
|
|
11
12
|
|
|
@@ -39,7 +40,7 @@ const ContentsNav = ({
|
|
|
39
40
|
className,
|
|
40
41
|
title = 'Contents',
|
|
41
42
|
...props
|
|
42
|
-
}:
|
|
43
|
+
}: ContentsNavProps) => {
|
|
43
44
|
return (
|
|
44
45
|
<nav
|
|
45
46
|
aria-label={ariaLabel}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { LinkComponent } from "../../shared-types";
|
|
2
|
+
|
|
3
|
+
export interface ContentsNavItemProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
4
|
+
isCurrent?: boolean;
|
|
5
|
+
linkComponent?: LinkComponent;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface ContentsNavProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
9
|
+
ariaLabel: React.AriaAttributes['aria-label'];
|
|
10
|
+
title: string;
|
|
11
|
+
}
|
|
@@ -12,9 +12,9 @@ const meta = {
|
|
|
12
12
|
},
|
|
13
13
|
args: {
|
|
14
14
|
children: [
|
|
15
|
-
<Button className="js-accept-all-cookies"
|
|
16
|
-
<Button className="js-accept-essential-cookies"
|
|
17
|
-
<a href="/cookies/">Set cookie preferences</a>
|
|
15
|
+
<Button className="js-accept-all-cookies" isSmall buttonStyle="secondary" key="1">Accept all cookies</Button>,
|
|
16
|
+
<Button className="js-accept-essential-cookies" isSmall buttonStyle="secondary" key="2">Use essential cookies only</Button>,
|
|
17
|
+
<a href="/cookies/" key="3">Set cookie preferences</a>
|
|
18
18
|
]
|
|
19
19
|
}
|
|
20
20
|
} satisfies Meta<typeof CookieBanner.Buttons>;
|
|
@@ -12,13 +12,13 @@ const meta = {
|
|
|
12
12
|
},
|
|
13
13
|
args: {
|
|
14
14
|
children: [
|
|
15
|
-
<p key="
|
|
15
|
+
<p key="1">We use <a href="/cookies/">cookies</a> to collect anonymous data to help us improve your site browsing
|
|
16
16
|
experience.</p>,
|
|
17
|
-
<p key="
|
|
18
|
-
To only allow the cookies that make the site work, click
|
|
19
|
-
<CookieBanner.Buttons>
|
|
20
|
-
<Button className="js-accept-all-cookies"
|
|
21
|
-
<Button className="js-accept-essential-cookies"
|
|
17
|
+
<p key="2">Click ‘Accept all cookies’ to agree to all cookies that collect anonymous data.
|
|
18
|
+
To only allow the cookies that make the site work, click ‘Use essential cookies only.’ Visit ‘Set cookie preferences’ to control specific cookies.</p>,
|
|
19
|
+
<CookieBanner.Buttons key="3">
|
|
20
|
+
<Button className="js-accept-all-cookies" isSmall buttonStyle="secondary">Accept all cookies</Button>
|
|
21
|
+
<Button className="js-accept-essential-cookies" isSmall buttonStyle="secondary">Use essential cookies only</Button>
|
|
22
22
|
<a href="/cookies/">Set cookie preferences</a>
|
|
23
23
|
</CookieBanner.Buttons>
|
|
24
24
|
]
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
import { test, expect } from 'vitest';
|
|
7
7
|
import { render } from '@testing-library/react';
|
|
8
8
|
import CookieBanner from './CookieBanner';
|
|
9
|
+
import Button from '../Button/Button';
|
|
9
10
|
|
|
10
11
|
const BANNER_TEXT = 'We need to tell you about something';
|
|
11
12
|
|
|
@@ -16,6 +17,11 @@ test('cookie banner renders correctly', () => {
|
|
|
16
17
|
render(
|
|
17
18
|
<CookieBanner>
|
|
18
19
|
{BANNER_TEXT}
|
|
20
|
+
<CookieBanner.Buttons>
|
|
21
|
+
<Button className="js-accept-all-cookies" isSmall buttonStyle="secondary">Accept all cookies</Button>
|
|
22
|
+
<Button className="js-accept-essential-cookies" isSmall buttonStyle="secondary">Use essential cookies only</Button>
|
|
23
|
+
<a href="/cookies/">Set cookie preferences</a>
|
|
24
|
+
</CookieBanner.Buttons>
|
|
19
25
|
</CookieBanner>
|
|
20
26
|
);
|
|
21
27
|
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
|
|
2
|
+
import { useEffect, useRef } from 'react';
|
|
2
3
|
import AbstractNotificationBanner from '../../common/AbstractNotificationBanner';
|
|
3
|
-
// @ts-
|
|
4
|
+
// @ts-expect-error no types from core SGDS
|
|
4
5
|
import DSCookieBanner from '@scottish-government/design-system/src/components/cookie-notification/cookie-notification.js';
|
|
6
|
+
import { AbstractNotificationBannerProps } from '../../common/AbstractNotificationBanner/types';
|
|
5
7
|
|
|
6
8
|
const CookieBanner = ({
|
|
7
9
|
children,
|
|
8
10
|
className,
|
|
9
|
-
title,
|
|
11
|
+
title = 'Information',
|
|
10
12
|
...props
|
|
11
|
-
}:
|
|
13
|
+
}: AbstractNotificationBannerProps) => {
|
|
14
|
+
const ref = useRef(null);
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (ref.current) {
|
|
18
|
+
new DSCookieBanner(ref.current).init();
|
|
19
|
+
}
|
|
20
|
+
}, [ref]);
|
|
12
21
|
|
|
13
22
|
return (
|
|
14
23
|
<>
|
|
@@ -20,6 +29,7 @@ const CookieBanner = ({
|
|
|
20
29
|
className
|
|
21
30
|
].join(' ')}
|
|
22
31
|
data-module="ds-cookie-notification"
|
|
32
|
+
ref={ref}
|
|
23
33
|
title={title}
|
|
24
34
|
{...props}
|
|
25
35
|
>
|
|
@@ -24,8 +24,6 @@ test('date picker renders correctly', () => {
|
|
|
24
24
|
expect(label.tagName).toEqual('LABEL');
|
|
25
25
|
expect(textInput).toHaveClass('ds_input', 'ds_input--fixed-10');
|
|
26
26
|
expect(textInput.id).toEqual(DATE_PICKER_ID);
|
|
27
|
-
|
|
28
|
-
// todo: check for DS script being fired
|
|
29
27
|
});
|
|
30
28
|
|
|
31
29
|
test('date picker with disabled dates', () => {
|
|
@@ -71,9 +69,6 @@ test('date picker with custom icon path', () => {
|
|
|
71
69
|
iconPath={ICON_PATH}
|
|
72
70
|
/>
|
|
73
71
|
);
|
|
74
|
-
const datePicker = screen.getAllByRole('generic')[1];
|
|
75
|
-
const label = within(datePicker).getByText(LABEL_TEXT);
|
|
76
|
-
const textInput = within(datePicker).getByRole('textbox');
|
|
77
72
|
|
|
78
73
|
// todo
|
|
79
74
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
|
-
// @ts-
|
|
2
|
+
// @ts-expect-error no types from core SGDS
|
|
3
3
|
import DSDatePicker from '@scottish-government/design-system/src/components/date-picker/date-picker';
|
|
4
4
|
import ErrorMessage from '../ErrorMessage';
|
|
5
5
|
import TextInput from '../TextInput';
|
|
6
|
+
import { DatePickerProps } from './types';
|
|
6
7
|
|
|
7
8
|
const DatePicker = ({
|
|
8
9
|
className,
|
|
@@ -23,7 +24,7 @@ const DatePicker = ({
|
|
|
23
24
|
value,
|
|
24
25
|
width = 'fixed-10',
|
|
25
26
|
...props
|
|
26
|
-
}:
|
|
27
|
+
}: DatePickerProps) => {
|
|
27
28
|
const ref = useRef(null);
|
|
28
29
|
|
|
29
30
|
useEffect(() => {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { InputWidth } from "../../shared-types";
|
|
2
|
+
|
|
3
|
+
export interface DatePickerProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
4
|
+
dateSelectCallback?: (date: Date) => void;
|
|
5
|
+
disabledDates?: string;
|
|
6
|
+
hasError?: boolean;
|
|
7
|
+
errorMessage?: string;
|
|
8
|
+
id: string;
|
|
9
|
+
hintText?: string;
|
|
10
|
+
iconPath?: string;
|
|
11
|
+
label: string;
|
|
12
|
+
maxDate?: string;
|
|
13
|
+
minDate?: string;
|
|
14
|
+
isMultiple?: boolean;
|
|
15
|
+
name?: string;
|
|
16
|
+
onBlur?: React.EventHandler<React.FocusEvent>;
|
|
17
|
+
onChange?: React.EventHandler<React.FormEvent>;
|
|
18
|
+
value?: string;
|
|
19
|
+
width?: InputWidth;
|
|
20
|
+
}
|
|
@@ -9,7 +9,7 @@ const meta = {
|
|
|
9
9
|
argTypes: {
|
|
10
10
|
children: argTypes.children(),
|
|
11
11
|
summary: {
|
|
12
|
-
description: 'Text to use for the details component\'s
|
|
12
|
+
description: 'Text to use for the details component\'s \'summary\' element',
|
|
13
13
|
type: {
|
|
14
14
|
name: 'string',
|
|
15
15
|
required: true
|