@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
package/.storybook/main.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import type { StorybookConfig } from '@storybook/react-vite';
|
|
2
2
|
|
|
3
3
|
const config: StorybookConfig = {
|
|
4
|
-
|
|
4
|
+
stories: [
|
|
5
5
|
"../src/**/*.mdx",
|
|
6
6
|
"../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"
|
|
7
7
|
],
|
|
8
|
-
|
|
8
|
+
addons: [
|
|
9
9
|
"@chromatic-com/storybook",
|
|
10
10
|
"@storybook/addon-docs",
|
|
11
11
|
"@storybook/addon-onboarding",
|
|
12
12
|
"@storybook/addon-a11y",
|
|
13
13
|
"@storybook/addon-vitest"
|
|
14
14
|
],
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
framework: {
|
|
16
|
+
name: "@storybook/react-vite",
|
|
17
|
+
options: {}
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
|
-
export default config;
|
|
20
|
+
export default config;
|
|
@@ -1,141 +1,182 @@
|
|
|
1
|
+
import { InputType } from "storybook/internal/csf";
|
|
2
|
+
|
|
3
|
+
type OptionsControlType = 'radio' | 'inline-radio' | 'check' | 'inline-check' | 'select' | 'multi-select';
|
|
4
|
+
|
|
5
|
+
type Conditional = (
|
|
6
|
+
{ arg: string; }
|
|
7
|
+
| { global: string; }) & ({ truthy?: boolean | undefined; }
|
|
8
|
+
| { exists: boolean; }
|
|
9
|
+
| { eq: () => void; }
|
|
10
|
+
| { neq: () => void; }
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
type ControlType =
|
|
14
|
+
| 'array'
|
|
15
|
+
| 'boolean'
|
|
16
|
+
| 'color'
|
|
17
|
+
| 'date'
|
|
18
|
+
| 'number'
|
|
19
|
+
| 'range'
|
|
20
|
+
| 'object'
|
|
21
|
+
| OptionsControlType
|
|
22
|
+
| 'text';
|
|
23
|
+
|
|
24
|
+
interface ArgType {
|
|
25
|
+
control?: ControlType | { type: ControlType };
|
|
26
|
+
defaultValue?: string | number | boolean | object | null;
|
|
27
|
+
description?: string;
|
|
28
|
+
if?: Conditional;
|
|
29
|
+
mapping?: { [key: string]: { [option: string]: string | object } };
|
|
30
|
+
name?: string;
|
|
31
|
+
options?: string[];
|
|
32
|
+
table?: {
|
|
33
|
+
category?: string;
|
|
34
|
+
defaultValue?: { summary: string; detail?: string };
|
|
35
|
+
subcategory?: string;
|
|
36
|
+
type?: { summary?: string; detail?: string };
|
|
37
|
+
disable?: boolean;
|
|
38
|
+
};
|
|
39
|
+
type?: string | { name: string; required?: boolean };
|
|
40
|
+
}
|
|
41
|
+
|
|
1
42
|
const SGDSArgTypes = {
|
|
2
|
-
ariaLabel: (options?:
|
|
43
|
+
ariaLabel: (options?: ArgType) => {
|
|
3
44
|
return Object.assign({
|
|
4
45
|
type: 'string'
|
|
5
|
-
}, options);
|
|
46
|
+
}, options) as InputType;
|
|
6
47
|
},
|
|
7
|
-
ariaLive: (options?:
|
|
48
|
+
ariaLive: (options?: ArgType) => {
|
|
8
49
|
return Object.assign({
|
|
9
50
|
options: ['off', 'polite', 'assertive'],
|
|
10
51
|
control: { type: 'select' },
|
|
11
52
|
type: 'string'
|
|
12
|
-
}, options);
|
|
53
|
+
}, options) as InputType;
|
|
13
54
|
},
|
|
14
|
-
children: (options?:
|
|
55
|
+
children: (options?: ArgType) => {
|
|
15
56
|
return Object.assign({
|
|
16
57
|
control: false
|
|
17
|
-
}, options);
|
|
58
|
+
}, options) as InputType;
|
|
18
59
|
},
|
|
19
|
-
countThreshold: (options?:
|
|
60
|
+
countThreshold: (options?: ArgType) => {
|
|
20
61
|
return Object.assign({
|
|
21
62
|
control: {
|
|
22
63
|
type: 'number', min: 1, max: 100, step: 1
|
|
23
64
|
},
|
|
24
65
|
description: 'Percentage threshold to show the character count at',
|
|
25
66
|
type: 'number'
|
|
26
|
-
}, options);
|
|
67
|
+
}, options) as InputType;
|
|
27
68
|
},
|
|
28
|
-
errorMessage: (options?:
|
|
69
|
+
errorMessage: (options?: ArgType) => {
|
|
29
70
|
return Object.assign({
|
|
30
71
|
description: 'Text to use for an error message',
|
|
31
72
|
type: 'string'
|
|
32
|
-
}, options);
|
|
73
|
+
}, options) as InputType;
|
|
33
74
|
},
|
|
34
|
-
hasError: (options?:
|
|
75
|
+
hasError: (options?: ArgType) => {
|
|
35
76
|
return Object.assign({
|
|
36
77
|
control: 'boolean',
|
|
37
78
|
description: 'Whether the field is in an error state'
|
|
38
|
-
}, options);
|
|
79
|
+
}, options) as InputType;
|
|
39
80
|
},
|
|
40
|
-
headingLevel: (options?:
|
|
81
|
+
headingLevel: (options?: ArgType) => {
|
|
41
82
|
return Object.assign({
|
|
42
83
|
description: 'Heading level for the component\'s title',
|
|
43
84
|
options: ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'],
|
|
44
85
|
control: { type: 'select' },
|
|
45
86
|
type: 'string'
|
|
46
|
-
}, options);
|
|
87
|
+
}, options) as InputType;
|
|
47
88
|
},
|
|
48
|
-
hintText: (options?:
|
|
89
|
+
hintText: (options?: ArgType) => {
|
|
49
90
|
return Object.assign({
|
|
50
91
|
description: 'Text to use for the field\'s hint text',
|
|
51
92
|
type: 'string'
|
|
52
|
-
}, options);
|
|
93
|
+
}, options) as InputType;
|
|
53
94
|
},
|
|
54
|
-
href: (options?:
|
|
95
|
+
href: (options?: ArgType) => {
|
|
55
96
|
return Object.assign({
|
|
56
97
|
type: 'string'
|
|
57
|
-
}, options)
|
|
98
|
+
}, options) as InputType
|
|
58
99
|
},
|
|
59
|
-
id: (options?:
|
|
100
|
+
id: (options?: ArgType) => {
|
|
60
101
|
return Object.assign({
|
|
61
102
|
type: {
|
|
62
103
|
required: true,
|
|
63
104
|
name: 'string'
|
|
64
105
|
}
|
|
65
|
-
}, options)
|
|
106
|
+
}, options) as InputType
|
|
66
107
|
},
|
|
67
|
-
inputWidth: (options?:
|
|
108
|
+
inputWidth: (options?: ArgType) => {
|
|
68
109
|
return Object.assign({
|
|
69
110
|
control: { type: 'select' },
|
|
70
111
|
options: [undefined, 'fixed-20', 'fixed-10', 'fixed-5', 'fixed-4', 'fixed-3', 'fixed-2', 'fluid-three-quarters', 'fluid-two-thirds', 'fluid-half', 'fluid-one-third', 'fluid-one-quarter'],
|
|
71
112
|
type: 'string'
|
|
72
|
-
}, options)
|
|
113
|
+
}, options) as InputType
|
|
73
114
|
},
|
|
74
|
-
isCurrent: (options?:
|
|
115
|
+
isCurrent: (options?: ArgType) => {
|
|
75
116
|
return Object.assign({
|
|
76
117
|
control: 'boolean',
|
|
77
118
|
description: 'Whether the component is for the current page'
|
|
78
|
-
}, options)
|
|
119
|
+
}, options) as InputType
|
|
79
120
|
},
|
|
80
|
-
isSmall: (options?:
|
|
121
|
+
isSmall: (options?: ArgType) => {
|
|
81
122
|
return Object.assign({
|
|
82
123
|
control: 'boolean',
|
|
83
|
-
description: 'Whether to use the
|
|
84
|
-
}, options)
|
|
124
|
+
description: 'Whether to use the \'small\' input control variant'
|
|
125
|
+
}, options) as InputType
|
|
85
126
|
},
|
|
86
|
-
label: (options?:
|
|
127
|
+
label: (options?: ArgType) => {
|
|
87
128
|
return Object.assign({
|
|
88
129
|
description: 'Text to use for the field\'s associated label',
|
|
89
130
|
type: {
|
|
90
131
|
required: true,
|
|
91
132
|
name: 'string'
|
|
92
133
|
}
|
|
93
|
-
}, options);
|
|
134
|
+
}, options) as InputType;
|
|
94
135
|
},
|
|
95
|
-
linkComponent: (options?:
|
|
136
|
+
linkComponent: (options?: ArgType) => {
|
|
96
137
|
return Object.assign({
|
|
97
138
|
control: false,
|
|
98
139
|
description: 'Function that returns an element, to customise the output',
|
|
99
140
|
type: 'function'
|
|
100
|
-
}, options);
|
|
141
|
+
}, options) as InputType;
|
|
101
142
|
},
|
|
102
|
-
maxlength: (options?:
|
|
143
|
+
maxlength: (options?: ArgType) => {
|
|
103
144
|
return Object.assign({
|
|
104
145
|
description: 'Maximum number of characters permitted',
|
|
105
146
|
type: 'number'
|
|
106
|
-
}, options);
|
|
147
|
+
}, options) as InputType;
|
|
107
148
|
},
|
|
108
|
-
noBorder: (options?:
|
|
149
|
+
noBorder: (options?: ArgType) => {
|
|
109
150
|
return Object.assign({
|
|
110
151
|
control: 'boolean',
|
|
111
152
|
description: 'Use the borderless display variant'
|
|
112
|
-
}, options);
|
|
153
|
+
}, options) as InputType;
|
|
113
154
|
},
|
|
114
|
-
onBlur: (options?:
|
|
155
|
+
onBlur: (options?: ArgType) => {
|
|
115
156
|
return Object.assign({
|
|
116
157
|
description: 'Function to fire in response to a blur event',
|
|
117
158
|
type: 'function'
|
|
118
|
-
}, options);
|
|
159
|
+
}, options) as InputType;
|
|
119
160
|
},
|
|
120
|
-
onChange: (options?:
|
|
161
|
+
onChange: (options?: ArgType) => {
|
|
121
162
|
return Object.assign({
|
|
122
163
|
description: 'Function to fire in response to a change event',
|
|
123
164
|
type: 'function'
|
|
124
|
-
}, options);
|
|
165
|
+
}, options) as InputType;
|
|
125
166
|
},
|
|
126
|
-
onClick: (options?:
|
|
167
|
+
onClick: (options?: ArgType) => {
|
|
127
168
|
return Object.assign({
|
|
128
169
|
description: 'Function to fire in response to a click event',
|
|
129
170
|
type: 'function'
|
|
130
|
-
}, options);
|
|
171
|
+
}, options) as InputType;
|
|
131
172
|
},
|
|
132
|
-
tagColour: (options?:
|
|
173
|
+
tagColour: (options?: ArgType) => {
|
|
133
174
|
return Object.assign({
|
|
134
175
|
control: { type: 'select' },
|
|
135
176
|
description: 'The tag colour to use',
|
|
136
177
|
options: ['', 'blue', 'green', 'grey', 'orange', 'pink', 'purple', 'red', 'teal', 'yellow'],
|
|
137
178
|
type: 'string'
|
|
138
|
-
}, options);
|
|
179
|
+
}, options) as InputType;
|
|
139
180
|
}
|
|
140
181
|
}
|
|
141
182
|
|
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,32 @@ Changes are grouped under the labels: `Added`, `Changed`, `Deprecated`, `Fixed`,
|
|
|
6
6
|
`Removed` and `Security`.
|
|
7
7
|
|
|
8
8
|
---
|
|
9
|
+
## [0.13.0] - 2025-12-19
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- eslint added to build task
|
|
13
|
+
### Changed
|
|
14
|
+
- Types moved from .d.ts files in @types folder to types.ts files in each component's folder
|
|
15
|
+
- HintText no longer allows content to be added with a 'text' prop -- use children instead
|
|
16
|
+
- NotificationBanner title (visually hidden) is customisable via a 'title' prop
|
|
17
|
+
### Fixed
|
|
18
|
+
- Checkbox stories updated to use 'isSmall' and 'isExclusive' (see v0.10.0).
|
|
19
|
+
- CookieBanner now fires the SG Design System cookie notification JS
|
|
20
|
+
### Removed
|
|
21
|
+
- 'SGDS' namespace no longer used for types etc
|
|
22
|
+
### Security
|
|
23
|
+
- Storybook version updated to address vulnerabilities
|
|
24
|
+
|
|
25
|
+
## [0.12.1] - 2025-11-19
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
- 'Barrel' index files
|
|
29
|
+
- 'main' and typings added to package.json
|
|
30
|
+
### Changed
|
|
31
|
+
- Move hooks and common components and to subfolders to match structure of the main components
|
|
32
|
+
### Security
|
|
33
|
+
- Update dependencies
|
|
34
|
+
|
|
9
35
|
## [0.12.0] - 2025-11-12
|
|
10
36
|
|
|
11
37
|
### Added
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// import eslint from "@eslint";
|
|
2
|
+
import globals from "globals";
|
|
3
|
+
import tseslint from "typescript-eslint";
|
|
4
|
+
import react from "eslint-plugin-react";
|
|
5
|
+
import { defineConfig } from "eslint/config";
|
|
6
|
+
|
|
7
|
+
export default defineConfig([
|
|
8
|
+
{
|
|
9
|
+
files: ["**/*.{js,mjs,cjs,ts,mts,cts,jsx,tsx}"],
|
|
10
|
+
plugins: { react },
|
|
11
|
+
languageOptions: { globals: globals.browser },
|
|
12
|
+
settings: {
|
|
13
|
+
react: {
|
|
14
|
+
version: "detect"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
tseslint.configs.recommended,
|
|
19
|
+
react.configs.flat.recommended,
|
|
20
|
+
{
|
|
21
|
+
rules: {
|
|
22
|
+
"react/react-in-jsx-scope": "off"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
ignores: [
|
|
27
|
+
"coverage/**",
|
|
28
|
+
"dist/**",
|
|
29
|
+
"node_modules/**"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
]);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scottish-government/designsystem-react",
|
|
3
3
|
"description": "A React/JSX implementation of the Scottish Government Design System",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.13.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Scottish Government Digital Design System team",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"typings": "dist/index.d.ts",
|
|
12
12
|
"main": "dist/index.js",
|
|
13
13
|
"scripts": {
|
|
14
|
-
"build": "npm run svgr && npm run tsc",
|
|
14
|
+
"build": "npx eslint && npm run svgr && npm run tsc",
|
|
15
15
|
"coverage": "vitest test.tsx run --coverage",
|
|
16
16
|
"svgr": "npx @svgr/cli node_modules/@scottish-government/design-system/src/images/icons/svg --config-file .svgrrc",
|
|
17
17
|
"svgr_documents": "npx @svgr/cli node_modules/@scottish-government/design-system/src/images/documents/svg --config-file .svgrrc_documents",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@chromatic-com/storybook": "^4.1.3",
|
|
28
|
+
"@eslint/js": "^9.39.1",
|
|
28
29
|
"@storybook/addon-a11y": "^10.0.8",
|
|
29
30
|
"@storybook/addon-docs": "^10.0.8",
|
|
30
31
|
"@storybook/addon-onboarding": "^10.0.8",
|
|
@@ -42,11 +43,15 @@
|
|
|
42
43
|
"@vitest/browser": "4.0.10",
|
|
43
44
|
"@vitest/browser-playwright": "^4.0.10",
|
|
44
45
|
"@vitest/coverage-v8": "^4.0.10",
|
|
46
|
+
"eslint": "^9.39.1",
|
|
47
|
+
"eslint-plugin-react": "^7.37.5",
|
|
48
|
+
"globals": "^16.5.0",
|
|
45
49
|
"jsdom": "^27.2.0",
|
|
46
50
|
"react": "^19.2.0",
|
|
47
51
|
"react-dom": "^19.2.0",
|
|
48
|
-
"storybook": "^10.
|
|
52
|
+
"storybook": "^10.1.10",
|
|
49
53
|
"typescript": "^5.9.3",
|
|
54
|
+
"typescript-eslint": "^8.47.0",
|
|
50
55
|
"vitest": "^4.0.10"
|
|
51
56
|
}
|
|
52
57
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Children } from 'react';
|
|
2
2
|
import Icon from '../Icon';
|
|
3
3
|
import ScreenReaderText from '../ScreenReaderText';
|
|
4
|
+
import { AbstractNotificationBannerProps, AbstractNotificationBannerButtonsProps } from './types';
|
|
4
5
|
|
|
5
6
|
const Buttons = ({
|
|
6
7
|
children
|
|
7
|
-
}:
|
|
8
|
+
}: AbstractNotificationBannerButtonsProps) => {
|
|
8
9
|
return (<div className="ds_button-group">{children}</div>);
|
|
9
|
-
}
|
|
10
|
+
};
|
|
10
11
|
|
|
11
12
|
const AbstractNotificationBanner = ({
|
|
12
13
|
children,
|
|
@@ -17,8 +18,8 @@ const AbstractNotificationBanner = ({
|
|
|
17
18
|
isDismissable,
|
|
18
19
|
title = 'Information',
|
|
19
20
|
...props
|
|
20
|
-
}:
|
|
21
|
-
|
|
21
|
+
}: AbstractNotificationBannerProps) => {
|
|
22
|
+
const content: React.ReactElement[] = [];
|
|
22
23
|
let buttons;
|
|
23
24
|
|
|
24
25
|
Children.forEach(children, (child) => {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IconName } from '../../shared-types';
|
|
2
|
+
|
|
3
|
+
export interface AbstractNotificationBannerProps extends React.AllHTMLAttributes<HTMLDivElement> {
|
|
4
|
+
hasIcon?: boolean;
|
|
5
|
+
hasColourIcon?: boolean;
|
|
6
|
+
hasInverseIcon?: boolean;
|
|
7
|
+
icon?: IconName;
|
|
8
|
+
isDismissable?: boolean;
|
|
9
|
+
title?: string;
|
|
10
|
+
ref?: React.Ref<HTMLDivElement>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AbstractNotificationBannerButtonsProps extends React.AllHTMLAttributes<HTMLDivElement> {
|
|
14
|
+
children: React.ReactNode;
|
|
15
|
+
}
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { ActionLinkProps } from './types';
|
|
2
|
+
|
|
1
3
|
const ActionLink = ({
|
|
2
4
|
children,
|
|
3
5
|
describedby,
|
|
4
6
|
href,
|
|
5
7
|
linkComponent,
|
|
6
8
|
onclick
|
|
7
|
-
}:
|
|
9
|
+
}: ActionLinkProps) => {
|
|
8
10
|
const CLASSNAME = 'ds_link';
|
|
9
11
|
|
|
10
12
|
function processChildren(children: React.ReactNode) {
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Wraps all children in a specified HTML tag if a condition is met.
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
|
|
5
|
+
import { ConditionalWrapperProps } from "./types";
|
|
6
|
+
|
|
7
|
+
const ConditionalWrapper = ({
|
|
8
|
+
condition,
|
|
9
|
+
wrapper,
|
|
10
|
+
children
|
|
11
|
+
}: ConditionalWrapperProps) => {
|
|
12
|
+
return condition ? wrapper(children as React.JSX.Element) : children;
|
|
13
|
+
};
|
|
6
14
|
|
|
7
15
|
ConditionalWrapper.displayName = 'ConditionalWrapper';
|
|
8
16
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import * as FileIcons from '../../images/documents';
|
|
3
|
+
import { FileIconProps } from './types';
|
|
3
4
|
|
|
4
5
|
const FileIcon = ({
|
|
5
6
|
ariaLabel = '',
|
|
6
7
|
className,
|
|
7
8
|
icon
|
|
8
|
-
}:
|
|
9
|
+
}: FileIconProps) => {
|
|
9
10
|
const FileIconComponent = FileIcons[icon];
|
|
10
11
|
|
|
11
12
|
return (
|
|
@@ -9,8 +9,9 @@ test('hint test renders correctly', () => {
|
|
|
9
9
|
render(
|
|
10
10
|
<HintText data-testid="hint-text"
|
|
11
11
|
id={HINT_TEXT_ID}
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
>
|
|
13
|
+
{HINT_TEXT_CONTENT}
|
|
14
|
+
</HintText>
|
|
14
15
|
);
|
|
15
16
|
|
|
16
17
|
const hintText = screen.getByTestId('hint-text');
|
|
@@ -20,19 +21,6 @@ test('hint test renders correctly', () => {
|
|
|
20
21
|
expect(hintText.textContent).toEqual(HINT_TEXT_CONTENT);
|
|
21
22
|
});
|
|
22
23
|
|
|
23
|
-
test('hint test with children instead of text', () => {
|
|
24
|
-
render(
|
|
25
|
-
<HintText data-testid="hint-text"
|
|
26
|
-
id={HINT_TEXT_ID}
|
|
27
|
-
>
|
|
28
|
-
<span>{HINT_TEXT_CONTENT}</span>
|
|
29
|
-
</HintText>
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
const hintText = screen.getByTestId('hint-text');
|
|
33
|
-
expect(hintText.innerHTML).toEqual(`<span>${HINT_TEXT_CONTENT}</span>`);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
24
|
test('passing additional props', () => {
|
|
37
25
|
render(
|
|
38
26
|
<HintText data-testid="hint-text"
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
+
import { HintTextProps } from "./types";
|
|
2
|
+
|
|
1
3
|
const HintText = ({
|
|
2
4
|
children,
|
|
3
5
|
id,
|
|
4
|
-
text,
|
|
5
6
|
...props
|
|
6
|
-
}:
|
|
7
|
+
}: HintTextProps) => {
|
|
7
8
|
return (
|
|
8
9
|
<p
|
|
9
10
|
className="ds_hint-text"
|
|
10
|
-
dangerouslySetInnerHTML={text ? { __html: text } : undefined}
|
|
11
11
|
id={id}
|
|
12
12
|
{...props}
|
|
13
13
|
>
|
|
14
|
-
{
|
|
14
|
+
{children}
|
|
15
15
|
</p>
|
|
16
16
|
);
|
|
17
17
|
};
|
package/src/common/Icon/Icon.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import * as Icons from '../../images/icons';
|
|
3
|
+
import { IconProps } from './types';
|
|
3
4
|
|
|
4
5
|
const Icon = ({
|
|
5
6
|
ariaLabel,
|
|
@@ -7,7 +8,7 @@ const Icon = ({
|
|
|
7
8
|
isFilled,
|
|
8
9
|
icon,
|
|
9
10
|
iconSize
|
|
10
|
-
}:
|
|
11
|
+
}: IconProps) => {
|
|
11
12
|
const IconComponent = Icons[icon];
|
|
12
13
|
|
|
13
14
|
return (
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Wraps all children in a specified HTML tag.
|
|
3
3
|
*/
|
|
4
|
+
import React from 'react';
|
|
5
|
+
import { WrapperTagProps } from './types';
|
|
6
|
+
|
|
4
7
|
const WrapperTag = ({
|
|
5
8
|
children,
|
|
6
9
|
tagName = 'div',
|
|
7
10
|
...props
|
|
8
|
-
}:
|
|
9
|
-
|
|
10
|
-
return <TagName {...props}>{children}</TagName>;
|
|
11
|
+
}: WrapperTagProps) => {
|
|
12
|
+
return React.createElement(tagName, props, children);
|
|
11
13
|
};
|
|
12
14
|
|
|
13
15
|
WrapperTag.displayName = 'WrapperTag';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import argTypes from '../../../.storybook/sgdsArgTypes';
|
|
3
2
|
|
|
4
3
|
import Accordion from './Accordion';
|
|
5
4
|
|
|
@@ -15,9 +14,6 @@ const meta = {
|
|
|
15
14
|
required: true
|
|
16
15
|
}
|
|
17
16
|
},
|
|
18
|
-
headingLevel: argTypes.headingLevel({
|
|
19
|
-
description: 'Heading level for the component\'s heading. It is best to set this on the parent Accordion.'
|
|
20
|
-
}),
|
|
21
17
|
id: {
|
|
22
18
|
description: 'ID to use for the accordion item if you want to override the automatically generated default',
|
|
23
19
|
type: 'string'
|
|
@@ -37,7 +33,7 @@ const meta = {
|
|
|
37
33
|
Veterans are entitled to the same healthcare as any citizen. And there are health care options and support available specifically for veterans.
|
|
38
34
|
</p>
|
|
39
35
|
<p>
|
|
40
|
-
If you have a health condition that
|
|
36
|
+
If you have a health condition that's related to your service, you're entitled to priority treatment based on clinical need.
|
|
41
37
|
</p>
|
|
42
38
|
</>
|
|
43
39
|
}
|
|
@@ -12,7 +12,7 @@ const meta = {
|
|
|
12
12
|
}),
|
|
13
13
|
hideOpenAll: {
|
|
14
14
|
control: 'boolean',
|
|
15
|
-
description: 'Do not show the
|
|
15
|
+
description: 'Do not show the \'open all\' button',
|
|
16
16
|
type: 'boolean'
|
|
17
17
|
},
|
|
18
18
|
children: {
|
|
@@ -26,17 +26,17 @@ const meta = {
|
|
|
26
26
|
Veterans are entitled to the same healthcare as any citizen. And there are health care options and support available specifically for veterans.
|
|
27
27
|
</p>
|
|
28
28
|
<p>
|
|
29
|
-
If you have a health condition that
|
|
29
|
+
If you have a health condition that's related to your service, you're entitled to priority treatment based on clinical need.
|
|
30
30
|
</p>
|
|
31
31
|
</Accordion.Item>
|
|
32
32
|
<Accordion.Item id='accordion-2' heading='Employability for veterans'>
|
|
33
33
|
<p>
|
|
34
|
-
If you
|
|
34
|
+
If you're looking for a job, there are several organisations that can help you <a href="#accordion-link">find a job or develop new skills</a>.
|
|
35
35
|
</p>
|
|
36
36
|
</Accordion.Item>
|
|
37
37
|
<Accordion.Item id='accordion-3' heading='Housing for veterans'>
|
|
38
38
|
<p>
|
|
39
|
-
If you need <a href="#accordion-link"> help finding a place to live</a> there
|
|
39
|
+
If you need <a href="#accordion-link"> help finding a place to live</a> there's support specifically for veterans.
|
|
40
40
|
</p>
|
|
41
41
|
</Accordion.Item>
|
|
42
42
|
</>
|
|
@@ -53,7 +53,7 @@ export const Default: Story = {
|
|
|
53
53
|
export const HideOpenAll: Story = {
|
|
54
54
|
args: {
|
|
55
55
|
hideOpenAll: true
|
|
56
|
-
}
|
|
56
|
+
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
export const InvalidNoChildren: Story = {
|