@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
|
@@ -8,16 +8,16 @@ const meta = {
|
|
|
8
8
|
component: SkipLinks,
|
|
9
9
|
argTypes: {
|
|
10
10
|
mainContentId: {
|
|
11
|
-
description: 'The id attribute of the
|
|
11
|
+
description: 'The id attribute of the \'main content\' element to link to',
|
|
12
12
|
type: 'string'
|
|
13
13
|
},
|
|
14
14
|
mainLinkText: {
|
|
15
|
-
description: 'The text to use for the
|
|
15
|
+
description: 'The text to use for the \'main content\' link',
|
|
16
16
|
type: 'string'
|
|
17
17
|
},
|
|
18
18
|
isStatic: {
|
|
19
19
|
control: 'boolean',
|
|
20
|
-
description: 'Use the
|
|
20
|
+
description: 'Use the \'static\' display variant'
|
|
21
21
|
},
|
|
22
22
|
children: argTypes.children()
|
|
23
23
|
},
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import React, { useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
// @ts-ignore
|
|
2
|
+
// @ts-expect-error no types from core SGDS
|
|
4
3
|
import dsSkipLinks from '@scottish-government/design-system/src/components/skip-links/skip-links';
|
|
4
|
+
import { SkipLinksLinkProps, SkipLinksProps } from './types';
|
|
5
5
|
|
|
6
6
|
const Link = ({
|
|
7
7
|
children,
|
|
8
8
|
fragmentId
|
|
9
|
-
}:
|
|
9
|
+
}: SkipLinksLinkProps) => {
|
|
10
10
|
return (
|
|
11
11
|
<li
|
|
12
12
|
className="ds_skip-links__item"
|
|
@@ -22,7 +22,7 @@ const SkipLinks = ({
|
|
|
22
22
|
mainLinkText = 'Skip to main content',
|
|
23
23
|
isStatic,
|
|
24
24
|
...props
|
|
25
|
-
}:
|
|
25
|
+
}: SkipLinksProps) => {
|
|
26
26
|
|
|
27
27
|
useEffect(() => {
|
|
28
28
|
dsSkipLinks.init();
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface SkipLinksLinkProps extends React.AllHTMLAttributes<HTMLLIElement> {
|
|
2
|
+
fragmentId: string;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export interface SkipLinksProps extends React.AllHTMLAttributes<HTMLDivElement> {
|
|
6
|
+
mainContentId?: string;
|
|
7
|
+
mainLinkText?: string;
|
|
8
|
+
isStatic?: boolean;
|
|
9
|
+
}
|
|
@@ -16,17 +16,6 @@ const ACTIONS = [
|
|
|
16
16
|
}
|
|
17
17
|
];
|
|
18
18
|
|
|
19
|
-
const ITEMS = [
|
|
20
|
-
{
|
|
21
|
-
title: 'Phone number',
|
|
22
|
-
value: '0123 456 7890'
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
title: 'Address',
|
|
26
|
-
value: `Victoria Quay\nEdinburgh\nEH6 6QQ`
|
|
27
|
-
}
|
|
28
|
-
];
|
|
29
|
-
|
|
30
19
|
const TITLE_TEXT = 'Joe Bloggs';
|
|
31
20
|
|
|
32
21
|
test('summary card renders correctly', () => {
|
|
@@ -3,6 +3,8 @@ import React, { Children, useId } from 'react';
|
|
|
3
3
|
import ActionLink from '../../common/ActionLink';
|
|
4
4
|
import ConditionalWrapper from '../../common/ConditionalWrapper';
|
|
5
5
|
import WrapperTag from "../../common/WrapperTag";
|
|
6
|
+
import { SummaryCardProps } from './types';
|
|
7
|
+
import { ActionLinkProps } from '../../common/ActionLink/types';
|
|
6
8
|
|
|
7
9
|
const SummaryCard = ({
|
|
8
10
|
children,
|
|
@@ -10,14 +12,14 @@ const SummaryCard = ({
|
|
|
10
12
|
headingLevel = 'h3',
|
|
11
13
|
title,
|
|
12
14
|
...props
|
|
13
|
-
}:
|
|
14
|
-
|
|
15
|
-
|
|
15
|
+
}: SummaryCardProps) => {
|
|
16
|
+
const actions: React.ReactElement[] = [];
|
|
17
|
+
const remainingChildren: React.ReactElement[] = [];
|
|
16
18
|
|
|
17
19
|
const describedById = useId();
|
|
18
20
|
|
|
19
21
|
Children.forEach(children, (child: React.ReactNode) => {
|
|
20
|
-
const thisChild = child as React.ReactElement<
|
|
22
|
+
const thisChild = child as React.ReactElement<ActionLinkProps>;
|
|
21
23
|
if (thisChild && thisChild.type === ActionLink) {
|
|
22
24
|
actions.push(React.cloneElement(thisChild, { describedby: describedById }));
|
|
23
25
|
} else {
|
|
@@ -14,7 +14,7 @@ const meta = {
|
|
|
14
14
|
)
|
|
15
15
|
],
|
|
16
16
|
argTypes: {
|
|
17
|
-
|
|
17
|
+
title: {
|
|
18
18
|
description: 'Title of the summary list item.',
|
|
19
19
|
type: {
|
|
20
20
|
name: 'string',
|
|
@@ -26,16 +26,16 @@ const meta = {
|
|
|
26
26
|
args: {
|
|
27
27
|
title: 'Contact details',
|
|
28
28
|
children: [
|
|
29
|
-
<SummaryList.Value name="Email">
|
|
29
|
+
<SummaryList.Value name="Email" key="1">
|
|
30
30
|
email@gov.scot
|
|
31
31
|
</SummaryList.Value>,
|
|
32
|
-
<SummaryList.Value name="Telephone">
|
|
32
|
+
<SummaryList.Value name="Telephone" key="2">
|
|
33
33
|
0123 456 7890
|
|
34
34
|
</SummaryList.Value>,
|
|
35
|
-
<SummaryList.Action href="foo">
|
|
35
|
+
<SummaryList.Action href="foo" key="3">
|
|
36
36
|
Change
|
|
37
37
|
</SummaryList.Action>,
|
|
38
|
-
<SummaryList.Action onclick={function w(){}}>
|
|
38
|
+
<SummaryList.Action onclick={function w(){}} key="4">
|
|
39
39
|
Delete
|
|
40
40
|
</SummaryList.Action>
|
|
41
41
|
]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { test, expect, vi } from 'vitest';
|
|
2
|
-
import { within, render, screen
|
|
2
|
+
import { within, render, screen } from '@testing-library/react';
|
|
3
3
|
import SummaryList from './SummaryList';
|
|
4
4
|
|
|
5
5
|
const ONCLICK_FUNCTION = vi.fn();
|
|
@@ -7,11 +7,6 @@ const TITLE = 'Name';
|
|
|
7
7
|
const VALUE_1 = 'Jane Smith';
|
|
8
8
|
const VALUE_2 = 'Tony Brown';
|
|
9
9
|
|
|
10
|
-
const ACTION_HREF = "#foo"
|
|
11
|
-
const ACTION_ONCLICK = ONCLICK_FUNCTION;
|
|
12
|
-
const ACTION_TEXT = 'Name';
|
|
13
|
-
const DESCRIBEDBY_ID = 'q1-name';
|
|
14
|
-
|
|
15
10
|
test('summary list renders correctly', () => {
|
|
16
11
|
render(
|
|
17
12
|
<SummaryList data-testid="summarylist">
|
|
@@ -2,18 +2,20 @@ import React, { Children, useId } from 'react';
|
|
|
2
2
|
|
|
3
3
|
import ActionLink from '../../common/ActionLink';
|
|
4
4
|
import ConditionalWrapper from '../../common/ConditionalWrapper';
|
|
5
|
+
import { SummaryListItemProps, SummaryListProps } from './types';
|
|
6
|
+
import { ActionLinkProps } from '@/src/common/ActionLink/types';
|
|
5
7
|
|
|
6
8
|
const Item = ({
|
|
7
9
|
children,
|
|
8
10
|
title
|
|
9
|
-
}:
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
}: SummaryListItemProps) => {
|
|
12
|
+
const values: React.ReactElement[] = [];
|
|
13
|
+
const actions: React.ReactElement[] = [];
|
|
12
14
|
|
|
13
15
|
const describedById = useId();
|
|
14
16
|
|
|
15
17
|
Children.forEach(children, (child: React.ReactNode) => {
|
|
16
|
-
const thisChild = child as React.ReactElement<
|
|
18
|
+
const thisChild = child as React.ReactElement<ActionLinkProps>;
|
|
17
19
|
if (thisChild && thisChild.type === Value) {
|
|
18
20
|
values.push(thisChild);
|
|
19
21
|
} else if (thisChild && thisChild.type === ActionLink) {
|
|
@@ -64,7 +66,7 @@ const Item = ({
|
|
|
64
66
|
|
|
65
67
|
const Value = ({
|
|
66
68
|
children
|
|
67
|
-
}:
|
|
69
|
+
}: React.AllHTMLAttributes<HTMLElement>) => {
|
|
68
70
|
return (
|
|
69
71
|
<q className="ds_summary-list__answer">{children}</q>
|
|
70
72
|
);
|
|
@@ -75,7 +77,7 @@ const SummaryList = ({
|
|
|
75
77
|
className,
|
|
76
78
|
isBorderless,
|
|
77
79
|
...props
|
|
78
|
-
}:
|
|
80
|
+
}: SummaryListProps) => {
|
|
79
81
|
return (
|
|
80
82
|
<ol
|
|
81
83
|
className={[
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
|
-
// @ts-
|
|
2
|
+
// @ts-expect-error no types from core SGDS
|
|
3
3
|
import DSTable from '@scottish-government/design-system/src/components/table/table';
|
|
4
|
+
import { TableProps } from './types';
|
|
4
5
|
|
|
5
6
|
const Table = ({
|
|
6
7
|
children,
|
|
7
8
|
className,
|
|
8
9
|
smallscreen,
|
|
9
10
|
...props
|
|
10
|
-
}:
|
|
11
|
+
}: TableProps) => {
|
|
11
12
|
const ref = useRef(null);
|
|
12
13
|
|
|
13
14
|
useEffect(() => {
|
|
@@ -17,15 +17,15 @@ const meta = {
|
|
|
17
17
|
children: argTypes.children()
|
|
18
18
|
},
|
|
19
19
|
args: {
|
|
20
|
-
baseId: 'my-tabs',
|
|
21
20
|
children: [
|
|
22
|
-
<h3>Search for training courses and funding</h3>,
|
|
23
|
-
<p>A wide range of training courses for your employees are available.</p>,
|
|
24
|
-
<p>Opportunities include distance learning, short courses and vocational training.</p>,
|
|
25
|
-
<p><a href="#">Visit My World of Work to search for training courses</a>.</p>,
|
|
26
|
-
<p>You can also <a href="#">search for training courses, and funding towards training</a>.</p>
|
|
21
|
+
<h3 key="1">Search for training courses and funding</h3>,
|
|
22
|
+
<p key="2">A wide range of training courses for your employees are available.</p>,
|
|
23
|
+
<p key="3">Opportunities include distance learning, short courses and vocational training.</p>,
|
|
24
|
+
<p key="4"><a href="#">Visit My World of Work to search for training courses</a>.</p>,
|
|
25
|
+
<p key="5">You can also <a href="#">search for training courses, and funding towards training</a>.</p>
|
|
27
26
|
],
|
|
28
|
-
tabLabel: 'Courses and funding'
|
|
27
|
+
tabLabel: 'Courses and funding',
|
|
28
|
+
id: 'my-tab'
|
|
29
29
|
}
|
|
30
30
|
} satisfies Meta<typeof Tabs.Item>;
|
|
31
31
|
|
|
@@ -35,14 +35,14 @@ const meta = {
|
|
|
35
35
|
args: {
|
|
36
36
|
baseId: 'my-tabs',
|
|
37
37
|
children: [
|
|
38
|
-
<Tabs.Item key="foo" tabLabel="Courses and funding">
|
|
38
|
+
<Tabs.Item id="foo" key="foo" tabLabel="Courses and funding">
|
|
39
39
|
<h3>Search for training courses and funding</h3>
|
|
40
40
|
<p>A wide range of training courses for your employees are available.</p>
|
|
41
41
|
<p>Opportunities include distance learning, short courses and vocational training.</p>
|
|
42
42
|
<p><a href="#">Visit My World of Work to search for training courses</a>.</p>
|
|
43
43
|
<p>You can also <a href="#">search for training courses, and funding towards training</a>.</p>
|
|
44
44
|
</Tabs.Item>,
|
|
45
|
-
<Tabs.Item key="bar" tabLabel="Choosing apprenticeships">
|
|
45
|
+
<Tabs.Item id="bar" key="bar" tabLabel="Choosing apprenticeships">
|
|
46
46
|
<h3>Choosing an apprenticeship for your business</h3>
|
|
47
47
|
<p>Apprenticeships can help you address skills gaps in your business. The government provides help with the cost of training an apprentice.</p>
|
|
48
48
|
<p>There are 3 different types of apprenticeship:</p>
|
|
@@ -53,7 +53,7 @@ const meta = {
|
|
|
53
53
|
</ul>
|
|
54
54
|
<p>You can find more information on the <a href="#">apprenticeships.scot</a> website.</p>
|
|
55
55
|
</Tabs.Item>,
|
|
56
|
-
<Tabs.Item key="baz" tabLabel="Extra skills support">
|
|
56
|
+
<Tabs.Item id="baz" key="baz" tabLabel="Extra skills support">
|
|
57
57
|
<h3>Extra skills support</h3>
|
|
58
58
|
<p>The <a href="#">Skills for Growth</a> service can offer skills advice to businesses with fewer than 250 employees.</p>
|
|
59
59
|
<p>Businesses of any size can get skills advice by completing a <a href="#">skills support request form</a>.</p>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React, { Children, 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 DSTabs from '@scottish-government/design-system/src/components/tabs/tabs';
|
|
5
|
+
import { TabListItemProps, TabsItemProps, TabsProps } from './types';
|
|
5
6
|
|
|
6
7
|
const TabItem = ({
|
|
7
8
|
isBorderless,
|
|
@@ -10,7 +11,7 @@ const TabItem = ({
|
|
|
10
11
|
id,
|
|
11
12
|
tabLabel,
|
|
12
13
|
...props
|
|
13
|
-
}:
|
|
14
|
+
}: TabsItemProps) => {
|
|
14
15
|
return (
|
|
15
16
|
<div
|
|
16
17
|
className={[
|
|
@@ -18,6 +19,7 @@ const TabItem = ({
|
|
|
18
19
|
!isBorderless && 'ds_tabs__content--bordered',
|
|
19
20
|
className
|
|
20
21
|
].join(' ')}
|
|
22
|
+
data-label={tabLabel}
|
|
21
23
|
id={id}
|
|
22
24
|
{...props}
|
|
23
25
|
>
|
|
@@ -29,7 +31,7 @@ const TabItem = ({
|
|
|
29
31
|
const TabListItem = ({
|
|
30
32
|
children,
|
|
31
33
|
href
|
|
32
|
-
}:
|
|
34
|
+
}: TabListItemProps) => {
|
|
33
35
|
return (
|
|
34
36
|
<li className="ds_tabs__tab">
|
|
35
37
|
<a className="ds_tabs__tab-link" href={href}>{children}</a>
|
|
@@ -46,7 +48,7 @@ const Tabs = ({
|
|
|
46
48
|
isManual = false,
|
|
47
49
|
title = 'Contents',
|
|
48
50
|
...props
|
|
49
|
-
}:
|
|
51
|
+
}: TabsProps) => {
|
|
50
52
|
const ref = useRef(null);
|
|
51
53
|
|
|
52
54
|
const headingId = `${baseId}-heading`;
|
|
@@ -58,7 +60,7 @@ const Tabs = ({
|
|
|
58
60
|
}, [ref]);
|
|
59
61
|
|
|
60
62
|
const processedItems = Children.map(children, child => {
|
|
61
|
-
const thisChild = child as React.ReactElement<
|
|
63
|
+
const thisChild = child as React.ReactElement<TabsItemProps>;
|
|
62
64
|
|
|
63
65
|
if (thisChild && thisChild.type === TabItem) {
|
|
64
66
|
return React.cloneElement(thisChild, {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { HeadingLevel } from '../../shared-types';
|
|
2
|
+
|
|
3
|
+
export interface TabsItemProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
4
|
+
isBorderless?: boolean;
|
|
5
|
+
id: string;
|
|
6
|
+
tabLabel: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface TabListItemProps extends React.AllHTMLAttributes<HTMLLIElement> {
|
|
10
|
+
href: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface TabsProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
14
|
+
baseId: string;
|
|
15
|
+
isBorderless?: boolean;
|
|
16
|
+
headingLevel?: HeadingLevel;
|
|
17
|
+
isManual?: boolean;
|
|
18
|
+
title: string;
|
|
19
|
+
}
|
|
@@ -3,6 +3,7 @@ import ConditionalWrapper from '../../common/ConditionalWrapper';
|
|
|
3
3
|
import HintText from '../../common/HintText';
|
|
4
4
|
import ScreenReaderText from '../../common/ScreenReaderText';
|
|
5
5
|
import Tag from '../Tag';
|
|
6
|
+
import { TaskListGroupProps, TaskListItemProps, TaskListProps } from './types';
|
|
6
7
|
|
|
7
8
|
const TaskItem = ({
|
|
8
9
|
children,
|
|
@@ -15,7 +16,7 @@ const TaskItem = ({
|
|
|
15
16
|
tagColour = 'grey',
|
|
16
17
|
title,
|
|
17
18
|
...props
|
|
18
|
-
}:
|
|
19
|
+
}: TaskListItemProps) => {
|
|
19
20
|
if (isComplete) {
|
|
20
21
|
tagColour = 'green';
|
|
21
22
|
statusText = statusText || 'Completed'
|
|
@@ -24,11 +25,13 @@ const TaskItem = ({
|
|
|
24
25
|
const LINK_CLASS = 'ds_task-list__task-link';
|
|
25
26
|
|
|
26
27
|
function getLinkElement(children: React.ReactNode) {
|
|
28
|
+
let linkElement;
|
|
27
29
|
if (linkComponent) {
|
|
28
|
-
|
|
29
|
-
} else
|
|
30
|
-
|
|
30
|
+
linkElement = linkComponent({ className: LINK_CLASS, href, children });
|
|
31
|
+
} else {
|
|
32
|
+
linkElement = <a href={href} className={LINK_CLASS}>{children}</a>;
|
|
31
33
|
}
|
|
34
|
+
return linkElement as React.JSX.Element;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
return (
|
|
@@ -77,7 +80,7 @@ const TaskGroup = ({
|
|
|
77
80
|
intro,
|
|
78
81
|
title,
|
|
79
82
|
...props
|
|
80
|
-
}:
|
|
83
|
+
}: TaskListGroupProps) => {
|
|
81
84
|
return (
|
|
82
85
|
<li
|
|
83
86
|
className={[
|
|
@@ -101,12 +104,12 @@ const TaskList = ({
|
|
|
101
104
|
headingId = 'task-list',
|
|
102
105
|
title,
|
|
103
106
|
...props
|
|
104
|
-
}:
|
|
107
|
+
}: TaskListProps) => {
|
|
105
108
|
let taskCount = 0;
|
|
106
|
-
|
|
109
|
+
const incompleteTaskIds: string[] = [];
|
|
107
110
|
let completedTasksCount = 0;
|
|
108
111
|
|
|
109
|
-
function processChild(item:
|
|
112
|
+
function processChild(item: React.JSX.Element) {
|
|
110
113
|
if (item.type.displayName === 'TaskList.Item') {
|
|
111
114
|
taskCount = taskCount + 1;
|
|
112
115
|
|
|
@@ -131,7 +134,7 @@ const TaskList = ({
|
|
|
131
134
|
}
|
|
132
135
|
|
|
133
136
|
Children.forEach(children, child => {
|
|
134
|
-
processChild(child);
|
|
137
|
+
processChild(child as React.JSX.Element);
|
|
135
138
|
});
|
|
136
139
|
|
|
137
140
|
return (
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LinkComponent, TagColour } from '../../shared-types';
|
|
2
|
+
|
|
3
|
+
export interface TaskListGroupProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
4
|
+
intro?: string;
|
|
5
|
+
title: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface TaskListItemProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
9
|
+
href?: string;
|
|
10
|
+
id?: string;
|
|
11
|
+
isComplete?: boolean;
|
|
12
|
+
linkComponent?: LinkComponent;
|
|
13
|
+
statusText?: string;
|
|
14
|
+
tagColour?: TagColour;
|
|
15
|
+
title: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface TaskListProps extends React.AllHTMLAttributes<HTMLElement> {
|
|
19
|
+
headingId?: string;
|
|
20
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
|
-
// @ts-
|
|
2
|
+
// @ts-expect-error no types from core SGDS
|
|
3
3
|
import DSCharacterCount from '@scottish-government/design-system/src/forms/character-count/character-count';
|
|
4
4
|
import Button from '../Button';
|
|
5
5
|
import ConditionalWrapper from '../../common/ConditionalWrapper';
|
|
6
6
|
import ErrorMessage from '../ErrorMessage';
|
|
7
7
|
import HintText from '../../common/HintText';
|
|
8
|
+
import { TextInputProps } from './types';
|
|
8
9
|
|
|
9
10
|
const TextInput = ({
|
|
10
11
|
buttonIcon,
|
|
11
12
|
buttonText,
|
|
12
|
-
children,
|
|
13
13
|
className,
|
|
14
14
|
countThreshold,
|
|
15
15
|
width,
|
|
@@ -29,7 +29,7 @@ const TextInput = ({
|
|
|
29
29
|
type = 'text',
|
|
30
30
|
value,
|
|
31
31
|
...props
|
|
32
|
-
}:
|
|
32
|
+
}: TextInputProps) => {
|
|
33
33
|
const errorMessageId = `error-message-${id}`;
|
|
34
34
|
const hintTextId = `hint-text-${id}`;
|
|
35
35
|
const ref = useRef(null);
|
|
@@ -45,13 +45,13 @@ const TextInput = ({
|
|
|
45
45
|
}
|
|
46
46
|
}, [ref]);
|
|
47
47
|
|
|
48
|
-
function handleBlur(event: React.FocusEvent) {
|
|
48
|
+
function handleBlur(event: React.FocusEvent<HTMLInputElement>) {
|
|
49
49
|
if (typeof onBlur === 'function') {
|
|
50
50
|
onBlur(event);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
function handleChange(event: React.ChangeEvent) {
|
|
54
|
+
function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
|
|
55
55
|
if (typeof onChange === 'function') {
|
|
56
56
|
onChange(event);
|
|
57
57
|
}
|
|
@@ -63,7 +63,7 @@ const TextInput = ({
|
|
|
63
63
|
wrapper={(children: React.JSX.Element) => <div ref={ref} data-threshold={countThreshold} data-module="ds-character-count">{children}</div>}
|
|
64
64
|
>
|
|
65
65
|
<label className="ds_label" htmlFor={id}>{label}</label>
|
|
66
|
-
{hintText && <HintText id={hintTextId}
|
|
66
|
+
{hintText && <HintText id={hintTextId}>{hintText}</HintText>}
|
|
67
67
|
{errorMessage && <ErrorMessage id={errorMessageId}>{errorMessage}</ErrorMessage>}
|
|
68
68
|
<ConditionalWrapper
|
|
69
69
|
condition={hasButton || typeof isCurrency !== 'undefined' && isCurrency}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IconName, InputWidth, TextInputBase } from '../../shared-types';
|
|
2
|
+
|
|
3
|
+
export interface TextInputProps extends TextInputBase<HTMLInputElement> {
|
|
4
|
+
buttonIcon?: IconName;
|
|
5
|
+
buttonText?: string;
|
|
6
|
+
className?: string;
|
|
7
|
+
currencySymbol?: string;
|
|
8
|
+
hasButton?: boolean;
|
|
9
|
+
isCurrency?: boolean;
|
|
10
|
+
type?: string;
|
|
11
|
+
width?: InputWidth;
|
|
12
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
|
-
// @ts-
|
|
2
|
+
// @ts-expect-error no types from core SGDS
|
|
3
3
|
import DSCharacterCount from '@scottish-government/design-system/src/forms/character-count/character-count';
|
|
4
4
|
import ConditionalWrapper from '../../common/ConditionalWrapper';
|
|
5
5
|
import ErrorMessage from '../ErrorMessage';
|
|
6
6
|
import HintText from '../../common/HintText';
|
|
7
|
+
import { TextInputBase } from '../../shared-types';
|
|
7
8
|
|
|
8
9
|
const Textarea = ({
|
|
9
10
|
className,
|
|
@@ -21,7 +22,7 @@ const Textarea = ({
|
|
|
21
22
|
rows = 4,
|
|
22
23
|
value,
|
|
23
24
|
...props
|
|
24
|
-
}:
|
|
25
|
+
}: TextInputBase<HTMLTextAreaElement>) => {
|
|
25
26
|
const errorMessageId = `error-message-${id}`;
|
|
26
27
|
const hintTextId = `hint-text-${id}`;
|
|
27
28
|
const ref = useRef(null);
|
|
@@ -36,13 +37,13 @@ const Textarea = ({
|
|
|
36
37
|
}
|
|
37
38
|
}, [ref]);
|
|
38
39
|
|
|
39
|
-
function handleBlur(event: React.FocusEvent) {
|
|
40
|
+
function handleBlur(event: React.FocusEvent<HTMLTextAreaElement>) {
|
|
40
41
|
if (typeof onBlur === 'function') {
|
|
41
42
|
onBlur(event);
|
|
42
43
|
}
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
function handleChange(event: React.ChangeEvent) {
|
|
46
|
+
function handleChange(event: React.ChangeEvent<HTMLTextAreaElement>) {
|
|
46
47
|
if (typeof onChange === 'function') {
|
|
47
48
|
onChange(event);
|
|
48
49
|
}
|
|
@@ -54,7 +55,7 @@ const Textarea = ({
|
|
|
54
55
|
wrapper={(children: React.JSX.Element) => <div ref={ref} data-threshold={countThreshold} data-module="ds-character-count">{children}</div>}
|
|
55
56
|
>
|
|
56
57
|
<label className="ds_label" htmlFor={id}>{label}</label>
|
|
57
|
-
{hintText && <HintText id={hintTextId}
|
|
58
|
+
{hintText && <HintText id={hintTextId}>{hintText}</HintText>}
|
|
58
59
|
{errorMessage && <ErrorMessage id={errorMessageId}>{errorMessage}</ErrorMessage>}
|
|
59
60
|
|
|
60
61
|
<textarea
|
|
@@ -6,7 +6,9 @@ import { fireEvent, render, screen } from '@testing-library/react';
|
|
|
6
6
|
|
|
7
7
|
import useTracking from './useTracking';
|
|
8
8
|
|
|
9
|
-
const Link = ({ children }
|
|
9
|
+
const Link = ({ children }: {
|
|
10
|
+
children: React.ReactNode;
|
|
11
|
+
}) => <a href="#">{children}</a>;
|
|
10
12
|
|
|
11
13
|
const Links = () => {
|
|
12
14
|
useTracking();
|
|
@@ -45,9 +47,7 @@ test('text tracking on component render', async () => {
|
|
|
45
47
|
|
|
46
48
|
const button = screen.getByRole('button');
|
|
47
49
|
const firstLink = screen.getByText('First link');
|
|
48
|
-
|
|
49
|
-
// todo: this will fail until the tracking script in DS core is updated to use textContent instead of innerText
|
|
50
|
-
// expect(firstLink).toHaveAttribute('data-section', SECTION_ONE_TEXT);
|
|
50
|
+
expect(firstLink).toHaveAttribute('data-section', SECTION_ONE_TEXT);
|
|
51
51
|
|
|
52
52
|
fireEvent(
|
|
53
53
|
button,
|
|
@@ -58,7 +58,5 @@ test('text tracking on component render', async () => {
|
|
|
58
58
|
));
|
|
59
59
|
|
|
60
60
|
const secondLink = await screen.findByText('Second link')
|
|
61
|
-
|
|
62
|
-
// todo: this will fail until the tracking script in DS core is updated to use textContent instead of innerText
|
|
63
|
-
// expect(secondLink).toHaveAttribute('data-section', SECTION_TWO_TEXT);
|
|
61
|
+
expect(secondLink).toHaveAttribute('data-section', SECTION_TWO_TEXT);
|
|
64
62
|
});
|