@scottish-government/designsystem-react 0.8.0 → 0.10.0-beta.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.
Files changed (169) hide show
  1. package/.storybook/main.ts +20 -0
  2. package/.storybook/manager.ts +13 -0
  3. package/.storybook/preview-head.html +1 -0
  4. package/.storybook/preview.tsx +56 -0
  5. package/.storybook/sgdsArgTypes.ts +123 -0
  6. package/.storybook/sgdsTheme.ts +9 -0
  7. package/.storybook/vitest.setup.ts +7 -0
  8. package/@types/common/AbstractNotificationBanner.d.ts +2 -2
  9. package/@types/common/ActionLink.d.ts +1 -1
  10. package/@types/common/Icon.d.ts +1 -1
  11. package/@types/components/Accordion.d.ts +2 -3
  12. package/@types/components/Button.d.ts +5 -5
  13. package/@types/components/CategoryItem.d.ts +10 -0
  14. package/@types/components/CategoryList.d.ts +7 -0
  15. package/@types/components/Checkbox.d.ts +2 -2
  16. package/@types/components/ContentsNav.d.ts +1 -1
  17. package/@types/components/DatePicker.d.ts +1 -1
  18. package/@types/components/ErrorMessage.d.ts +1 -2
  19. package/@types/components/ErrorSummary.d.ts +1 -1
  20. package/@types/components/FileDownload.d.ts +2 -2
  21. package/@types/components/Metadata.d.ts +1 -1
  22. package/@types/components/Pagination.d.ts +1 -1
  23. package/@types/components/RadioButton.d.ts +2 -2
  24. package/@types/components/SideNavigation.d.ts +1 -1
  25. package/@types/components/SiteNavigation.d.ts +1 -1
  26. package/@types/components/SummaryList.d.ts +1 -1
  27. package/@types/components/Tabs.d.ts +3 -3
  28. package/@types/components/TextInput.d.ts +1 -1
  29. package/@types/sgds.d.ts +2 -1
  30. package/CHANGELOG.md +29 -0
  31. package/dist/common/AbstractNotificationBanner.jsx +4 -4
  32. package/dist/common/Icon.jsx +2 -2
  33. package/dist/components/Accordion/Accordion.jsx +8 -7
  34. package/dist/components/Button/Button.jsx +6 -6
  35. package/dist/components/CategoryItem/CategoryItem.jsx +35 -0
  36. package/dist/components/CategoryList/CategoryList.jsx +55 -0
  37. package/dist/components/Checkbox/Checkbox.jsx +7 -4
  38. package/dist/components/Checkbox/CheckboxGroup.jsx +5 -11
  39. package/dist/components/ContentsNav/ContentsNav.jsx +2 -2
  40. package/dist/components/DatePicker/DatePicker.jsx +1 -1
  41. package/dist/components/ErrorMessage/ErrorMessage.jsx +3 -3
  42. package/dist/components/FileDownload/FileDownload.jsx +2 -2
  43. package/dist/components/NotificationBanner/NotificationBanner.jsx +2 -2
  44. package/dist/components/PageMetadata/PageMetadata.jsx +4 -4
  45. package/dist/components/Pagination/Pagination.jsx +4 -4
  46. package/dist/components/Question/Question.jsx +1 -1
  47. package/dist/components/RadioButton/RadioButton.jsx +6 -2
  48. package/dist/components/RadioButton/RadioGroup.jsx +7 -47
  49. package/dist/components/Select/Select.jsx +1 -1
  50. package/dist/components/SideNavigation/SideNavigation.jsx +2 -2
  51. package/dist/components/SiteHeader/SiteHeader.jsx +3 -3
  52. package/dist/components/SiteNavigation/SiteNavigation.jsx +2 -2
  53. package/dist/components/SiteSearch/SiteSearch.jsx +1 -1
  54. package/dist/components/SkipLinks/SkipLinks.jsx +1 -1
  55. package/dist/components/SummaryList/SummaryList.jsx +3 -3
  56. package/dist/components/Tabs/Tabs.jsx +6 -7
  57. package/dist/components/TextInput/TextInput.jsx +5 -5
  58. package/dist/components/Textarea/Textarea.jsx +1 -1
  59. package/dist/hooks/useTracking.js +21 -0
  60. package/dist/tsconfig.tsbuildinfo +1 -1
  61. package/dist/utils/context.js +5 -0
  62. package/package.json +15 -4
  63. package/src/common/AbstractNotificationBanner.test.tsx +1 -1
  64. package/src/common/AbstractNotificationBanner.tsx +4 -4
  65. package/src/common/Icon.test.tsx +1 -1
  66. package/src/common/Icon.tsx +2 -2
  67. package/src/components/Accordion/Accordion.stories.tsx +111 -0
  68. package/src/components/Accordion/Accordion.test.tsx +5 -17
  69. package/src/components/Accordion/Accordion.tsx +11 -10
  70. package/src/components/AspectBox/AspectBox.stories.tsx +64 -0
  71. package/src/components/BackToTop/BackToTop.stories.tsx +36 -0
  72. package/src/components/Breadcrumbs/Breadcrumbs.stories.tsx +49 -0
  73. package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +0 -1
  74. package/src/components/Breadcrumbs/Breadcrumbs.tsx +1 -1
  75. package/src/components/Button/Button.stories.tsx +194 -0
  76. package/src/components/Button/Button.test.tsx +4 -4
  77. package/src/components/Button/Button.tsx +9 -9
  78. package/src/components/CategoryItem/CategoryItem.stories.tsx +55 -0
  79. package/src/components/CategoryItem/CategoryItem.test.tsx +93 -0
  80. package/src/components/CategoryItem/CategoryItem.tsx +56 -0
  81. package/src/components/CategoryList/CategoryList.stories.tsx +65 -0
  82. package/src/components/CategoryList/CategoryList.test.tsx +59 -0
  83. package/src/components/CategoryList/CategoryList.tsx +33 -0
  84. package/src/components/Checkbox/Checkbox.stories.tsx +85 -0
  85. package/src/components/Checkbox/Checkbox.test.tsx +2 -2
  86. package/src/components/Checkbox/Checkbox.tsx +11 -6
  87. package/src/components/Checkbox/CheckboxGroup.stories.tsx +68 -0
  88. package/src/components/Checkbox/CheckboxGroup.tsx +7 -12
  89. package/src/components/ConfirmationMessage/ConfirmationMessage.stories.tsx +38 -0
  90. package/src/components/ContentsNav/ContentsNav.stories.tsx +43 -0
  91. package/src/components/ContentsNav/ContentsNav.test.tsx +2 -2
  92. package/src/components/ContentsNav/ContentsNav.tsx +2 -2
  93. package/src/components/CookieBanner/CookieBanner.stories.tsx +33 -0
  94. package/src/components/DatePicker/DatePicker.stories.tsx +113 -0
  95. package/src/components/DatePicker/DatePicker.tsx +1 -1
  96. package/src/components/Details/Details.stories.tsx +36 -0
  97. package/src/components/ErrorMessage/ErrorMessage.stories.tsx +19 -0
  98. package/src/components/ErrorMessage/ErrorMessage.test.tsx +3 -15
  99. package/src/components/ErrorMessage/ErrorMessage.tsx +1 -3
  100. package/src/components/ErrorSummary/ErrorSummary.stories.tsx +38 -0
  101. package/src/components/FileDownload/FileDownload.stories.tsx +75 -0
  102. package/src/components/FileDownload/FileDownload.test.tsx +1 -1
  103. package/src/components/FileDownload/FileDownload.tsx +2 -2
  104. package/src/components/HideThisPage/HideThisPage.stories.tsx +20 -0
  105. package/src/components/InsetText/InsetText.stories.tsx +21 -0
  106. package/src/components/NotificationBanner/NotificationBanner.stories.tsx +57 -0
  107. package/src/components/NotificationBanner/NotificationBanner.test.tsx +1 -1
  108. package/src/components/NotificationBanner/NotificationBanner.tsx +4 -4
  109. package/src/components/NotificationPanel/NotificationPanel.stories.tsx +32 -0
  110. package/src/components/PageHeader/PageHeader.stories.tsx +60 -0
  111. package/src/components/PageMetadata/PageMetadata.stories.tsx +58 -0
  112. package/src/components/PageMetadata/PageMetadata.test.tsx +2 -2
  113. package/src/components/PageMetadata/PageMetadata.tsx +4 -4
  114. package/src/components/Pagination/Pagination.stories.tsx +69 -0
  115. package/src/components/Pagination/Pagination.test.tsx +1 -1
  116. package/src/components/Pagination/Pagination.tsx +4 -4
  117. package/src/components/PhaseBanner/PhaseBanner.stories.tsx +38 -0
  118. package/src/components/Question/Question.stories.tsx +78 -0
  119. package/src/components/Question/Question.tsx +1 -1
  120. package/src/components/RadioButton/RadioButton.stories.tsx +67 -0
  121. package/src/components/RadioButton/RadioButton.test.tsx +2 -1
  122. package/src/components/RadioButton/RadioButton.tsx +9 -3
  123. package/src/components/RadioButton/RadioGroup.stories.tsx +77 -0
  124. package/src/components/RadioButton/RadioGroup.test.tsx +2 -2
  125. package/src/components/RadioButton/RadioGroup.tsx +8 -15
  126. package/src/components/Select/Select.stories.tsx +76 -0
  127. package/src/components/Select/Select.tsx +1 -1
  128. package/src/components/SequentialNavigation/SequentialNavigation.stories.tsx +31 -0
  129. package/src/components/SideNavigation/SideNavigation.stories.tsx +92 -0
  130. package/src/components/SideNavigation/SideNavigation.test.tsx +2 -2
  131. package/src/components/SideNavigation/SideNavigation.tsx +2 -2
  132. package/src/components/SiteFooter/SiteFooter.stories.tsx +65 -0
  133. package/src/components/SiteHeader/SiteHeader.stories.tsx +92 -0
  134. package/src/components/SiteHeader/SiteHeader.tsx +2 -7
  135. package/src/components/SiteNavigation/SiteNavigation.stories.tsx +45 -0
  136. package/src/components/SiteNavigation/SiteNavigation.test.tsx +1 -1
  137. package/src/components/SiteNavigation/SiteNavigation.tsx +2 -2
  138. package/src/components/SiteSearch/SiteSearch.stories.tsx +81 -0
  139. package/src/components/SiteSearch/SiteSearch.tsx +1 -1
  140. package/src/components/SkipLinks/SkipLinks.stories.tsx +57 -0
  141. package/src/components/SkipLinks/SkipLinks.tsx +1 -1
  142. package/src/components/SummaryCard/SummaryCard.stories.tsx +46 -0
  143. package/src/components/SummaryList/SummaryList.stories.tsx +75 -0
  144. package/src/components/SummaryList/SummaryList.test.tsx +1 -1
  145. package/src/components/SummaryList/SummaryList.tsx +3 -3
  146. package/src/components/Table/Table.stories.tsx +96 -0
  147. package/src/components/Tabs/Tabs.stories.tsx +90 -0
  148. package/src/components/Tabs/Tabs.test.tsx +6 -8
  149. package/src/components/Tabs/Tabs.tsx +8 -9
  150. package/src/components/Tag/Tag.stories.tsx +25 -0
  151. package/src/components/TaskList/TaskList.stories.tsx +129 -0
  152. package/src/components/TextInput/TextInput.stories.tsx +123 -0
  153. package/src/components/TextInput/TextInput.test.tsx +2 -2
  154. package/src/components/TextInput/TextInput.tsx +5 -5
  155. package/src/components/Textarea/Textarea.stories.tsx +71 -0
  156. package/src/components/Textarea/Textarea.tsx +1 -1
  157. package/src/components/WarningText/WarningText.stories.tsx +21 -0
  158. package/src/hooks/useTracking.test.tsx +64 -0
  159. package/src/hooks/useTracking.ts +19 -0
  160. package/src/utils/context.ts +3 -0
  161. package/static/data/autocomplete-dummy-data.json +2361 -0
  162. package/static/images/highland-cow.jpg +0 -0
  163. package/static/images/scottish-government--min.svg +11 -0
  164. package/static/images/scottish-government.svg +6 -0
  165. package/tsconfig.json +3 -2
  166. package/vite.config.ts +45 -11
  167. package/vitest-setup.ts +1 -0
  168. package/vitest.shims.d.ts +1 -0
  169. package/src/utils/slugify.ts +0 -13
