@transferwise/components 46.98.1 → 46.100.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 (64) hide show
  1. package/build/accordion/Accordion.js +4 -0
  2. package/build/accordion/Accordion.js.map +1 -1
  3. package/build/accordion/Accordion.mjs +4 -0
  4. package/build/accordion/Accordion.mjs.map +1 -1
  5. package/build/accordion/AccordionItem/AccordionItem.js +14 -5
  6. package/build/accordion/AccordionItem/AccordionItem.js.map +1 -1
  7. package/build/accordion/AccordionItem/AccordionItem.mjs +14 -5
  8. package/build/accordion/AccordionItem/AccordionItem.mjs.map +1 -1
  9. package/build/body/Body.js +2 -1
  10. package/build/body/Body.js.map +1 -1
  11. package/build/body/Body.mjs +2 -1
  12. package/build/body/Body.mjs.map +1 -1
  13. package/build/instructionsList/InstructionsList.js +1 -0
  14. package/build/instructionsList/InstructionsList.js.map +1 -1
  15. package/build/instructionsList/InstructionsList.mjs +1 -0
  16. package/build/instructionsList/InstructionsList.mjs.map +1 -1
  17. package/build/main.css +19 -16
  18. package/build/styles/accordion/Accordion.css +4 -1
  19. package/build/styles/body/Body.css +3 -0
  20. package/build/styles/main.css +19 -16
  21. package/build/styles/switch/Switch.css +22 -41
  22. package/build/styles/switchOption/SwitchOption.css +4 -0
  23. package/build/switch/Switch.js +7 -18
  24. package/build/switch/Switch.js.map +1 -1
  25. package/build/switch/Switch.mjs +8 -19
  26. package/build/switch/Switch.mjs.map +1 -1
  27. package/build/switchOption/SwitchOption.js +1 -0
  28. package/build/switchOption/SwitchOption.js.map +1 -1
  29. package/build/switchOption/SwitchOption.mjs +1 -0
  30. package/build/switchOption/SwitchOption.mjs.map +1 -1
  31. package/build/types/accordion/Accordion.d.ts +1 -1
  32. package/build/types/accordion/Accordion.d.ts.map +1 -1
  33. package/build/types/accordion/AccordionItem/AccordionItem.d.ts +12 -0
  34. package/build/types/accordion/AccordionItem/AccordionItem.d.ts.map +1 -1
  35. package/build/types/body/Body.d.ts +5 -0
  36. package/build/types/body/Body.d.ts.map +1 -1
  37. package/build/types/switch/Switch.d.ts.map +1 -1
  38. package/build/types/switchOption/SwitchOption.d.ts.map +1 -1
  39. package/package.json +7 -7
  40. package/src/accordion/Accordion.css +4 -1
  41. package/src/accordion/Accordion.less +10 -5
  42. package/src/accordion/Accordion.story.tsx +30 -1
  43. package/src/accordion/Accordion.tsx +5 -4
  44. package/src/accordion/AccordionItem/AccordionItem.tsx +25 -4
  45. package/src/body/Body.css +3 -0
  46. package/src/body/Body.less +3 -0
  47. package/src/body/Body.spec.tsx +8 -0
  48. package/src/body/Body.story.tsx +12 -0
  49. package/src/body/Body.tsx +11 -2
  50. package/src/instructionsList/InstructionsList.story.tsx +35 -37
  51. package/src/instructionsList/InstructionsList.tsx +1 -1
  52. package/src/main.css +19 -16
  53. package/src/main.less +2 -0
  54. package/src/switch/Switch.css +22 -41
  55. package/src/switch/Switch.less +6 -12
  56. package/src/switch/Switch.spec.tsx +11 -9
  57. package/src/switch/Switch.story.tsx +158 -33
  58. package/src/switch/Switch.tsx +6 -15
  59. package/src/switchOption/SwitchOption.css +4 -0
  60. package/src/switchOption/SwitchOption.less +8 -0
  61. package/src/switchOption/SwitchOption.spec.tsx +4 -5
  62. package/src/switchOption/SwitchOption.story.tsx +42 -38
  63. package/src/switchOption/SwitchOption.tsx +1 -0
  64. package/src/switch/__snapshots__/Switch.spec.tsx.snap +0 -44
