@nypl/design-system-react-components 0.23.4 → 0.25.1
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/CHANGELOG.md +98 -1
- package/README.md +46 -11
- package/dist/components/Accordion/Accordion.d.ts +14 -14
- package/dist/components/Autosuggest/Autosuggest.stories.d.ts +1 -0
- package/dist/components/Breadcrumbs/Breadcrumbs.d.ts +11 -14
- package/dist/components/Breadcrumbs/BreadcrumbsTypes.d.ts +6 -0
- package/dist/components/Button/Button.d.ts +6 -13
- package/dist/components/Button/ButtonTypes.d.ts +5 -3
- package/dist/components/Card/Card.d.ts +59 -10
- package/dist/components/Card/CardTypes.d.ts +19 -0
- package/dist/components/CardEdition/CardEdition.d.ts +21 -0
- package/dist/components/{StyleGuide/Colors.stories.d.ts → CardEdition/CardEdition.stories.d.ts} +5 -2
- package/dist/components/Checkbox/Checkbox.d.ts +21 -16
- package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +43 -0
- package/dist/components/CheckboxGroup/CheckboxGroupLayoutTypes.d.ts +4 -0
- package/dist/components/DatePicker/DatePicker.d.ts +79 -0
- package/dist/components/DatePicker/DatePickerTypes.d.ts +5 -0
- package/dist/components/Form/Form.d.ts +16 -8
- package/dist/components/Form/FormTypes.d.ts +2 -0
- package/dist/components/Grid/GridTypes.d.ts +9 -0
- package/dist/components/Grid/SimpleGrid.d.ts +14 -0
- package/dist/components/Heading/Heading.d.ts +9 -11
- package/dist/components/Heading/{HeadingDisplaySizes.d.ts → HeadingTypes.d.ts} +8 -0
- package/dist/components/HelperErrorText/HelperErrorText.stories.d.ts +2 -1
- package/dist/components/Hero/Hero.d.ts +19 -14
- package/dist/components/Hero/HeroTypes.d.ts +10 -5
- package/dist/components/Icons/Icon.d.ts +13 -16
- package/dist/components/Icons/IconSvgs.d.ts +4 -0
- package/dist/components/Icons/IconTypes.d.ts +78 -60
- package/dist/components/Image/Image.stories.d.ts +2 -1
- package/dist/components/Label/Label.d.ts +10 -26
- package/dist/components/Link/Link.d.ts +8 -12
- package/dist/components/List/List.stories.d.ts +1 -0
- package/dist/components/Radio/Radio.d.ts +30 -24
- package/dist/components/RadioGroup/RadioGroup.d.ts +40 -0
- package/dist/components/RadioGroup/RadioGroupLayoutTypes.d.ts +4 -0
- package/dist/components/SearchBar/SearchBar.d.ts +45 -27
- package/dist/components/Select/Select.d.ts +34 -35
- package/dist/components/Select/SelectTypes.d.ts +4 -0
- package/dist/components/SkeletonLoader/SkeletonLoader.d.ts +1 -1
- package/dist/components/SkeletonLoader/SkeletonLoaderTypes.d.ts +2 -2
- package/dist/components/StatusBadge/StatusBadge.d.ts +8 -6
- package/dist/components/StatusBadge/StatusBadgeTypes.d.ts +5 -0
- package/dist/components/Tabs/Tabs.d.ts +25 -0
- package/dist/components/Template/Template.d.ts +91 -0
- package/dist/components/Text/Text.d.ts +16 -0
- package/dist/components/Text/TextTypes.d.ts +6 -0
- package/dist/components/TextInput/TextInput.d.ts +37 -30
- package/dist/components/TextInput/TextInputTypes.d.ts +5 -0
- package/dist/design-system-react-components.cjs.development.js +4102 -917
- package/dist/design-system-react-components.cjs.development.js.map +1 -1
- package/dist/design-system-react-components.cjs.production.min.js +1 -1
- package/dist/design-system-react-components.cjs.production.min.js.map +1 -1
- package/dist/design-system-react-components.esm.js +4023 -920
- package/dist/design-system-react-components.esm.js.map +1 -1
- package/dist/index.d.ts +23 -5
- package/dist/resources.scss +133 -24
- package/dist/styles.css +1 -1
- package/dist/theme/components/accordion.d.ts +25 -0
- package/dist/theme/components/breadcrumb.d.ts +90 -0
- package/dist/theme/components/button.d.ts +109 -0
- package/dist/theme/components/checkbox.d.ts +91 -0
- package/dist/theme/components/customCheckboxGroup.d.ts +18 -0
- package/dist/theme/components/customRadioGroup.d.ts +18 -0
- package/dist/theme/components/global.d.ts +55 -0
- package/dist/theme/components/globalMixins.d.ts +15 -0
- package/dist/theme/components/heading.d.ts +110 -0
- package/dist/theme/components/hero.d.ts +492 -0
- package/dist/theme/components/icon.d.ts +13 -0
- package/dist/theme/components/label.d.ts +16 -0
- package/dist/theme/components/link.d.ts +45 -0
- package/dist/theme/components/radio.d.ts +95 -0
- package/dist/theme/components/searchBar.d.ts +20 -0
- package/dist/theme/components/select.d.ts +58 -0
- package/dist/theme/components/statusBadge.d.ts +25 -0
- package/dist/theme/components/tabs.d.ts +85 -0
- package/dist/theme/components/template.d.ts +105 -0
- package/dist/theme/components/text.d.ts +20 -0
- package/dist/theme/components/textInput.d.ts +105 -0
- package/dist/theme/foundations/breakpoints.d.ts +23 -0
- package/dist/theme/foundations/colors.d.ts +3 -0
- package/dist/theme/foundations/global.d.ts +23 -0
- package/dist/theme/foundations/shadows.d.ts +4 -0
- package/dist/theme/foundations/spacing.d.ts +77 -0
- package/dist/theme/foundations/typography.d.ts +8 -0
- package/dist/theme/index.d.ts +20 -0
- package/dist/theme/provider.d.ts +5 -0
- package/dist/theme/types.d.ts +1 -0
- package/dist/utils/utils.d.ts +6 -0
- package/package.json +9 -2
- package/src/components/Accordion/Accordion.stories.mdx +233 -33
- package/src/components/Accordion/Accordion.test.tsx +135 -19
- package/src/components/Accordion/Accordion.tsx +81 -56
- package/src/components/Autosuggest/Autosuggest.stories.mdx +4 -3
- package/src/components/Autosuggest/Autosuggest.stories.tsx +1 -1
- package/src/components/Autosuggest/_Autosuggest.scss +2 -2
- package/src/components/Breadcrumbs/Breadcrumbs.stories.mdx +57 -56
- package/src/components/Breadcrumbs/Breadcrumbs.test.tsx +31 -25
- package/src/components/Breadcrumbs/Breadcrumbs.tsx +71 -73
- package/src/components/Breadcrumbs/BreadcrumbsTypes.tsx +6 -0
- package/src/components/Breadcrumbs/__snapshots__/Breadcrumbs.test.tsx.snap +100 -0
- package/src/components/Button/Button.stories.mdx +125 -138
- package/src/components/Button/Button.test.tsx +65 -11
- package/src/components/Button/Button.tsx +72 -68
- package/src/components/Button/ButtonTypes.tsx +4 -2
- package/src/components/Button/_Button.scss +7 -92
- package/src/components/Button/__snapshots__/Button.test.tsx.snap +58 -3
- package/src/components/Card/Card.stories.mdx +694 -0
- package/src/components/Card/Card.test.tsx +97 -102
- package/src/components/Card/Card.tsx +182 -31
- package/src/components/Card/CardTypes.tsx +21 -0
- package/src/components/Card/_Card.scss +234 -49
- package/src/components/{Card/Card.stories.tsx → CardEdition/CardEdition.stories.tsx} +32 -22
- package/src/components/CardEdition/CardEdition.test.tsx +395 -0
- package/src/components/CardEdition/CardEdition.tsx +60 -0
- package/src/components/CardEdition/_CardEdition.scss +138 -0
- package/src/components/Chakra/Box.stories.mdx +57 -0
- package/src/components/Chakra/Center.stories.mdx +99 -0
- package/src/components/Chakra/Grid.stories.mdx +79 -0
- package/src/components/Chakra/Stack.stories.mdx +93 -0
- package/src/components/Checkbox/Checkbox.stories.mdx +57 -35
- package/src/components/Checkbox/Checkbox.test.tsx +117 -147
- package/src/components/Checkbox/Checkbox.tsx +76 -50
- package/src/components/Checkbox/__snapshots__/Checkbox.test.tsx.snap +325 -0
- package/src/components/CheckboxGroup/CheckboxGroup.stories.mdx +249 -0
- package/src/components/CheckboxGroup/CheckboxGroup.test.tsx +345 -0
- package/src/components/CheckboxGroup/CheckboxGroup.tsx +148 -0
- package/src/components/CheckboxGroup/CheckboxGroupLayoutTypes.tsx +4 -0
- package/src/components/CheckboxGroup/__snapshots__/CheckboxGroup.test.tsx.snap +1360 -0
- package/src/components/DatePicker/DatePicker.stories.mdx +284 -0
- package/src/components/DatePicker/DatePicker.test.tsx +657 -0
- package/src/components/DatePicker/DatePicker.tsx +396 -0
- package/src/components/DatePicker/DatePickerTypes.tsx +5 -0
- package/src/components/DatePicker/_DatePicker.scss +76 -0
- package/src/components/Form/Form.stories.mdx +130 -27
- package/src/components/Form/Form.test.tsx +78 -36
- package/src/components/Form/Form.tsx +53 -19
- package/src/components/Form/FormTypes.tsx +3 -0
- package/src/components/Form/__snapshots__/Form.test.tsx.snap +38 -0
- package/src/components/Grid/GridTypes.tsx +9 -0
- package/src/components/Grid/SimpleGrid.stories.mdx +275 -0
- package/src/components/Grid/SimpleGrid.test.tsx +66 -0
- package/src/components/Grid/SimpleGrid.tsx +37 -0
- package/src/components/Grid/__snapshots__/SimpleGrid.test.tsx.snap +8 -0
- package/src/components/Heading/Heading.stories.mdx +63 -33
- package/src/components/Heading/Heading.test.tsx +24 -16
- package/src/components/Heading/Heading.tsx +54 -38
- package/src/components/Heading/{HeadingDisplaySizes.tsx → HeadingTypes.tsx} +9 -0
- package/src/components/HelperErrorText/HelperErrorText.stories.tsx +2 -1
- package/src/components/HelperErrorText/_HelperErrorText.scss +1 -1
- package/src/components/Hero/Hero.stories.mdx +195 -85
- package/src/components/Hero/Hero.test.tsx +544 -113
- package/src/components/Hero/Hero.tsx +80 -93
- package/src/components/Hero/HeroTypes.tsx +17 -5
- package/src/components/Hero/__snapshots__/Hero.test.tsx.snap +307 -0
- package/src/components/HorizontalRule/HorizontalRule.stories.mdx +6 -1
- package/src/components/HorizontalRule/_HorizontalRule.scss +1 -1
- package/src/components/Icons/Icon.stories.mdx +89 -74
- package/src/components/Icons/Icon.test.tsx +30 -22
- package/src/components/Icons/Icon.tsx +63 -61
- package/src/components/Icons/IconSvgs.tsx +8 -0
- package/src/components/Icons/IconTypes.tsx +80 -60
- package/src/components/Image/Image.stories.tsx +2 -1
- package/src/components/Input/_Input.scss +2 -2
- package/src/components/Label/Label.stories.mdx +77 -0
- package/src/components/Label/Label.test.tsx +43 -12
- package/src/components/Label/Label.tsx +28 -45
- package/src/components/Label/__snapshots__/Label.test.tsx.snap +41 -0
- package/src/components/Link/Link.stories.mdx +47 -41
- package/src/components/Link/Link.test.tsx +33 -44
- package/src/components/Link/Link.tsx +114 -100
- package/src/components/List/List.stories.mdx +7 -3
- package/src/components/List/List.stories.tsx +14 -9
- package/src/components/List/List.test.tsx +12 -8
- package/src/components/List/List.tsx +9 -7
- package/src/components/List/_List.scss +3 -3
- package/src/components/Modal/Modal.stories.mdx +7 -3
- package/src/components/Modal/_Modal.scss +1 -1
- package/src/components/Notification/Notification.stories.mdx +99 -65
- package/src/components/Notification/Notification.test.tsx +3 -16
- package/src/components/Notification/Notification.tsx +12 -12
- package/src/components/Notification/_Notification.scss +5 -4
- package/src/components/Notification/__snapshots__/Notification.test.tsx.snap +1 -1
- package/src/components/Pagination/Pagination.stories.mdx +7 -1
- package/src/components/Pagination/Pagination.test.tsx +16 -10
- package/src/components/Radio/Radio.stories.mdx +57 -46
- package/src/components/Radio/Radio.test.tsx +92 -138
- package/src/components/Radio/Radio.tsx +70 -69
- package/src/components/Radio/__snapshots__/Radio.test.tsx.snap +250 -0
- package/src/components/RadioGroup/RadioGroup.stories.mdx +247 -0
- package/src/components/RadioGroup/RadioGroup.test.tsx +327 -0
- package/src/components/RadioGroup/RadioGroup.tsx +154 -0
- package/src/components/RadioGroup/RadioGroupLayoutTypes.tsx +4 -0
- package/src/components/RadioGroup/__snapshots__/RadioGroup.test.tsx.snap +1101 -0
- package/src/components/SearchBar/SearchBar.Test.tsx +151 -16
- package/src/components/SearchBar/SearchBar.stories.mdx +196 -224
- package/src/components/SearchBar/SearchBar.tsx +151 -46
- package/src/components/Select/Select.stories.mdx +193 -168
- package/src/components/Select/Select.test.tsx +129 -324
- package/src/components/Select/Select.tsx +120 -160
- package/src/components/Select/SelectTypes.tsx +4 -0
- package/src/components/SkeletonLoader/SkeletonLoader.stories.mdx +18 -29
- package/src/components/SkeletonLoader/SkeletonLoader.test.tsx +7 -7
- package/src/components/SkeletonLoader/SkeletonLoader.tsx +4 -2
- package/src/components/SkeletonLoader/SkeletonLoaderTypes.tsx +2 -2
- package/src/components/SkeletonLoader/_SkeletonLoader.scss +3 -3
- package/src/components/StatusBadge/StatusBadge.stories.mdx +91 -0
- package/src/components/StatusBadge/StatusBadge.test.tsx +35 -7
- package/src/components/StatusBadge/StatusBadge.tsx +24 -25
- package/src/components/StatusBadge/StatusBadgeTypes.tsx +5 -0
- package/src/components/StatusBadge/__snapshots__/StatusBadge.test.tsx.snap +28 -0
- package/src/components/StyleGuide/Bidirectionality.stories.mdx +112 -90
- package/src/components/StyleGuide/Buttons.stories.mdx +98 -100
- package/src/components/StyleGuide/Colors.stories.mdx +336 -0
- package/src/components/StyleGuide/Forms.stories.mdx +85 -0
- package/src/components/StyleGuide/Iconography.stories.mdx +86 -93
- package/src/components/StyleGuide/Spacing.stories.mdx +0 -1
- package/src/components/StyleGuide/Typography.stories.mdx +164 -166
- package/src/components/StyleGuide/UIDocCard.tsx +4 -4
- package/src/components/Tabs/Tabs.stories.mdx +221 -0
- package/src/components/Tabs/Tabs.test.tsx +264 -0
- package/src/components/Tabs/Tabs.tsx +220 -0
- package/src/components/Template/Template.stories.mdx +574 -0
- package/src/components/Template/Template.test.tsx +124 -0
- package/src/components/Template/Template.tsx +226 -0
- package/src/components/Text/Text.stories.mdx +70 -0
- package/src/components/Text/Text.test.tsx +63 -0
- package/src/components/Text/Text.tsx +55 -0
- package/src/components/Text/TextTypes.tsx +6 -0
- package/src/components/Text/__snapshots__/Text.test.tsx.snap +33 -0
- package/src/components/TextInput/TextInput.stories.mdx +90 -90
- package/src/components/TextInput/TextInput.test.tsx +103 -83
- package/src/components/TextInput/TextInput.tsx +108 -91
- package/src/components/TextInput/TextInputTypes.tsx +6 -0
- package/src/components/VideoPlayer/VideoPlayer.stories.mdx +2 -1
- package/src/components/VideoPlayer/VideoPlayer.tsx +4 -2
- package/src/components/VideoPlayer/_VideoPlayer.scss +1 -1
- package/src/docs/Chakra.stories.mdx +341 -0
- package/src/docs/Intro.stories.mdx +31 -24
- package/src/index.ts +70 -5
- package/src/styles/01-colors/_colors-brand.scss +6 -4
- package/src/styles/01-colors/_colors-utility.scss +14 -15
- package/src/styles/03-space/_space-inline.scss +47 -7
- package/src/styles/03-space/_space-inset.scss +33 -5
- package/src/styles/03-space/_space-stack.scss +48 -8
- package/src/styles/base/_02-breakpoints.scss +5 -4
- package/src/styles/base/_04-base.scss +2 -1
- package/src/styles/base/_place-holder.scss +1 -1
- package/src/styles/base/_typography.scss +1 -29
- package/src/styles.scss +22 -25
- package/src/theme/components/accordion.ts +30 -0
- package/src/theme/components/breadcrumb.ts +77 -0
- package/src/theme/components/button.ts +125 -0
- package/src/theme/components/checkbox.ts +107 -0
- package/src/theme/components/customCheckboxGroup.ts +12 -0
- package/src/theme/components/customRadioGroup.ts +12 -0
- package/src/theme/components/global.ts +71 -0
- package/src/theme/components/globalMixins.ts +16 -0
- package/src/theme/components/heading.ts +72 -0
- package/src/theme/components/hero.ts +239 -0
- package/src/theme/components/icon.ts +79 -0
- package/src/theme/components/label.ts +17 -0
- package/src/theme/components/link.ts +47 -0
- package/src/theme/components/radio.ts +106 -0
- package/src/theme/components/searchBar.ts +21 -0
- package/src/theme/components/select.ts +50 -0
- package/src/theme/components/statusBadge.ts +27 -0
- package/src/theme/components/tabs.ts +79 -0
- package/src/theme/components/template.ts +114 -0
- package/src/theme/components/text.ts +31 -0
- package/src/theme/components/textInput.ts +61 -0
- package/src/theme/foundations/breakpoints.ts +24 -0
- package/src/theme/foundations/colors.ts +208 -0
- package/src/theme/foundations/global.ts +26 -0
- package/src/theme/foundations/shadows.ts +5 -0
- package/src/theme/foundations/spacing.ts +85 -0
- package/src/theme/foundations/typography.ts +35 -0
- package/src/theme/index.ts +88 -0
- package/src/theme/provider.tsx +9 -0
- package/src/theme/types.ts +1 -0
- package/src/utils/componentCategories.ts +56 -21
- package/src/utils/utils.ts +13 -0
- package/dist/components/Accordion/Accordion.stories.d.ts +0 -5
- package/dist/components/Card/Card.stories.d.ts +0 -27
- package/dist/components/Label/Label.stories.d.ts +0 -12
- package/dist/components/StatusBadge/StatusBadge.stories.d.ts +0 -8
- package/dist/components/Template/Template.stories.d.ts +0 -29
- package/src/components/Accordion/Accordion.stories.tsx +0 -65
- package/src/components/Accordion/_Accordion.scss +0 -81
- package/src/components/Breadcrumbs/_Breadcrumbs.scss +0 -97
- package/src/components/Checkbox/_Checkbox.scss +0 -97
- package/src/components/Form/_Form.scss +0 -28
- package/src/components/Heading/_Heading.scss +0 -163
- package/src/components/Hero/_Hero.scss +0 -256
- package/src/components/Icons/_Icons.scss +0 -116
- package/src/components/Label/Label.stories.tsx +0 -30
- package/src/components/Label/_Label.scss +0 -22
- package/src/components/Link/_Link.scss +0 -73
- package/src/components/Radio/_Radio.scss +0 -84
- package/src/components/SearchBar/_SearchBar.scss +0 -16
- package/src/components/Select/_Select.scss +0 -82
- package/src/components/StatusBadge/StatusBadge.stories.tsx +0 -33
- package/src/components/StatusBadge/_StatusBadge.scss +0 -23
- package/src/components/StyleGuide/Colors.stories.tsx +0 -288
- package/src/components/Template/Template.stories.tsx +0 -85
- package/src/components/Template/_Template.scss +0 -63
- package/src/components/TextInput/_TextInput.scss +0 -59
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
import { axe } from "jest-axe";
|
|
4
|
+
import renderer from "react-test-renderer";
|
|
5
|
+
|
|
6
|
+
import * as generateUUID from "../../helpers/generateUUID";
|
|
7
|
+
import RadioGroup from "./RadioGroup";
|
|
8
|
+
import Radio from "../Radio/Radio";
|
|
9
|
+
import { RadioGroupLayoutTypes } from "./RadioGroupLayoutTypes";
|
|
10
|
+
import userEvent from "@testing-library/user-event";
|
|
11
|
+
|
|
12
|
+
describe("Radio Accessibility", () => {
|
|
13
|
+
it("passes axe accessibility", async () => {
|
|
14
|
+
const { container } = render(
|
|
15
|
+
<RadioGroup labelText="RadioGroup example" name="a11y-test">
|
|
16
|
+
<Radio value="2" labelText="Radio 2" />
|
|
17
|
+
<Radio value="3" labelText="Radio 3" />
|
|
18
|
+
<Radio value="4" labelText="Radio 4" />
|
|
19
|
+
<Radio value="5" labelText="Radio 5" />
|
|
20
|
+
</RadioGroup>
|
|
21
|
+
);
|
|
22
|
+
expect(await axe(container)).toHaveNoViolations();
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe("Radio Button", () => {
|
|
27
|
+
it("renders with radio inputs and a label", () => {
|
|
28
|
+
render(
|
|
29
|
+
<RadioGroup labelText="Test Label" name="test1">
|
|
30
|
+
<Radio value="2" labelText="Radio 2" />
|
|
31
|
+
<Radio value="3" labelText="Radio 3" />
|
|
32
|
+
<Radio value="4" labelText="Radio 4" />
|
|
33
|
+
</RadioGroup>
|
|
34
|
+
);
|
|
35
|
+
expect(screen.getByText(/Test Label/i)).toBeInTheDocument();
|
|
36
|
+
expect(screen.getAllByRole("radio")).toHaveLength(3);
|
|
37
|
+
expect(screen.getByText("Radio 2")).toBeInTheDocument();
|
|
38
|
+
expect(screen.getByText("Radio 3")).toBeInTheDocument();
|
|
39
|
+
expect(screen.getByText("Radio 4")).toBeInTheDocument();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("renders with appropriate 'aria-label' attribute and value when 'showLabel' prop is set to false", () => {
|
|
43
|
+
render(
|
|
44
|
+
<RadioGroup labelText="Test Label" name="test2" showLabel={false}>
|
|
45
|
+
<Radio value="2" labelText="Radio 2" />
|
|
46
|
+
<Radio value="3" labelText="Radio 3" />
|
|
47
|
+
<Radio value="4" labelText="Radio 4" />
|
|
48
|
+
</RadioGroup>
|
|
49
|
+
);
|
|
50
|
+
expect(screen.getByRole("radiogroup")).toHaveAttribute(
|
|
51
|
+
"aria-label",
|
|
52
|
+
"Test Label"
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it("renders visible helper or error text", () => {
|
|
57
|
+
const { rerender } = render(
|
|
58
|
+
<RadioGroup
|
|
59
|
+
labelText="Test Label"
|
|
60
|
+
name="test3"
|
|
61
|
+
helperText="This is the helper text for the full group."
|
|
62
|
+
invalidText="This is the error text :("
|
|
63
|
+
>
|
|
64
|
+
<Radio value="2" labelText="Radio 2" />
|
|
65
|
+
<Radio value="3" labelText="Radio 3" />
|
|
66
|
+
<Radio value="4" labelText="Radio 4" />
|
|
67
|
+
</RadioGroup>
|
|
68
|
+
);
|
|
69
|
+
expect(
|
|
70
|
+
screen.getByText("This is the helper text for the full group.")
|
|
71
|
+
).toBeVisible();
|
|
72
|
+
expect(
|
|
73
|
+
screen.queryByText("This is the error text :(")
|
|
74
|
+
).not.toBeInTheDocument();
|
|
75
|
+
|
|
76
|
+
rerender(
|
|
77
|
+
<RadioGroup
|
|
78
|
+
labelText="Test Label"
|
|
79
|
+
name="test4"
|
|
80
|
+
helperText="This is the helper text for the full group."
|
|
81
|
+
invalidText="This is the error text :("
|
|
82
|
+
isInvalid
|
|
83
|
+
>
|
|
84
|
+
<Radio value="2" labelText="Radio 2" />
|
|
85
|
+
<Radio value="3" labelText="Radio 3" />
|
|
86
|
+
<Radio value="4" labelText="Radio 4" />
|
|
87
|
+
</RadioGroup>
|
|
88
|
+
);
|
|
89
|
+
expect(screen.getByText("This is the error text :(")).toBeVisible();
|
|
90
|
+
expect(
|
|
91
|
+
screen.queryByText("This is the helper text for the full group.")
|
|
92
|
+
).not.toBeInTheDocument();
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("sets the RadioGroup's ID", () => {
|
|
96
|
+
render(
|
|
97
|
+
<RadioGroup labelText="Test Label" name="test5" id="some-id">
|
|
98
|
+
<Radio value="2" labelText="Radio 2" />
|
|
99
|
+
</RadioGroup>
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
// The "group" role here is for the `fieldset` element.
|
|
103
|
+
expect(screen.getByRole("group")).toHaveAttribute(
|
|
104
|
+
"id",
|
|
105
|
+
"radio-group-some-id"
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("sets the next value through the onChange function", () => {
|
|
110
|
+
let newValue = "";
|
|
111
|
+
const onChange = (value) => {
|
|
112
|
+
newValue = value;
|
|
113
|
+
};
|
|
114
|
+
render(
|
|
115
|
+
<RadioGroup
|
|
116
|
+
labelText="Test Label"
|
|
117
|
+
name="getValue"
|
|
118
|
+
defaultValue="4"
|
|
119
|
+
onChange={onChange}
|
|
120
|
+
>
|
|
121
|
+
<Radio value="2" labelText="Radio 2" />
|
|
122
|
+
<Radio value="3" labelText="Radio 3" />
|
|
123
|
+
<Radio value="4" labelText="Radio 4" />
|
|
124
|
+
</RadioGroup>
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
expect(newValue).toEqual("");
|
|
128
|
+
userEvent.click(screen.getByText("Radio 3"));
|
|
129
|
+
expect(newValue).toEqual("3");
|
|
130
|
+
userEvent.click(screen.getByText("Radio 2"));
|
|
131
|
+
expect(newValue).toEqual("2");
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("calls the UUID generation function if no id prop value is passed", () => {
|
|
135
|
+
const generateUUIDSpy = jest.spyOn(generateUUID, "default");
|
|
136
|
+
expect(generateUUIDSpy).toHaveBeenCalledTimes(0);
|
|
137
|
+
render(
|
|
138
|
+
<RadioGroup labelText="Test Label" name="test6">
|
|
139
|
+
<Radio value="2" labelText="Radio 2" id="radio2" />
|
|
140
|
+
</RadioGroup>
|
|
141
|
+
);
|
|
142
|
+
expect(generateUUIDSpy).toHaveBeenCalledTimes(1);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("sets the 'disabled' attribute for all its Radio children", () => {
|
|
146
|
+
render(
|
|
147
|
+
<RadioGroup labelText="Test Label" name="test7" isDisabled>
|
|
148
|
+
<Radio value="2" labelText="Radio 2" />
|
|
149
|
+
<Radio value="3" labelText="Radio 3" />
|
|
150
|
+
<Radio value="4" labelText="Radio 4" />
|
|
151
|
+
</RadioGroup>
|
|
152
|
+
);
|
|
153
|
+
const radios = screen.getAllByRole("radio");
|
|
154
|
+
|
|
155
|
+
expect(radios).toHaveLength(3);
|
|
156
|
+
expect(radios[0]).toHaveAttribute("disabled");
|
|
157
|
+
expect(radios[1]).toHaveAttribute("disabled");
|
|
158
|
+
expect(radios[2]).toHaveAttribute("disabled");
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("sets the 'required' attribute for all its Radio children", () => {
|
|
162
|
+
render(
|
|
163
|
+
<RadioGroup labelText="Test Label" name="test8" isRequired>
|
|
164
|
+
<Radio value="2" labelText="Radio 2" />
|
|
165
|
+
<Radio value="3" labelText="Radio 3" />
|
|
166
|
+
<Radio value="4" labelText="Radio 4" />
|
|
167
|
+
</RadioGroup>
|
|
168
|
+
);
|
|
169
|
+
const radios = screen.getAllByRole("radio");
|
|
170
|
+
|
|
171
|
+
expect(radios).toHaveLength(3);
|
|
172
|
+
expect(radios[0]).toHaveAttribute("required");
|
|
173
|
+
expect(radios[0]).toHaveAttribute("aria-required");
|
|
174
|
+
expect(radios[1]).toHaveAttribute("required");
|
|
175
|
+
expect(radios[1]).toHaveAttribute("aria-required");
|
|
176
|
+
expect(radios[2]).toHaveAttribute("required");
|
|
177
|
+
expect(radios[2]).toHaveAttribute("aria-required");
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it("sets the error state for all its Radio children", () => {
|
|
181
|
+
render(
|
|
182
|
+
<RadioGroup labelText="Test Label" name="test9" isInvalid>
|
|
183
|
+
<Radio value="2" labelText="Radio 2" />
|
|
184
|
+
<Radio value="3" labelText="Radio 3" />
|
|
185
|
+
<Radio value="4" labelText="Radio 4" />
|
|
186
|
+
</RadioGroup>
|
|
187
|
+
);
|
|
188
|
+
const radios = screen.getAllByRole("radio");
|
|
189
|
+
|
|
190
|
+
expect(radios).toHaveLength(3);
|
|
191
|
+
expect(radios[0]).toHaveAttribute("aria-invalid");
|
|
192
|
+
expect(radios[1]).toHaveAttribute("aria-invalid");
|
|
193
|
+
expect(radios[2]).toHaveAttribute("aria-invalid");
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("renders the UI snapshot correctly", () => {
|
|
197
|
+
const column = renderer
|
|
198
|
+
.create(
|
|
199
|
+
<RadioGroup labelText="column" name="column" id="column">
|
|
200
|
+
<Radio value="2" labelText="Radio 2" id="radio-2" />
|
|
201
|
+
<Radio value="3" labelText="Radio 3" id="radio-3" />
|
|
202
|
+
</RadioGroup>
|
|
203
|
+
)
|
|
204
|
+
.toJSON();
|
|
205
|
+
const row = renderer
|
|
206
|
+
.create(
|
|
207
|
+
<RadioGroup
|
|
208
|
+
labelText="row"
|
|
209
|
+
name="row"
|
|
210
|
+
id="row"
|
|
211
|
+
layout={RadioGroupLayoutTypes.Row}
|
|
212
|
+
>
|
|
213
|
+
<Radio value="2" labelText="Radio 2" id="radio-2" />
|
|
214
|
+
<Radio value="3" labelText="Radio 3" id="radio-3" />
|
|
215
|
+
</RadioGroup>
|
|
216
|
+
)
|
|
217
|
+
.toJSON();
|
|
218
|
+
const noLabel = renderer
|
|
219
|
+
.create(
|
|
220
|
+
<RadioGroup
|
|
221
|
+
labelText="no label"
|
|
222
|
+
name="noLabel"
|
|
223
|
+
id="noLabel"
|
|
224
|
+
showLabel={false}
|
|
225
|
+
>
|
|
226
|
+
<Radio value="2" labelText="Radio 2" id="radio-2" />
|
|
227
|
+
<Radio value="3" labelText="Radio 3" id="radio-3" />
|
|
228
|
+
</RadioGroup>
|
|
229
|
+
)
|
|
230
|
+
.toJSON();
|
|
231
|
+
const helperText = renderer
|
|
232
|
+
.create(
|
|
233
|
+
<RadioGroup
|
|
234
|
+
labelText="helperText"
|
|
235
|
+
name="helperText"
|
|
236
|
+
id="helperText"
|
|
237
|
+
helperText="helper text"
|
|
238
|
+
>
|
|
239
|
+
<Radio value="2" labelText="Radio 2" id="radio-2" />
|
|
240
|
+
<Radio value="3" labelText="Radio 3" id="radio-3" />
|
|
241
|
+
</RadioGroup>
|
|
242
|
+
)
|
|
243
|
+
.toJSON();
|
|
244
|
+
const invalidText = renderer
|
|
245
|
+
.create(
|
|
246
|
+
<RadioGroup
|
|
247
|
+
labelText="invalidText"
|
|
248
|
+
name="invalidText"
|
|
249
|
+
id="invalidText"
|
|
250
|
+
invalidText="error text"
|
|
251
|
+
>
|
|
252
|
+
<Radio value="2" labelText="Radio 2" id="radio-2" />
|
|
253
|
+
<Radio value="3" labelText="Radio 3" id="radio-3" />
|
|
254
|
+
</RadioGroup>
|
|
255
|
+
)
|
|
256
|
+
.toJSON();
|
|
257
|
+
const noOptReqLabel = renderer
|
|
258
|
+
.create(
|
|
259
|
+
<RadioGroup
|
|
260
|
+
labelText="no optional or required label"
|
|
261
|
+
name="optReq"
|
|
262
|
+
id="optReq"
|
|
263
|
+
optReqFlag={false}
|
|
264
|
+
>
|
|
265
|
+
<Radio value="2" labelText="Radio 2" id="radio-2" />
|
|
266
|
+
<Radio value="3" labelText="Radio 3" id="radio-3" />
|
|
267
|
+
</RadioGroup>
|
|
268
|
+
)
|
|
269
|
+
.toJSON();
|
|
270
|
+
const isRequired = renderer
|
|
271
|
+
.create(
|
|
272
|
+
<RadioGroup
|
|
273
|
+
labelText="required"
|
|
274
|
+
name="required"
|
|
275
|
+
id="required"
|
|
276
|
+
isRequired
|
|
277
|
+
>
|
|
278
|
+
<Radio value="2" labelText="Radio 2" id="radio-2" />
|
|
279
|
+
<Radio value="3" labelText="Radio 3" id="radio-3" />
|
|
280
|
+
</RadioGroup>
|
|
281
|
+
)
|
|
282
|
+
.toJSON();
|
|
283
|
+
const isInvalid = renderer
|
|
284
|
+
.create(
|
|
285
|
+
<RadioGroup labelText="invalid" name="invalid" id="invalid" isInvalid>
|
|
286
|
+
<Radio value="2" labelText="Radio 2" id="radio-2" />
|
|
287
|
+
<Radio value="3" labelText="Radio 3" id="radio-3" />
|
|
288
|
+
</RadioGroup>
|
|
289
|
+
)
|
|
290
|
+
.toJSON();
|
|
291
|
+
const isDisabled = renderer
|
|
292
|
+
.create(
|
|
293
|
+
<RadioGroup
|
|
294
|
+
labelText="disabled"
|
|
295
|
+
name="disabled"
|
|
296
|
+
id="disabled"
|
|
297
|
+
isDisabled
|
|
298
|
+
>
|
|
299
|
+
<Radio value="2" labelText="Radio 2" id="radio-2" />
|
|
300
|
+
<Radio value="3" labelText="Radio 3" id="radio-3" />
|
|
301
|
+
</RadioGroup>
|
|
302
|
+
)
|
|
303
|
+
.toJSON();
|
|
304
|
+
|
|
305
|
+
expect(column).toMatchSnapshot();
|
|
306
|
+
expect(row).toMatchSnapshot();
|
|
307
|
+
expect(noLabel).toMatchSnapshot();
|
|
308
|
+
expect(helperText).toMatchSnapshot();
|
|
309
|
+
expect(invalidText).toMatchSnapshot();
|
|
310
|
+
expect(noOptReqLabel).toMatchSnapshot();
|
|
311
|
+
expect(isRequired).toMatchSnapshot();
|
|
312
|
+
expect(isInvalid).toMatchSnapshot();
|
|
313
|
+
expect(isDisabled).toMatchSnapshot();
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
it("should throw warning when a non-Radio component is used as a child", () => {
|
|
317
|
+
const warn = jest.spyOn(console, "warn");
|
|
318
|
+
render(
|
|
319
|
+
<RadioGroup labelText="wrong child!" name="wrong" id="wrong-child">
|
|
320
|
+
<p>This is wrong!</p>
|
|
321
|
+
</RadioGroup>
|
|
322
|
+
);
|
|
323
|
+
expect(warn).toHaveBeenCalledWith(
|
|
324
|
+
"Only `Radio` components are allowed inside the `RadioGroup` component."
|
|
325
|
+
);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
Box,
|
|
4
|
+
Stack,
|
|
5
|
+
useMultiStyleConfig,
|
|
6
|
+
useRadioGroup,
|
|
7
|
+
} from "@chakra-ui/react";
|
|
8
|
+
|
|
9
|
+
import HelperErrorText from "../HelperErrorText/HelperErrorText";
|
|
10
|
+
import generateUUID from "../../helpers/generateUUID";
|
|
11
|
+
import { spacing } from "../../theme/foundations/spacing";
|
|
12
|
+
import { RadioGroupLayoutTypes } from "./RadioGroupLayoutTypes";
|
|
13
|
+
import Radio from "../Radio/Radio";
|
|
14
|
+
|
|
15
|
+
export interface RadioGroupProps {
|
|
16
|
+
/** Any child node passed to the component. */
|
|
17
|
+
children: React.ReactNode;
|
|
18
|
+
/** Additional class name. */
|
|
19
|
+
className?: string;
|
|
20
|
+
/** Populates the initial value of the input */
|
|
21
|
+
defaultValue?: string;
|
|
22
|
+
/** Optional string to populate the HelperErrorText for error state */
|
|
23
|
+
invalidText?: string;
|
|
24
|
+
/** Optional string to populate the HelperErrorText for standard state */
|
|
25
|
+
helperText?: string;
|
|
26
|
+
/** ID that other components can cross reference for accessibility purposes */
|
|
27
|
+
id?: string;
|
|
28
|
+
/** Adds the 'disabled' prop to the input when true. */
|
|
29
|
+
isDisabled?: boolean;
|
|
30
|
+
/** Adds the 'aria-invalid' attribute to the input and
|
|
31
|
+
* sets the error state when true. */
|
|
32
|
+
isInvalid?: boolean;
|
|
33
|
+
/** Adds the 'required' attribute to the input when true. */
|
|
34
|
+
isRequired?: boolean;
|
|
35
|
+
/** The radio group label displayed in a `legend` element if `showlabel` is
|
|
36
|
+
* true, or an "aria-label" if `showLabel` is false. */
|
|
37
|
+
labelText: string;
|
|
38
|
+
/** Renders the Radio buttons in a row or column (default). */
|
|
39
|
+
layout?: RadioGroupLayoutTypes;
|
|
40
|
+
/** The `name` prop indicates the form group for all the Radio children. */
|
|
41
|
+
name: string;
|
|
42
|
+
/** The action to perform on the `<input>`'s onChange function */
|
|
43
|
+
onChange?: (value: string) => void;
|
|
44
|
+
/** Whether or not to display "Required"/"Optional" in the label text. */
|
|
45
|
+
optReqFlag?: boolean;
|
|
46
|
+
/** Offers the ability to show the group's legend onscreen or hide it. Refer
|
|
47
|
+
* to the `labelText` property for more information. */
|
|
48
|
+
showLabel?: boolean;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const noop = () => {};
|
|
52
|
+
export const onChangeDefault = () => {
|
|
53
|
+
return;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const RadioGroup = React.forwardRef<HTMLInputElement, RadioGroupProps>(
|
|
57
|
+
(props, ref?) => {
|
|
58
|
+
const {
|
|
59
|
+
children,
|
|
60
|
+
className = "",
|
|
61
|
+
defaultValue,
|
|
62
|
+
invalidText,
|
|
63
|
+
helperText,
|
|
64
|
+
id = generateUUID(),
|
|
65
|
+
isDisabled = false,
|
|
66
|
+
isInvalid = false,
|
|
67
|
+
isRequired = false,
|
|
68
|
+
labelText,
|
|
69
|
+
layout = RadioGroupLayoutTypes.Column,
|
|
70
|
+
name,
|
|
71
|
+
onChange = onChangeDefault,
|
|
72
|
+
optReqFlag = true,
|
|
73
|
+
showLabel = true,
|
|
74
|
+
} = props;
|
|
75
|
+
const footnote = isInvalid ? invalidText : helperText;
|
|
76
|
+
const spacingProp =
|
|
77
|
+
layout === RadioGroupLayoutTypes.Column ? spacing.s : spacing.l;
|
|
78
|
+
const newChildren = [];
|
|
79
|
+
|
|
80
|
+
// Use Chakra's RadioGroup hook to set and get the proper props
|
|
81
|
+
// or the custom components.
|
|
82
|
+
const { getRootProps, getRadioProps } = useRadioGroup({
|
|
83
|
+
name,
|
|
84
|
+
defaultValue,
|
|
85
|
+
onChange,
|
|
86
|
+
});
|
|
87
|
+
const radioGroupProps = getRootProps();
|
|
88
|
+
|
|
89
|
+
// Go through the Radio children and update them as needed.
|
|
90
|
+
React.Children.map(children, (child: React.ReactElement, i) => {
|
|
91
|
+
if (child.type !== Radio) {
|
|
92
|
+
// Special case for Storybook MDX documentation.
|
|
93
|
+
if (child.props.mdxType && child.props.mdxType === "Radio") {
|
|
94
|
+
noop();
|
|
95
|
+
} else {
|
|
96
|
+
console.warn(
|
|
97
|
+
"Only `Radio` components are allowed inside the `RadioGroup` component."
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const chakraRadioProps = getRadioProps({
|
|
103
|
+
value: child.props.value,
|
|
104
|
+
} as any);
|
|
105
|
+
|
|
106
|
+
if (child !== undefined && child !== null) {
|
|
107
|
+
const newProps = { key: i, isDisabled, isInvalid, isRequired };
|
|
108
|
+
if (child.props.value === defaultValue) {
|
|
109
|
+
newProps["checked"] = true;
|
|
110
|
+
}
|
|
111
|
+
newChildren.push(
|
|
112
|
+
React.cloneElement(child, { ...newProps, ...chakraRadioProps })
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Get the Chakra-based styles for all the custom elements in this component.
|
|
118
|
+
const styles = useMultiStyleConfig("CustomRadioGroup", {});
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<Box
|
|
122
|
+
as="fieldset"
|
|
123
|
+
id={`radio-group-${id}`}
|
|
124
|
+
className={className}
|
|
125
|
+
__css={styles}
|
|
126
|
+
>
|
|
127
|
+
<legend className={showLabel ? "" : "sr-only"}>
|
|
128
|
+
<span>{labelText}</span>
|
|
129
|
+
{optReqFlag && (
|
|
130
|
+
<Box as="span" __css={styles.required}>
|
|
131
|
+
{isRequired ? "Required" : "Optional"}
|
|
132
|
+
</Box>
|
|
133
|
+
)}
|
|
134
|
+
</legend>
|
|
135
|
+
<Stack
|
|
136
|
+
direction={[layout]}
|
|
137
|
+
spacing={spacingProp}
|
|
138
|
+
ref={ref}
|
|
139
|
+
aria-label={!showLabel ? labelText : null}
|
|
140
|
+
{...radioGroupProps}
|
|
141
|
+
>
|
|
142
|
+
{newChildren}
|
|
143
|
+
</Stack>
|
|
144
|
+
{footnote && (
|
|
145
|
+
<Box __css={styles.helper}>
|
|
146
|
+
<HelperErrorText isError={isInvalid}>{footnote}</HelperErrorText>
|
|
147
|
+
</Box>
|
|
148
|
+
)}
|
|
149
|
+
</Box>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
export default RadioGroup;
|