@@ -54,7 +54,7 @@ test('current pagination page', () => {
54
54
  <Page
55
55
  ariaLabel={PAGE_ARIA_LABEL}
56
56
  href={PAGE_HREF}
57
- current
57
+ isCurrent
58
58
  >{PAGE_LABEL}</Page>
59
59
  );
60
60
 
@@ -4,8 +4,8 @@ export const Page = ({
4
4
  ariaLabel,
5
5
  children,
6
6
  className,
7
- current = false,
8
7
  href,
8
+ isCurrent = false,
9
9
  linkComponent,
10
10
  onClick
11
11
  }: SGDS.Component.Pagination.Page) => {
@@ -19,7 +19,7 @@ export const Page = ({
19
19
  const classNames = [
20
20
  'ds_pagination__link',
21
21
  className,
22
- current ? 'ds_current' : undefined
22
+ isCurrent ? 'ds_current' : undefined
23
23
  ].join(' ');
24
24
 
25
25
  const linkProps: SGDS.LinkComponentProps = {
@@ -28,7 +28,7 @@ export const Page = ({
28
28
  onClick: handleClick
29
29
  };
30
30
 
31
- if (current) {
31
+ if (isCurrent) {
32
32
  linkProps['aria-current'] = 'page';
33
33
  }
34
34
 
@@ -144,7 +144,7 @@ const Pagination = ({
144
144
  <Page
145
145
  ariaLabel={`Page ${item}`}
146
146
  href={pattern.replace('$1', String(item))}
147
- current={item === page}
147
+ isCurrent={item === page}
148
148
  key={`pagination${index}`}
149
149
  linkComponent={linkComponent}
150
150
  onClick={onClick}
@@ -0,0 +1,38 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import argTypes from '../../../.storybook/sgdsArgTypes';
3
+
4
+ import PhaseBanner from './PhaseBanner';
5
+
6
+ const meta = {
7
+ title: 'Components/Phase banner',
8
+ component: PhaseBanner,
9
+ argTypes: {
10
+ children: argTypes.children(),
11
+ phaseName: {
12
+ description: 'The text for the banner\'s tag component.',
13
+ type: 'string'
14
+ }
15
+ },
16
+ args: {
17
+ phaseName: 'Beta'
18
+ }
19
+ } satisfies Meta<typeof PhaseBanner>;
20
+
21
+ export default meta;
22
+ type Story = StoryObj<typeof meta>;
23
+
24
+ export const Default: Story = {
25
+ args: {
26
+ phaseName: 'Beta'
27
+ },
28
+ };
29
+
30
+ export const CustomContent: Story = {
31
+ args: {
32
+ phaseName: 'Beta',
33
+ children: <>This is a new service. Your <a href="#foo">feedback</a> will help us to improve it.</>
34
+ },
35
+ render: (args: any) => (
36
+ <PhaseBanner {...args}></PhaseBanner>
37
+ )
38
+ };
@@ -0,0 +1,78 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import argTypes from '../../../.storybook/sgdsArgTypes';
3
+
4
+ import Question from './Question';
5
+ import TextInput from '../TextInput/TextInput';
6
+ import Checkbox from '../Checkbox/Checkbox';
7
+ import CheckboxGroup from '../Checkbox/CheckboxGroup';
8
+
9
+ const meta = {
10
+ title: 'Components/Question',
11
+ component: Question,
12
+ argTypes: {
13
+ errorMessage: argTypes.errorMessage(),
14
+ hasError: argTypes.hasError(),
15
+ hintText: argTypes.hintText(),
16
+ legend: {
17
+ desctiption: 'Text for a question\'s legend element (if the question uses a fieldset)',
18
+ type: 'string'
19
+ },
20
+ tagName: {
21
+ control: { type: 'select' },
22
+ description: 'HTML tag name to use for the question',
23
+ options: ['div', 'fieldset'],
24
+ type: 'string'
25
+ },
26
+ children: argTypes.children()
27
+ },
28
+ args: {
29
+ children: <TextInput
30
+ id="text-input-question"
31
+ label="First name"
32
+ />,
33
+ tagName: 'div'
34
+ }
35
+ } satisfies Meta<typeof Question>;
36
+
37
+ export default meta;
38
+ type Story = StoryObj<typeof meta>;
39
+
40
+ export const Default: Story = {
41
+ };
42
+
43
+ export const ErrorQuestion: Story = {
44
+ args: {
45
+ errorMessage: 'This is a required field',
46
+ hasError: true
47
+ }
48
+ }
49
+
50
+ export const FieldsetQuestion: Story = {
51
+ args: {
52
+ children: <CheckboxGroup>
53
+ <Checkbox
54
+ checked
55
+ id="universal-credit"
56
+ label="Universal Credit"
57
+ />
58
+ <Checkbox
59
+ id="pension-credit"
60
+ label="Pension Credit"
61
+ />
62
+ <Checkbox
63
+ id="jsa"
64
+ label="Income-based Job Seeker's Allowance"
65
+ />
66
+ <Checkbox
67
+ isExclusive
68
+ id="none"
69
+ label="No, I do not receive any of these benefits"
70
+ />
71
+ </CheckboxGroup>,
72
+ errorMessage: 'You must select at least one option',
73
+ hasError: true,
74
+ hintText: 'Select all that apply.',
75
+ legend: 'Do you receive any of these benefits',
76
+ tagName: 'fieldset'
77
+ }
78
+ }
@@ -24,7 +24,7 @@ const Question = function ({
24
24
  >
25
25
  {legend && <legend>{legend}</legend>}
26
26
  {hintText && <HintText text={hintText} />}
27
- {hasError && errorMessage && <ErrorMessage text={errorMessage} />}
27
+ {hasError && errorMessage && <ErrorMessage>{errorMessage}</ErrorMessage>}
28
28
  {children}
29
29
  </WrapperTag>
30
30
  );
@@ -0,0 +1,67 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import argTypes from '../../../.storybook/sgdsArgTypes';
3
+
4
+ import RadioButton from './RadioButton';
5
+
6
+ const meta = {
7
+ title: 'Components/Radio button',
8
+ component: RadioButton,
9
+ argTypes: {
10
+ checked: {
11
+ control: 'boolean',
12
+ description: 'The radio is checked on load'
13
+ },
14
+ hintText: argTypes.hintText(),
15
+ id: argTypes.id(),
16
+ label: argTypes.label(),
17
+ name: { type: 'string' },
18
+ onBlur: argTypes.onBlur(),
19
+ onChange: argTypes.onChange(),
20
+ isSmall: argTypes.isSmall()
21
+ },
22
+ args: {
23
+ id: 'arrears-radio',
24
+ label: 'Arrears',
25
+ name: 'radio-name',
26
+ }
27
+ } satisfies Meta<typeof RadioButton>;
28
+
29
+ export default meta;
30
+ type Story = StoryObj<typeof meta>;
31
+
32
+ export const Default: Story = {
33
+
34
+ };
35
+
36
+ export const KitchenSink: Story = {
37
+ args: {
38
+ checked: true,
39
+ hintText: 'This means you\'re paid for the period coming up, e.g. the month ahead',
40
+ isSmall: false
41
+ }
42
+ };
43
+
44
+ export const SmallRadio: Story = {
45
+ args: {
46
+ isSmall: true
47
+ }
48
+ };
49
+
50
+ export const Blur: Story = {
51
+ args: {
52
+ onBlur: () => {console.log('radio button blur')}
53
+ },
54
+ play: async ({ canvas, userEvent }) => {
55
+ await userEvent.click(canvas.getByRole('radio'));
56
+ await userEvent.tab();
57
+ }
58
+ }
59
+
60
+ export const Change: Story = {
61
+ args: {
62
+ onChange: () => {console.log('radio button change')}
63
+ },
64
+ play: async ({ canvas, userEvent }) => {
65
+ await userEvent.click(canvas.getByRole('radio'));
66
+ }
67
+ }
@@ -12,6 +12,7 @@ test('individual radio renders correctly', () => {
12
12
  const label = screen.getByText('Pension Credit');
13
13
 
14
14
  expect(radioContainer).toHaveClass('ds_radio');
15
+ expect(radioContainer).not.toHaveClass('ds_radio--small');
15
16
  expect(radio.tagName).toEqual('INPUT');
16
17
  expect(radio).toHaveAttribute('type', 'radio');
17
18
  expect(radio.id).toEqual('pensioncredit');
@@ -74,7 +75,7 @@ test('radio with hint text', () => {
74
75
 
75
76
  test('small radio', () => {
76
77
  render(
77
- <RadioButton small name="benefitType" label="Pension Credit" id="pensioncredit" />
78
+ <RadioButton isSmall name="benefitType" label="Pension Credit" id="pensioncredit" />
78
79
  );
79
80
 
80
81
  const radio = screen.getByRole('radio');
@@ -1,14 +1,17 @@
1
+ import { useContext } from 'react';
2
+
1
3
  import HintText from '../../common/HintText';
4
+ import { CheckboxRadioContext } from '../../utils/context';
2
5
 
3
6
  const RadioButton = ({
4
7
  checked,
5
8
  hintText,
6
9
  id,
10
+ isSmall,
7
11
  label,
8
12
  name,
9
13
  onBlur,
10
- onChange,
11
- small
14
+ onChange
12
15
  }: SGDS.Component.RadioButton) => {
13
16
  const hintTextId = `hint-text-${id}`;
14
17
 
@@ -24,11 +27,14 @@ const RadioButton = ({
24
27
  }
25
28
  }
26
29
 
30
+ isSmall = isSmall || useContext(CheckboxRadioContext).isSmall;
31
+ name = name || useContext(CheckboxRadioContext).name;
32
+
27
33
  return (
28
34
  <div
29
35
  className={[
30
36
  'ds_radio',
31
- small && 'ds_radio--small'
37
+ isSmall && 'ds_radio--small'
32
38
  ].join(' ')}>
33
39
  <input
34
40
  aria-describedby={hintText ? hintTextId : undefined}
@@ -0,0 +1,77 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import argTypes from '../../../.storybook/sgdsArgTypes';
3
+
4
+ import RadioButton from '../RadioButton/RadioButton';
5
+ import RadioGroup from './RadioGroup';
6
+
7
+ const meta = {
8
+ title: 'Components/Radio group',
9
+ component: RadioGroup,
10
+ argTypes: {
11
+ isInline: {
12
+ control: 'boolean',
13
+ description: 'Whether to display the radio buttons in the group inline'
14
+ },
15
+ name: {type: 'string'},
16
+ isSmall: argTypes.isSmall(),
17
+ children: argTypes.children()
18
+ },
19
+ args: {
20
+ children: <>
21
+ <RadioButton
22
+ id="flat-radio"
23
+ label="Flat"
24
+ />
25
+ <RadioButton
26
+ id="bungalow-radio"
27
+ label="Bungalow"
28
+ />
29
+ <RadioButton
30
+ id="cottage-radio"
31
+ label="Cottage"
32
+ />
33
+ <RadioButton
34
+ id="terraced-radio"
35
+ label="Terraced house"
36
+ />
37
+ <RadioButton
38
+ id="semi-radio"
39
+ label="Semi-detached house"
40
+ />
41
+ <RadioButton
42
+ id="detached-radio"
43
+ label="Detached house"
44
+ />
45
+ </>,
46
+ name: 'propertyType'
47
+ }
48
+ } satisfies Meta<typeof RadioGroup>;
49
+
50
+ export default meta;
51
+ type Story = StoryObj<typeof meta>;
52
+
53
+ export const Default: Story = {
54
+
55
+ };
56
+
57
+ export const SmallRadios: Story = {
58
+ args: {
59
+ isSmall: true
60
+ }
61
+ };
62
+
63
+ export const InlineRadios: Story = {
64
+ args: {
65
+ children: <>
66
+ <RadioButton
67
+ id="yes-radio"
68
+ label="Yes"
69
+ />
70
+ <RadioButton
71
+ id="no-radio"
72
+ label="No"
73
+ />
74
+ </>,
75
+ isInline: true
76
+ }
77
+ };
@@ -22,7 +22,7 @@ test('radio group passes all expected item params', () => {
22
22
  const RADIO_NAME = 'radioname';
23
23
 
24
24
  render(
25
- <RadioGroup name={RADIO_NAME} small>
25
+ <RadioGroup name={RADIO_NAME} isSmall>
26
26
  <RadioButton id="banana" />
27
27
  <p>foo</p>
28
28
  </RadioGroup>
@@ -36,7 +36,7 @@ test('radio group passes all expected item params', () => {
36
36
 
37
37
  test('inline radio group', () => {
38
38
  render(
39
- <RadioGroup inline>
39
+ <RadioGroup isInline>
40
40
  <RadioButton id="banana" />
41
41
  </RadioGroup>
42
42
  );
@@ -1,34 +1,27 @@
1
- import React, { Children } from 'react';
2
- import RadioButton from './RadioButton';
1
+ import React from 'react';
2
+ import { CheckboxRadioContext } from '../../utils/context';
3
3
 
4
4
  const RadioGroup = ({
5
5
  children,
6
6
  className,
7
- inline,
7
+ isInline,
8
+ isSmall,
8
9
  name,
9
- small,
10
10
  ...props
11
11
  }: SGDS.Component.RadioButton.Group) => {
12
- function processChild(child: any) {
13
- if (child && child.type === RadioButton) {
14
- return React.cloneElement(child as React.ReactElement<SGDS.Component.RadioButton>, { small: small, name: name });
15
- } else {
16
- return child;
17
- }
18
- }
19
-
20
12
  return (
21
13
  <div
22
14
  className={[
23
15
  'ds_radios',
24
16
  'ds_field-group',
25
- inline && 'ds_field-group--inline',
17
+ isInline && 'ds_field-group--inline',
26
18
  className
27
19
  ].join(' ')}
28
20
  {...props}
29
21
  >
30
-
31
- {Children.map(children, child => processChild(child))}
22
+ <CheckboxRadioContext value={{ isSmall: !!isSmall, name }}>
23
+ {children}
24
+ </CheckboxRadioContext>
32
25
  </div>
33
26
  );
34
27
  };
@@ -0,0 +1,76 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import argTypes from '../../../.storybook/sgdsArgTypes';
3
+
4
+ import Select from './Select';
5
+
6
+ const meta = {
7
+ title: 'Components/Select',
8
+ component: Select,
9
+ argTypes: {
10
+ defaultValue: {type: 'string'},
11
+ errorMessage: argTypes.errorMessage(),
12
+ hasError: argTypes.hasError(),
13
+ hintText: argTypes.hintText(),
14
+ id: argTypes.id(),
15
+ label: argTypes.label(),
16
+ name: { type: 'string' },
17
+ onBlur: argTypes.onBlur(),
18
+ onChange: argTypes.onChange(),
19
+ placeholder: {type: 'string'},
20
+ width: argTypes.inputWidth(),
21
+ children: argTypes.children()
22
+ },
23
+ args: {
24
+ id: 'component',
25
+ label: 'Choose a component',
26
+ children: <>
27
+ <option value="accordion">
28
+ Accordion
29
+ </option>
30
+ <option value="breadcrumbs">
31
+ Breadcrumbs
32
+ </option>
33
+ <option value="button">
34
+ Button
35
+ </option>
36
+ </>
37
+ }
38
+ } satisfies Meta<typeof Select>;
39
+
40
+ export default meta;
41
+ type Story = StoryObj<typeof meta>;
42
+
43
+ export const Default: Story = {
44
+ };
45
+
46
+ export const KitchenSink: Story = {
47
+ args: {
48
+ defaultValue: 'button',
49
+ errorMessage: 'This field is required',
50
+ hasError: true,
51
+ hintText: 'Choose a component to learn more about how it works',
52
+ id: 'kitchensink',
53
+ placeholder: 'Choose',
54
+ width: 'fluid-one-third'
55
+ }
56
+ };
57
+
58
+ export const Blur: Story = {
59
+ args: {
60
+ onBlur: () => {console.log('select blur')}
61
+ },
62
+ play: async ({ canvas, userEvent }) => {
63
+ await userEvent.click(canvas.getByRole('combobox'));
64
+ await userEvent.tab();
65
+ }
66
+ }
67
+
68
+ export const Change: Story = {
69
+ args: {
70
+ onChange: () => {console.log('select change')}
71
+ },
72
+ play: async ({ canvas, userEvent }) => {
73
+ await userEvent.click(canvas.getByRole('combobox'));
74
+ await userEvent.selectOptions(canvas.getByRole('combobox'), ['button'])
75
+ }
76
+ }
@@ -40,7 +40,7 @@ const Select = function ({
40
40
  <>
41
41
  <label className="ds_label" htmlFor={id}>{label}</label>
42
42
  {hintText && <HintText id={hintTextId} text={hintText} />}
43
- {errorMessage && <ErrorMessage id={errorMessageId} text={errorMessage}/>}
43
+ {errorMessage && <ErrorMessage id={errorMessageId}>{errorMessage}</ErrorMessage>}
44
44
  <div
45
45
  className={[
46
46
  "ds_select-wrapper",
@@ -0,0 +1,31 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import argTypes from '../../../.storybook/sgdsArgTypes';
3
+
4
+ import SequentialNavigation from './SequentialNavigation';
5
+
6
+ const meta = {
7
+ title: 'Components/Sequential navigation',
8
+ component: SequentialNavigation,
9
+ argTypes: {
10
+ ariaLabel: argTypes.ariaLabel({ description: 'Text to use for an aria-label attribute on the nav element' }),
11
+ linkComponent: argTypes.linkComponent(),
12
+ children: argTypes.children()
13
+ },
14
+ args: {
15
+ children: <>
16
+ <SequentialNavigation.Previous href="#previous">
17
+ Apply for or renew a Blue Badge
18
+ </SequentialNavigation.Previous>
19
+ <SequentialNavigation.Next href="#next">
20
+ Eligibility: who can have one?
21
+ </SequentialNavigation.Next>
22
+ </>
23
+ }
24
+ } satisfies Meta<typeof SequentialNavigation>;
25
+
26
+ export default meta;
27
+ type Story = StoryObj<typeof meta>;
28
+
29
+ export const Default: Story = {
30
+
31
+ };
@@ -0,0 +1,92 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import argTypes from '../../../.storybook/sgdsArgTypes';
3
+
4
+ import SideNavigation from './SideNavigation';
5
+
6
+ const meta = {
7
+ title: 'Components/Side navigation',
8
+ component: SideNavigation,
9
+ argTypes: {
10
+ linkComponent: argTypes.linkComponent(),
11
+ children: argTypes.children()
12
+ },
13
+ args: {
14
+ children: <>
15
+ <SideNavigation.List isRoot>
16
+ <SideNavigation.Item
17
+ isCurrent
18
+ href="#apples"
19
+ title="Apples"
20
+ >
21
+ </SideNavigation.Item>
22
+ <SideNavigation.Item
23
+ href="#bananas"
24
+ title="Bananas"
25
+ />
26
+ <SideNavigation.Item
27
+ href="#cherries"
28
+ title="Cherries"
29
+ />
30
+ <SideNavigation.Item
31
+ href="#dates"
32
+ title="Dates"
33
+ />
34
+ </SideNavigation.List>
35
+ </>
36
+ }
37
+ } satisfies Meta<typeof SideNavigation>;
38
+
39
+ export default meta;
40
+ type Story = StoryObj<typeof meta>;
41
+
42
+ export const Default: Story = {
43
+
44
+ };
45
+
46
+ export const NestedNavigation: Story = {
47
+ args: {
48
+ children: <>
49
+ <SideNavigation.List isRoot>
50
+ <SideNavigation.Item
51
+ href="#apples"
52
+ title="Apples"
53
+ >
54
+ <SideNavigation.List>
55
+ <SideNavigation.Item
56
+ href="#green-apples"
57
+ title="Green apples"
58
+ >
59
+ <SideNavigation.List>
60
+ <SideNavigation.Item
61
+ isCurrent
62
+ href="#bramley"
63
+ title="Bramley"
64
+ />
65
+ <SideNavigation.Item
66
+ href="#granny-smith"
67
+ title="Granny smith"
68
+ />
69
+ </SideNavigation.List>
70
+ </SideNavigation.Item>
71
+ <SideNavigation.Item
72
+ href="#red-apples"
73
+ title="Red apples"
74
+ />
75
+ </SideNavigation.List>
76
+ </SideNavigation.Item>
77
+ <SideNavigation.Item
78
+ href="#bananas"
79
+ title="Bananas"
80
+ />
81
+ <SideNavigation.Item
82
+ href="#cherries"
83
+ title="Cherries"
84
+ />
85
+ <SideNavigation.Item
86
+ href="#dates"
87
+ title="Dates"
88
+ />
89
+ </SideNavigation.List>
90
+ </>
91
+ }
92
+ };
@@ -10,7 +10,7 @@ test('side navigation renders correctly', () => {
10
10
  <SideNavigation.List>
11
11
  <SideNavigation.Item href="#green-apples" title="Green apples">
12
12
  <SideNavigation.List>
13
- <SideNavigation.Item href="#bramley" title="Bramley" current/>
13
+ <SideNavigation.Item href="#bramley" title="Bramley" isCurrent/>
14
14
  <SideNavigation.Item href="#granny-smith" title="Granny smith"/>
15
15
  </SideNavigation.List>
16
16
  </SideNavigation.Item>
@@ -60,7 +60,7 @@ test('side nav link renders correctly', () => {
60
60
 
61
61
  test('current side nav item without link renders correctly', () => {
62
62
  render(
63
- <SideNavigation.Item href="#green-apples" title="Green apples" current />
63
+ <SideNavigation.Item href="#green-apples" title="Green apples" isCurrent />
64
64
  );
65
65
 
66
66
  const item = screen.getByRole('listitem');
@@ -18,7 +18,7 @@ const SideNavigationList = function ({
18
18
  const SideNavigationItem = function ({
19
19
  children,
20
20
  href,
21
- current = false,
21
+ isCurrent = false,
22
22
  linkComponent,
23
23
  title
24
24
  }: SGDS.Component.SideNavigation.Item) {
@@ -31,7 +31,7 @@ const SideNavigationItem = function ({
31
31
  children && 'ds_side-navigation__item--has-children'
32
32
  ].join(' ')}
33
33
  >
34
- {current ?
34
+ {isCurrent ?
35
35
  <span className={LINK_CLASS + ' ds_current'}>{title}</span> :
36
36
  linkComponent ? linkComponent({ className: LINK_CLASS, href, children: title }) :
37
37
  <a href={href} className={LINK_CLASS}>{title}</a>