@@ -18,6 +18,9 @@ export const Basic = () => {
18
18
  We’re building the world’s most <strong>international account</strong>. We’re building the
19
19
  world’s most <b>international account</b>.
20
20
  </Body>
21
+ <Body as="p" type={Typography.BODY_LARGE_BOLD} preserveNewlines>
22
+ {'This is line one.\nThis is line two.'}
23
+ </Body>
21
24
  <Body as="p" type={Typography.BODY_LARGE_BOLD}>
22
25
  Ми будуємо найбільш <strong>міжнародний рахунок у світі</strong>. Ми будуємо найбільш{' '}
23
26
  <b>міжнародний рахунок у світі</b>.
@@ -40,6 +43,9 @@ export const Basic = () => {
40
43
  We’re building the world’s most <strong>international account</strong>. We’re building the
41
44
  world’s most <b>international account</b>.
42
45
  </Body>
46
+ <Body as="p" preserveNewlines>
47
+ {'This is line one.\nThis is line two.'}
48
+ </Body>
43
49
  <Body as="p" type={Typography.BODY_DEFAULT}>
44
50
  Ми будуємо найбільш <strong>міжнародний рахунок у світі</strong>. Ми будуємо найбільш{' '}
45
51
  <b>міжнародний рахунок у світі</b>.
@@ -62,6 +68,9 @@ export const Basic = () => {
62
68
  We’re building the world’s most <strong>international account</strong>. We’re building the
63
69
  world’s most <b>international account</b>.
64
70
  </Body>
71
+ <Body as="p" type={Typography.BODY_DEFAULT_BOLD} preserveNewlines>
72
+ {'This is line one.\nThis is line two.'}
73
+ </Body>
65
74
  <Body as="p" type={Typography.BODY_DEFAULT_BOLD}>
66
75
  Ми будуємо найбільш <strong>міжнародний рахунок у світі</strong>. Ми будуємо найбільш{' '}
67
76
  <b>міжнародний рахунок у світі</b>.
@@ -84,6 +93,9 @@ export const Basic = () => {
84
93
  We’re building the world’s most <strong>international account</strong>. We’re building the
85
94
  world’s most <b>international account</b>.
86
95
  </Body>
96
+ <Body as="p" type={Typography.BODY_LARGE} preserveNewlines>
97
+ {'This is line one.\nThis is line two.'}
98
+ </Body>
87
99
  <Body as="p" type={Typography.BODY_LARGE}>
88
100
  Ми будуємо найбільш <strong>міжнародний рахунок у світі</strong>. Ми будуємо найбільш{' '}
89
101
  <b>міжнародний рахунок у світі</b>.
package/src/body/Body.tsx CHANGED
@@ -21,10 +21,15 @@ type Props = HTMLAttributes<HTMLSpanElement | HTMLParagraphElement> & {
21
21
  * Default value: `div`
22
22
  */
23
23
  as?: 'span' | 'p' | 'div';
24
+ /**
25
+ * When true, preserves newline characters in the text
26
+ * @default false
27
+ */
28
+ preserveNewlines?: boolean;
24
29
  };
25
30
 
26
31
  const Body = forwardRef(function Body(
27
- { as: Element = 'div', type = DEFAULT_TYPE, className, ...props }: Props,
32
+ { as: Element = 'div', type = DEFAULT_TYPE, className, preserveNewlines, ...props }: Props,
28
33
  reference: React.ForwardedRef<
29
34
  | {
30
35
  [key in typeof Element]: React.ElementRef<key>;
@@ -39,7 +44,11 @@ const Body = forwardRef(function Body(
39
44
  // @ts-expect-error TODO: Remove when component could be rewritten with generics
40
45
  // See: https://fettblog.eu/typescript-react-generic-forward-refs/
41
46
  ref={reference}
42
- className={clsx(`np-text-${isTypeSupported ? type : DEFAULT_TYPE}`, className)}
47
+ className={clsx(
48
+ `np-text-${isTypeSupported ? type : DEFAULT_TYPE}`,
49
+ preserveNewlines && 'np-text--pre-line',
50
+ className,
51
+ )}
43
52
  />
44
53
  );
45
54
  });
@@ -1,4 +1,6 @@
1
- import { StoryFn } from '@storybook/react';
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { fn } from '@storybook/test';
3
+ import { storyConfig } from '../test-utils';
2
4
 
3
5
  import Link from '../link';
4
6
 
@@ -7,46 +9,42 @@ import InstructionsList, { InstructionsListProps } from './InstructionsList';
7
9
  export default {
8
10
  component: InstructionsList,
9
11
  title: 'Typography/InstructionsList',
10
- };
12
+ render: (args) => <InstructionsList {...args} />,
13
+ tags: ['autodocs'],
14
+ } satisfies Meta<typeof InstructionsList>;
15
+
16
+ type Story = StoryObj<typeof InstructionsList>;
11
17
 
12
- export const Template: StoryFn = (args: InstructionsListProps) => {
13
- return (
14
- <>
15
- <InstructionsList
16
- className={args.className}
17
- dos={[
18
- 'Do an initial money transfer',
19
- 'Invite at least 3 friends',
20
- <span key="12">
21
- Paying extra{' '}
22
- <Link href="" type="link-large">
23
- hidden fees
24
- </Link>{' '}
25
- for transfers
26
- </span>,
27
- ]}
28
- donts={['Paying extra hidden fees for transfers', 'Use bad exchange rate']}
29
- sort={args.sort}
30
- />
31
- <hr />
32
- <InstructionsList
33
- dos={[
34
- { content: 'Multiple currencies', 'aria-label': 'Supports multiple currencies' },
35
- { content: 'Existing recipients', 'aria-label': 'Supports existing recipients' },
36
- ]}
37
- donts={[
38
- { content: 'Create recipients', 'aria-label': "Doesn't support creating recipients" },
39
- { content: 'Edit recipients', 'aria-label': "Doesn't support editing recipients" },
40
- ]}
41
- sort={args.sort}
42
- />
43
- </>
44
- );
18
+ export const Basic: Story = {
19
+ args: {
20
+ sort: 'dosFirst',
21
+ dos: [
22
+ 'Do an initial money transfer',
23
+ 'Invite at least 3 friends',
24
+ <span key="12">
25
+ Paying extra{' '}
26
+ <Link href="" type="link-large">
27
+ hidden fees
28
+ </Link>{' '}
29
+ for transfers
30
+ </span>,
31
+ ],
32
+ donts: ['Paying extra hidden fees for transfers', 'Use bad exchange rate'],
33
+ },
45
34
  };
46
35
 
47
- export const Basic = {
48
- render: Template,
36
+ export const WithNewLine: Story = {
49
37
  args: {
50
38
  sort: 'dosFirst',
39
+ dos: [
40
+ 'Do an initial money transfer',
41
+ 'Invite at least 3 friends',
42
+ 'This do item has a newline:\nSecond line appears below',
43
+ ],
44
+ donts: [
45
+ 'Paying extra hidden fees for transfers',
46
+ 'Use bad exchange rate',
47
+ 'This dont item has a newline:\nSecond line appears below',
48
+ ],
51
49
  },
52
50
  };
@@ -71,7 +71,7 @@ function Instruction({ item, type }: { item: ReactNode | InstructionNode; type:
71
71
  title={isInstructionNode ? item['aria-label'] : undefined}
72
72
  />
73
73
  )}
74
- <Body className="text-primary" type={Typography.BODY_LARGE}>
74
+ <Body className="text-primary" type={Typography.BODY_LARGE} preserveNewlines>
75
75
  {isInstructionNode ? item.content : item}
76
76
  </Body>
77
77
  </li>
package/src/main.css CHANGED
@@ -72,11 +72,15 @@
72
72
  font-weight: 600;
73
73
  font-weight: var(--font-weight-semi-bold);
74
74
  }
75
+ .np-theme-personal .np-accordion-item--with-media .media {
76
+ display: flex;
77
+ align-items: center;
78
+ }
75
79
  .np-theme-personal .np-accordion-item--with-icon .np-accordion-item__content {
76
80
  padding: 0 56px 16px;
77
81
  padding: 0 var(--size-56) var(--size-16);
78
82
  }
79
- .np-theme-personal .np-accordion-item .media {
83
+ .np-theme-personal .np-accordion-item--with-icon .media {
80
84
  display: flex;
81
85
  align-items: flex-start;
82
86
  }
@@ -658,6 +662,9 @@
658
662
  border-width: 1px;
659
663
  border-color: var(--badge-border-color);
660
664
  }
665
+ .np-text--pre-line {
666
+ white-space: pre-line;
667
+ }
661
668
  .np-btn {
662
669
  position: relative;
663
670
  }
@@ -5142,6 +5149,8 @@ html:not([dir="rtl"]) .np-navigation-option {
5142
5149
  margin-top: var(--size-24);
5143
5150
  }
5144
5151
  .np-switch {
5152
+ all: unset;
5153
+ box-sizing: border-box;
5145
5154
  display: inline-flex;
5146
5155
  overflow: hidden;
5147
5156
  width: 50px;
@@ -5150,6 +5159,7 @@ html:not([dir="rtl"]) .np-navigation-option {
5150
5159
  -webkit-user-select: none;
5151
5160
  -moz-user-select: none;
5152
5161
  user-select: none;
5162
+ cursor: pointer;
5153
5163
  }
5154
5164
  .np-switch:focus {
5155
5165
  outline: none;
@@ -5182,21 +5192,10 @@ html:not([dir="rtl"]) .np-navigation-option {
5182
5192
  [dir="rtl"] .np-switch--checked .np-switch--thumb {
5183
5193
  transform: translateX(-20px) ;
5184
5194
  }
5185
- .np-switch input {
5186
- position: absolute;
5187
- left: -100%;
5188
- display: none;
5189
- width: 0;
5190
- height: 0;
5191
- opacity: 0;
5192
- }
5193
- [dir="rtl"] .np-switch input {
5194
- right: -100%;
5195
- left: auto;
5196
- left: initial;
5197
- }
5198
- .np-switch:not([aria-disabled]) {
5199
- cursor: pointer;
5195
+ .np-switch.disabled {
5196
+ filter: grayscale(1);
5197
+ opacity: 0.45;
5198
+ cursor: not-allowed !important;
5200
5199
  }
5201
5200
  .np-theme-personal .np-switch {
5202
5201
  padding: 1px 2px;
@@ -5212,6 +5211,10 @@ html:not([dir="rtl"]) .np-navigation-option {
5212
5211
  background-color: #ffffff;
5213
5212
  background-color: var(--color-background-screen);
5214
5213
  }
5214
+ .np-switch-option.disabled .np-switch {
5215
+ filter: none;
5216
+ opacity: 1;
5217
+ }
5215
5218
  .tabs {
5216
5219
  position: relative;
5217
5220
  }
package/src/main.less CHANGED
@@ -8,6 +8,7 @@
8
8
  @import "./avatarLayout/AvatarLayout.less";
9
9
  @import "./iconButton/IconButton.less";
10
10
  @import "./badge/Badge.less";
11
+ @import "./body/Body.less";
11
12
  @import "./button/LegacyButton.less";
12
13
  @import "./button/Button.less";
13
14
  @import "./card/Card.less";
@@ -64,6 +65,7 @@
64
65
  @import "./segmentedControl/SegmentedControl.less";
65
66
  @import "./summary/Summary.less";
66
67
  @import "./switch/Switch.less";
68
+ @import "./switchOption/SwitchOption.less";
67
69
  @import "./tabs/Tabs.less";
68
70
  @import "./table/Table.less";
69
71
  @import "./tile/Tile.less";
@@ -1,4 +1,8 @@
1
- .np-switch {
1
+ @media (min-width: 768px) {
2
+ }@media (min-width: 768px) {
3
+ }.np-switch {
4
+ all: unset;
5
+ box-sizing: border-box;
2
6
  display: inline-flex;
3
7
  overflow: hidden;
4
8
  width: 50px;
@@ -7,61 +11,38 @@
7
11
  -webkit-user-select: none;
8
12
  -moz-user-select: none;
9
13
  user-select: none;
10
- }
11
- .np-switch:focus {
14
+ cursor: pointer;
15
+ }.np-switch:focus {
12
16
  outline: none;
13
- }
14
- .np-switch:focus-visible {
17
+ }.np-switch:focus-visible {
15
18
  outline: var(--ring-outline-color) solid var(--ring-outline-width);
16
19
  outline-offset: var(--ring-outline-offset);
17
- }
18
- .np-switch--thumb {
20
+ }.np-switch--thumb {
19
21
  display: flex;
20
22
  transition: transform cubic-bezier(0, 0.94, 0.62, 1) 350ms;
21
- }
22
- .np-switch--thumb .tw-icon {
23
+ }.np-switch--thumb .tw-icon {
23
24
  color: #fff;
24
- }
25
- .np-switch--unchecked {
25
+ }.np-switch--unchecked {
26
26
  background: #c9cbce;
27
27
  background: var(--color-interactive-secondary);
28
- }
29
- .np-switch--unchecked .switch--thumb {
28
+ }.np-switch--unchecked .switch--thumb {
30
29
  transform: translateX(0);
31
- }
32
- .np-switch--checked {
30
+ }.np-switch--checked {
33
31
  background: #00a2dd;
34
32
  background: var(--color-interactive-accent);
35
- }
36
- .np-switch--checked .np-switch--thumb {
33
+ }.np-switch--checked .np-switch--thumb {
37
34
  transform: translateX(20px) ;
38
- }
39
- [dir="rtl"] .np-switch--checked .np-switch--thumb {
35
+ }[dir="rtl"] .np-switch--checked .np-switch--thumb {
40
36
  transform: translateX(-20px) ;
41
- }
42
- .np-switch input {
43
- position: absolute;
44
- left: -100%;
45
- display: none;
46
- width: 0;
47
- height: 0;
48
- opacity: 0;
49
- }
50
- [dir="rtl"] .np-switch input {
51
- right: -100%;
52
- left: auto;
53
- left: initial;
54
- }
55
- .np-switch:not([aria-disabled]) {
56
- cursor: pointer;
57
- }
58
- .np-theme-personal .np-switch {
37
+ }.np-switch.disabled {
38
+ filter: grayscale(1);
39
+ opacity: 0.45;
40
+ cursor: not-allowed !important;
41
+ }.np-theme-personal .np-switch {
59
42
  padding: 1px 2px;
60
- }
61
- .np-theme-personal .np-switch--checked {
43
+ }.np-theme-personal .np-switch--checked {
62
44
  background: var(--color-interactive-primary);
63
- }
64
- .np-theme-personal .np-switch--thumb {
45
+ }.np-theme-personal .np-switch--thumb {
65
46
  width: 20px;
66
47
  height: 20px;
67
48
  margin: 3px;
@@ -1,14 +1,18 @@
1
1
  @import (reference) "../../node_modules/@transferwise/neptune-css/src/variables/neptune-tokens.less";
2
2
  @import (reference) "../../node_modules/@transferwise/neptune-css/src/less/mixins/_logical-properties.less";
3
3
  @import (reference) "../../node_modules/@transferwise/neptune-css/src/less/ring.less";
4
+ @import (reference) "../../node_modules/@transferwise/neptune-css/src/less/core/_scaffolding.less";
4
5
 
5
6
  .np-switch {
7
+ all: unset;
8
+ box-sizing: border-box;
6
9
  display: inline-flex;
7
10
  overflow: hidden;
8
11
  width: 50px;
9
12
  padding: 2px;
10
13
  border-radius: 16px;
11
14
  user-select: none;
15
+ cursor: pointer;
12
16
 
13
17
  .focus-ring();
14
18
 
@@ -37,18 +41,8 @@
37
41
  }
38
42
  }
39
43
 
40
- input {
41
- position: absolute;
42
- .left(-100%);
43
-
44
- display: none;
45
- width: 0;
46
- height: 0;
47
- opacity: 0;
48
- }
49
-
50
- &:not([aria-disabled]) {
51
- cursor: pointer;
44
+ &.disabled{
45
+ .disabled();
52
46
  }
53
47
  }
54
48
 
@@ -1,5 +1,5 @@
1
1
  import { Field } from '../field/Field';
2
- import { render, fireEvent, screen } from '../test-utils';
2
+ import { render, userEvent, fireEvent, screen } from '../test-utils';
3
3
 
4
4
  import Switch from './Switch';
5
5
 
@@ -22,7 +22,7 @@ describe('Switch', () => {
22
22
  onClick={props.onClick}
23
23
  />,
24
24
  );
25
- expect(container).toMatchSnapshot();
25
+ expect(screen.getByRole('switch')).toBeChecked();
26
26
  });
27
27
 
28
28
  it('renders component associated with label', () => {
@@ -54,25 +54,27 @@ describe('Switch', () => {
54
54
  onClick={props.onClick}
55
55
  />,
56
56
  );
57
- expect(container).toMatchSnapshot();
57
+ expect(screen.getByLabelText(props['aria-label'])).not.toBeChecked();
58
58
  });
59
59
 
60
- it('calls onClick when user press space key', () => {
60
+ it('calls onClick when user press space or enter key', async () => {
61
61
  render(
62
62
  <Switch
63
- checked={props.checked}
64
63
  className={props.className}
65
- id={props.id}
66
64
  aria-label={props['aria-label']}
67
65
  onClick={props.onClick}
68
66
  />,
69
67
  );
70
68
 
71
- const input = screen.getAllByRole('checkbox')[0];
72
- fireEvent.keyDown(input, { key: 'Enter' });
73
69
  expect(props.onClick).not.toHaveBeenCalled();
74
- fireEvent.keyDown(input, { key: ' ' });
70
+
71
+ await userEvent.tab();
72
+
73
+ await userEvent.keyboard(' ');
75
74
  expect(props.onClick).toHaveBeenCalledTimes(1);
75
+
76
+ await userEvent.keyboard('{Enter}');
77
+ expect(props.onClick).toHaveBeenCalledTimes(2);
76
78
  });
77
79
 
78
80
  it('should not call onClick if disabled', () => {
@@ -1,59 +1,184 @@
1
1
  import { useState } from 'react';
2
+ import { fn } from '@storybook/test';
2
3
 
3
- import Switch from './Switch';
4
+ import Switch, { SwitchProps } from './Switch';
4
5
  import { Field } from '../field/Field';
6
+ import { Meta, StoryObj } from '@storybook/react';
7
+ import { Label } from '../label';
5
8
 
6
- export default {
9
+ const meta: Meta<typeof Switch> = {
7
10
  component: Switch,
8
11
  title: 'Actions/Switch',
12
+ args: {
13
+ checked: false,
14
+ disabled: false,
15
+ id: 'switchId',
16
+ className: 'switchClassName',
17
+ 'aria-labelledby': undefined,
18
+ 'aria-label': undefined,
19
+ onClick: fn(),
20
+ },
21
+ tags: ['autodocs'],
22
+ } satisfies Meta<typeof Switch>;
23
+
24
+ export default meta;
25
+ type Story = StoryObj<typeof Switch>;
26
+
27
+ export const Basic: Story = {
28
+ tags: ['!autodocs', '!dev'],
29
+ };
30
+
31
+ export const Playground: Story = {
32
+ tags: ['!autodocs'],
33
+ argTypes: {
34
+ onClick: { table: { disable: true } },
35
+ },
9
36
  };
10
37
 
11
- export const Basic = () => {
38
+ export const Interactivity: Story = {
39
+ render: function Render({ disabled }: SwitchProps) {
40
+ const [checked1, setCheck1] = useState(false);
41
+ const [checked2, setCheck2] = useState(true);
42
+ const [checked3, setCheck3] = useState(false);
43
+
44
+ return (
45
+ <>
46
+ <Field id="fieldId" label="Using Field component">
47
+ <Switch checked={checked1} disabled={disabled} onClick={() => setCheck1(!checked1)} />
48
+ </Field>
49
+
50
+ <div>
51
+ <Label htmlFor="labelId">Using Label component</Label>
52
+ <Switch
53
+ id="labelId"
54
+ checked={checked2}
55
+ disabled={disabled}
56
+ onClick={() => setCheck2(!checked2)}
57
+ />
58
+ </div>
59
+
60
+ <div>
61
+ <strong id="ariaId" className="d-block">
62
+ Using `aria-labelledby`
63
+ </strong>
64
+ <Switch
65
+ aria-labelledby="ariaId"
66
+ checked={checked3}
67
+ disabled={disabled}
68
+ onClick={() => setCheck3(!checked3)}
69
+ />
70
+ </div>
71
+ </>
72
+ );
73
+ },
74
+ parameters: {
75
+ docs: {
76
+ source: {
77
+ code: `
78
+ function Render() {
12
79
  const [checked1, setCheck1] = useState(false);
13
80
  const [checked2, setCheck2] = useState(true);
14
-
81
+ const [checked3, setCheck3] = useState(false);
82
+
15
83
  return (
16
- <div className="d-flex flex-column">
17
- <Field id="switchId" label="A switch with a label" required>
84
+ <>
85
+ <Field id="fieldId" label="Using Field component">
18
86
  <Switch
19
87
  checked={checked1}
20
- className="a-class-name"
21
- id="switchId"
22
88
  onClick={() => setCheck1(!checked1)}
23
89
  />
24
90
  </Field>
25
- <Switch
26
- aria-label="I'm a switch without label"
27
- checked={checked2}
28
- className="a-class-name"
29
- onClick={() => setCheck2(!checked2)}
30
- />
31
- </div>
32
- );
91
+
92
+ <div>
93
+ <Label htmlFor="labelId">Using standalone Label component</Label>
94
+ <Switch
95
+ id="labelId"
96
+ checked={checked2}
97
+ onClick={() => setCheck2(!checked2)}
98
+ />
99
+ </div>
100
+
101
+ <div>
102
+ <strong id="ariaId" className="d-block">Using \`aria-labelledby\`</strong>
103
+ <Switch
104
+ aria-labelledby="ariaId"
105
+ checked={checked3}
106
+ onClick={() => setCheck3(!setCheck3)}
107
+ />
108
+ </div>
109
+ </>
110
+ )
111
+ }`,
112
+ },
113
+ },
114
+ },
115
+ decorators: [
116
+ (Story: any) => (
117
+ <div className="d-flex flex-column" style={{ gap: '1rem' }}>
118
+ <Story />
119
+ </div>
120
+ ),
121
+ ],
122
+ args: {},
123
+ argTypes: {
124
+ checked: { table: { disable: true } },
125
+ onClick: { table: { disable: true } },
126
+ },
33
127
  };
34
128
 
35
- export const Disabled = () => {
36
- const [checked, setCheck] = useState(false);
129
+ export const Disabled: Story = {
130
+ render: function Render(args) {
131
+ const [checked1, setCheck1] = useState(false);
132
+ const [checked2, setCheck2] = useState(true);
133
+
134
+ return (
135
+ <>
136
+ <Field label="Switch label">
137
+ <Switch checked={checked1} disabled onClick={() => setCheck1(!checked1)} />
138
+ </Field>
139
+
140
+ <Field label="Switch label">
141
+ <Switch checked={checked2} disabled onClick={() => setCheck2(!checked2)} />
142
+ </Field>
143
+ </>
144
+ );
145
+ },
146
+ parameters: {
147
+ docs: {
148
+ source: {
149
+ code: `
150
+ function Render() {
151
+ const [checked1, setCheck1] = useState(false);
152
+ const [checked2, setCheck2] = useState(true);
37
153
 
38
154
  return (
39
- <div className="d-flex flex-column">
40
- <Field id="switchId" label="A switch with a label" required>
155
+ <>
156
+ <Field label="Switch label">
157
+ <Switch
158
+ checked={checked1}
159
+ disabled
160
+ onClick={() => setCheck1(!checked1)}
161
+ />
162
+ </Fie
163
+ <Field label="Switch label">
41
164
  <Switch
42
- checked={checked}
165
+ checked={checked2}
43
166
  disabled
44
- className="a-class-name"
45
- id="switchId"
46
- onClick={() => setCheck(!checked)}
167
+ onClick={() => setCheck2(!checked2)}
47
168
  />
48
169
  </Field>
49
- <Switch
50
- aria-label="I'm a switch without label"
51
- checked={!checked}
52
- disabled
53
- className="a-class-name"
54
- id="switchId1"
55
- onClick={() => setCheck(!checked)}
56
- />
57
- </div>
170
+ </>
58
171
  );
172
+ }`,
173
+ },
174
+ },
175
+ },
176
+ args: {
177
+ disabled: true,
178
+ },
179
+ argTypes: {
180
+ disabled: { table: { readonly: true } },
181
+ onClick: { table: { disable: true } },
182
+ checked: { table: { disable: true } },
183
+ },
59
184
  };