@indico-data/design-system 1.0.48 → 1.0.49

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/lib/components/Accordion/Accordion.styles.d.ts +1 -275
  2. package/lib/components/Icon/Icon.stories.d.ts +2 -2
  3. package/lib/components/Icon/storyHelpers.d.ts +3 -813
  4. package/lib/components/ListTable/Header/Header.styles.d.ts +1 -272
  5. package/lib/components/ListTable/ListTable.styles.d.ts +1 -272
  6. package/lib/components/LoadingAwareContainer/LoadingAwareContainer.styles.d.ts +2 -543
  7. package/lib/components/Navigation/Drawer/DrawerLinkList.styles.d.ts +1 -272
  8. package/lib/components/Pagination/Pagination.styles.d.ts +1 -272
  9. package/lib/components/Wizard/Wizard.styles.d.ts +3 -814
  10. package/lib/components/basic-section/Section/Section.styles.d.ts +1 -272
  11. package/lib/components/basic-section/SectionBlock/SectionBlock.styles.d.ts +1 -272
  12. package/lib/components/basic-section/SectionBody/SectionBody.styles.d.ts +1 -272
  13. package/lib/components/basic-section/SectionHeader/SectionHeader.styles.d.ts +1 -272
  14. package/lib/components/basic-section/SectionTable/SectionTable.styles.d.ts +1 -272
  15. package/lib/components/buttons/Button/Button.styles.d.ts +1 -282
  16. package/lib/components/buttons/IconButton/IconButton.styles.d.ts +2 -567
  17. package/lib/components/dropdowns/BorderSelect/BorderSelect.styles.d.ts +2 -543
  18. package/lib/components/dropdowns/MultiCombobox/MultiCombobox.styles.d.ts +1 -84
  19. package/lib/components/dropdowns/Select/Select.styles.d.ts +1 -272
  20. package/lib/components/dropdowns/SingleCombobox/SingleCombobox.styles.d.ts +1 -84
  21. package/lib/components/index.d.ts +1 -1
  22. package/lib/components/inputs/EditableInput/EditableInput.styles.d.ts +1 -272
  23. package/lib/components/inputs/NumberInput/NumberInput.styles.d.ts +1 -272
  24. package/lib/components/inputs/RadioButtons/RadioButtons.d.ts +24 -0
  25. package/lib/components/inputs/RadioButtons/RadioButtons.stories.d.ts +15 -0
  26. package/lib/components/inputs/RadioButtons/RadioButtons.styles.d.ts +14 -0
  27. package/lib/components/inputs/RadioButtons/index.d.ts +1 -0
  28. package/lib/components/inputs/RadioGroup/RadioGroup.d.ts +27 -0
  29. package/lib/components/inputs/RadioGroup/RadioGroup.stories.d.ts +16 -0
  30. package/lib/components/inputs/RadioGroup/RadioGroup.styles.d.ts +2 -0
  31. package/lib/components/inputs/RadioGroup/index.d.ts +1 -0
  32. package/lib/components/inputs/SearchInput/SearchInput.styles.d.ts +1 -272
  33. package/lib/components/inputs/TextInput/TextInput.styles.d.ts +2 -543
  34. package/lib/components/inputs/index.d.ts +2 -0
  35. package/lib/components/loading-indicators/BarSpinner/BarSpinner.styles.d.ts +1 -272
  36. package/lib/components/loading-indicators/LoadingList/LoadingList.styles.d.ts +1 -272
  37. package/lib/components/loading-indicators/PercentageRing/PercentageRing.styles.d.ts +1 -272
  38. package/lib/components/modals/ConfirmModal/ConfirmModal.styles.d.ts +1 -272
  39. package/lib/components/modals/ModalBase/ModalBase.styles.d.ts +1 -3
  40. package/lib/components/user-feedback/Shrug/Shrug.styles.d.ts +1 -272
  41. package/lib/index.d.ts +191 -953
  42. package/lib/index.esm.js +1624 -186
  43. package/lib/index.esm.js.map +1 -1
  44. package/lib/index.js +1626 -184
  45. package/lib/index.js.map +1 -1
  46. package/lib/tokens/colors.d.ts +2 -0
  47. package/package.json +45 -42
  48. package/src/components/Wizard/Wizard.tsx +0 -1
  49. package/src/components/WizardWithSidebar/WizardWithSidebar.tsx +1 -0
  50. package/src/components/index.ts +10 -1
  51. package/src/components/inputs/RadioButtons/RadioButtons.stories.tsx +84 -0
  52. package/src/components/inputs/RadioButtons/RadioButtons.styles.ts +82 -0
  53. package/src/components/inputs/RadioButtons/RadioButtons.tsx +61 -0
  54. package/src/components/inputs/RadioButtons/index.tsx +1 -0
  55. package/src/components/inputs/RadioGroup/RadioGroup.stories.tsx +66 -0
  56. package/src/components/inputs/RadioGroup/RadioGroup.styles.ts +11 -0
  57. package/src/components/inputs/RadioGroup/RadioGroup.tsx +120 -0
  58. package/src/components/inputs/RadioGroup/index.ts +1 -0
  59. package/src/components/inputs/SearchInput/SearchInput.styles.ts +1 -1
  60. package/src/components/inputs/index.ts +2 -0
  61. package/src/components/loading-indicators/LoadingIndicator/LoadingIndicator.stories.tsx +0 -1
  62. package/src/index.ts +4 -0
  63. package/src/tokens/colors.ts +2 -0
  64. package/lib/components/Navigation/Drawer/constants.d.ts +0 -3
@@ -18,6 +18,7 @@ export declare const allColors: {
18
18
  readonly bouqet: "#a35c9a";
19
19
  readonly brick: "#c62828";
20
20
  readonly brightDusk: "#efebf7";
21
+ readonly britishShorthair: "#4b94eb";
21
22
  readonly brown: "#785349";
22
23
  readonly candyCorn: "#fcef4d";
23
24
  readonly carnation: "#ff8adf";
@@ -28,6 +29,7 @@ export declare const allColors: {
28
29
  readonly charcoal: "#474b4b";
29
30
  readonly chartreuse: "#34ff01";
30
31
  readonly clay: "#283243";
32
+ readonly clementine: "#F16E00";
31
33
  readonly cocoaBean: "#5c1200";
32
34
  readonly comet: "#5a6982";
33
35
  readonly cornflower: "#2060ff";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indico-data/design-system",
3
- "version": "1.0.48",
3
+ "version": "1.0.49",
4
4
  "description": "",
5
5
  "author": "",
6
6
  "main": "lib/index.js",
@@ -19,89 +19,92 @@
19
19
  "**/*": "prettier --write --ignore-unknown"
20
20
  },
21
21
  "dependencies": {
22
- "@fortawesome/fontawesome-svg-core": "^6.4.2",
23
- "@fortawesome/free-regular-svg-icons": "^6.4.2",
24
- "@fortawesome/free-solid-svg-icons": "^6.4.2",
22
+ "@fortawesome/fontawesome-svg-core": "^6.5.1",
23
+ "@fortawesome/free-regular-svg-icons": "^6.5.1",
24
+ "@fortawesome/free-solid-svg-icons": "^6.5.1",
25
25
  "@indico-data/utils": "^0.0.5",
26
+ "@react-aria/radio": "^3.10.0",
27
+ "@react-aria/visually-hidden": "^3.8.8",
26
28
  "@react-types/button": "^3.9.1",
27
29
  "@react-types/checkbox": "^3.6.0",
28
30
  "@react-types/radio": "^3.7.0",
29
- "classnames": "^2.3.2",
30
- "date-fns": "^2.30.0",
31
- "html-webpack-plugin": "^5.5.3",
31
+ "classnames": "^2.5.1",
32
+ "date-fns": "^3.3.1",
33
+ "html-webpack-plugin": "^5.6.0",
34
+ "react-aria-components": "^1.0.1",
32
35
  "react-modal": "^3.16.1",
36
+ "react-stately": "^3.29.1",
33
37
  "simple-zustand-devtools": "^1.1.0",
34
- "svgo": "^3.0.3",
38
+ "svgo": "^3.2.0",
35
39
  "tslib": "^2.6.2",
36
40
  "uuid": "^9.0.1",
37
- "webpack": "^5",
41
+ "webpack": "^5.89.0",
38
42
  "webpack-cli": "^5.1.4",
39
43
  "webpack-dev-server": "^4.15.1"
40
44
  },
41
45
  "devDependencies": {
42
- "@babel/core": "^7.23.3",
46
+ "@babel/core": "^7.23.7",
43
47
  "@babel/plugin-proposal-class-properties": "^7.18.6",
44
- "@babel/preset-env": "^7.23.3",
48
+ "@babel/preset-env": "^7.23.8",
45
49
  "@babel/preset-react": "^7.23.3",
46
50
  "@babel/preset-typescript": "^7.23.3",
47
- "@react-aria/button": "^3.9.0",
48
- "@react-aria/focus": "^3.15.0",
51
+ "@react-aria/button": "^3.9.1",
52
+ "@react-aria/focus": "^3.16.0",
49
53
  "@rollup/plugin-babel": "^6.0.4",
50
54
  "@rollup/plugin-commonjs": "^25.0.7",
51
55
  "@rollup/plugin-node-resolve": "^15.2.3",
52
56
  "@rollup/plugin-terser": "^0.4.4",
53
- "@rollup/plugin-typescript": "^11.1.5",
54
- "@storybook/addon-a11y": "^7.5.3",
55
- "@storybook/addon-docs": "^7.5.3",
56
- "@storybook/addon-essentials": "^7.5.3",
57
- "@storybook/addon-interactions": "^7.5.3",
58
- "@storybook/addon-links": "^7.5.3",
59
- "@storybook/addon-onboarding": "^1.0.8",
60
- "@storybook/addon-styling": "^2.0.2-next.4",
61
- "@storybook/addon-styling-webpack": "^0.0.5",
62
- "@storybook/addon-themes": "^7.5.3",
63
- "@storybook/blocks": "^7.5.3",
64
- "@storybook/react": "^7.5.3",
65
- "@storybook/react-webpack5": "^7.5.3",
66
- "@storybook/test": "^7.6.0-alpha.4",
57
+ "@rollup/plugin-typescript": "^11.1.6",
58
+ "@storybook/addon-a11y": "^7.6.10",
59
+ "@storybook/addon-docs": "^7.6.10",
60
+ "@storybook/addon-essentials": "^7.6.10",
61
+ "@storybook/addon-interactions": "^7.6.10",
62
+ "@storybook/addon-links": "^7.6.10",
63
+ "@storybook/addon-onboarding": "^1.0.10",
64
+ "@storybook/addon-styling": "^1.3.7",
65
+ "@storybook/addon-styling-webpack": "^0.0.6",
66
+ "@storybook/addon-themes": "^7.6.10",
67
+ "@storybook/blocks": "^7.6.10",
68
+ "@storybook/react": "^7.6.10",
69
+ "@storybook/react-webpack5": "^7.6.10",
70
+ "@storybook/test": "^7.6.10",
67
71
  "@storybook/test-runner": "^0.16.0",
68
72
  "@testing-library/dom": "^9.3.4",
69
73
  "@testing-library/jest-dom": "^6.2.1",
70
74
  "@testing-library/react": "^14.1.2",
71
75
  "@testing-library/user-event": "^14.5.2",
72
76
  "@types/jest": "^29.5.11",
73
- "@types/react": "^18",
74
- "@types/react-dom": "^18",
75
- "@types/react-modal": "^3",
76
- "@types/styled-components": "^5.1.30",
77
+ "@types/react": "^18.2.48",
78
+ "@types/react-dom": "^18.2.18",
79
+ "@types/react-modal": "^3.16.3",
80
+ "@types/styled-components": "^5.1.34",
77
81
  "@types/uuid": "^9.0.7",
78
- "@typescript-eslint/eslint-plugin": "^6.10.0",
79
- "@typescript-eslint/parser": "^6.10.0",
82
+ "@typescript-eslint/eslint-plugin": "^6.19.1",
83
+ "@typescript-eslint/parser": "^6.19.1",
80
84
  "babel-loader": "^9.1.3",
81
85
  "babel-plugin-styled-components": "^2.1.4",
82
86
  "babel-preset-react-app": "^10.0.1",
83
- "eslint": "^8.53.0",
87
+ "eslint": "^8.56.0",
84
88
  "eslint-plugin-react": "^7.33.2",
85
89
  "eslint-plugin-react-hooks": "^4.6.0",
86
90
  "jest": "^29.7.0",
87
91
  "jest-environment-jsdom": "^29.7.0",
88
92
  "lint-staged": "^15.2.0",
89
- "postcss": "^8.4.31",
90
- "prettier": "3.1.0",
93
+ "postcss": "^8.4.33",
94
+ "prettier": "3.2.4",
91
95
  "react": "^18.2.0",
92
96
  "react-dom": "^18.2.0",
93
- "react-router-dom": "^6.20.1",
97
+ "react-router-dom": "^6.21.3",
94
98
  "react-select": "^5.8.0",
95
- "rollup": "^4.6.1",
99
+ "rollup": "^4.9.6",
96
100
  "rollup-plugin-dts": "^6.1.0",
97
101
  "rollup-plugin-peer-deps-external": "^2.2.4",
98
102
  "rollup-plugin-postcss": "^4.0.2",
99
- "storybook": "^7.5.3",
100
- "styled-components": "^6.1.1",
101
- "ts-jest": "^29.1.2",
103
+ "storybook": "^7.6.10",
104
+ "styled-components": "^6.1.8",
102
105
  "ts-loader": "^9.5.1",
103
106
  "tsconfig-paths-webpack-plugin": "^4.1.0",
104
- "typescript": "^5.2.2"
107
+ "typescript": "^5.3.3"
105
108
  },
106
109
  "resolutions": {
107
110
  "jackspeak": "2.1.1"
@@ -122,7 +122,6 @@ export function Wizard(props: Props) {
122
122
 
123
123
  const handleNextPress = () => {
124
124
  const allowNext = onNextPress ? onNextPress() : true;
125
- debugger;
126
125
 
127
126
  if (!allowNext) {
128
127
  return;
@@ -255,6 +255,7 @@ export function WizardWithSidebar(props: Props) {
255
255
  open={openCancelConfirm}
256
256
  clickOutsideHandler={() => setOpenCancelConfirm(false)}
257
257
  responseHandler={handleCancelRequest}
258
+ width={430}
258
259
  />
259
260
  </StyledWizardWithSidebar>
260
261
  );
@@ -3,7 +3,16 @@ export { Section, SectionBlock, SectionBody, SectionHeader, SectionTable } from
3
3
  export { Button, IconButton } from './buttons';
4
4
  export { BorderSelect, MultiCombobox, Select, SingleCombobox } from './dropdowns';
5
5
  export { Icon, faIcons, indicons } from './Icon';
6
- export { EditableInput, NumberInput, SearchInput, TextInput } from './inputs';
6
+ export {
7
+ EditableInput,
8
+ NumberInput,
9
+ SearchInput,
10
+ TextInput,
11
+ Radio,
12
+ RadioGroup,
13
+ AbstractRadio,
14
+ AbstractRadioGroup,
15
+ } from './inputs';
7
16
  export {
8
17
  BarSpinner,
9
18
  CirclePulse,
@@ -0,0 +1,84 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import { Meta, StoryObj } from '@storybook/react';
4
+ import React, { useState } from 'react';
5
+
6
+ import { COLORS } from '@/tokens';
7
+ import { Radio, RadioGroup } from './RadioButtons';
8
+
9
+ const meta = {
10
+ component: RadioGroup,
11
+ title: 'inputs/RadioButtons',
12
+ args: {},
13
+ tags: ['autodocs'],
14
+ } satisfies Meta<typeof RadioGroup>;
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof RadioGroup>;
18
+
19
+ function StoryRender(props: any) {
20
+ const [value, setValue] = useState<string>('andy');
21
+ return (
22
+ <RadioGroup
23
+ {...props}
24
+ defaultValue="andy"
25
+ value={value}
26
+ onChange={(value: string) => setValue(value)}
27
+ >
28
+ <Radio value="andy">Andy</Radio>
29
+ <Radio value="jess">Jess</Radio>
30
+ <Radio value="mike">Mike</Radio>
31
+ </RadioGroup>
32
+ );
33
+ }
34
+
35
+ export const Normal: Story = {
36
+ args: {
37
+ label: 'Select a person:',
38
+ },
39
+ render: (args) => {
40
+ return <StoryRender {...args} />;
41
+ },
42
+ };
43
+
44
+ export const CustomColors: Story = {
45
+ args: {
46
+ label: 'Select a person:',
47
+ color: `${COLORS.red}`,
48
+ labelColor: `${COLORS.black}`,
49
+ hoverAndSelectedColor: `${COLORS.blueDarknut}`,
50
+ focusRingColor: `${COLORS.blueDarknut}`,
51
+ },
52
+ render: (args) => {
53
+ return <StoryRender {...args} />;
54
+ },
55
+ };
56
+
57
+ export const WithHiddenLabel: Story = {
58
+ args: {
59
+ ['aria-label']: 'Select a person:',
60
+ },
61
+ render: (args) => {
62
+ return <StoryRender {...args} />;
63
+ },
64
+ };
65
+
66
+ export const Horizontal: Story = {
67
+ args: {
68
+ label: 'Select a person:',
69
+ orientation: 'horizontal',
70
+ },
71
+ render: (args) => {
72
+ return <StoryRender {...args} />;
73
+ },
74
+ };
75
+
76
+ export const Disabled: Story = {
77
+ args: {
78
+ label: 'Select a person:',
79
+ isDisabled: true,
80
+ },
81
+ render: (args) => {
82
+ return <StoryRender {...args} />;
83
+ },
84
+ };
@@ -0,0 +1,82 @@
1
+ import styled from 'styled-components';
2
+
3
+ import { ANIMATION, COLORS, SPACING } from '@/tokens';
4
+ import { AbstractRadioGroup } from '../RadioGroup';
5
+
6
+ const radioSize = '20px';
7
+ const strokeWidth = 2;
8
+
9
+ export const StyledRadioGroup = styled(AbstractRadioGroup)<{
10
+ hideFocusRing: boolean;
11
+ color: string;
12
+ labelColor: string;
13
+ hoverAndSelectedColor: string;
14
+ focusRingColor: string;
15
+ }>`
16
+ color: ${(props) => props.color || 'currentColor'};
17
+
18
+ .groupLabel {
19
+ margin-bottom: ${SPACING.sm};
20
+ font-size: 16px;
21
+ color: ${(props) => props.labelColor || COLORS.lightGray};
22
+ }
23
+
24
+ // this is the Radio component; something gets cranky and styles end up
25
+ // not applied if we create a separate StyledComponent for Radio.
26
+ label {
27
+ display: flex;
28
+ align-items: center;
29
+
30
+ margin-bottom: ${SPACING.sm};
31
+
32
+ &.disabled {
33
+ cursor: not-allowed;
34
+ }
35
+
36
+ &:not(.disabled) {
37
+ cursor: pointer;
38
+
39
+ &.selected,
40
+ &:hover {
41
+ color: ${(props) => props.hoverAndSelectedColor || COLORS.white};
42
+ }
43
+ }
44
+
45
+ transition: color ${ANIMATION.duration} ${ANIMATION.timing};
46
+
47
+ svg {
48
+ width: ${radioSize};
49
+ height: ${radioSize};
50
+
51
+ margin-top: 1px;
52
+ margin-right: ${SPACING.sm};
53
+ }
54
+
55
+ .radioCircle {
56
+ stroke-width: ${strokeWidth};
57
+ }
58
+
59
+ .radioDot {
60
+ opacity: 0;
61
+ }
62
+
63
+ .focusRing {
64
+ opacity: 0;
65
+
66
+ stroke: ${(props) => props.focusRingColor || COLORS.curiousBlue};
67
+ stroke-width: ${strokeWidth};
68
+ }
69
+
70
+ &.selected {
71
+ .radioDot {
72
+ opacity: 1;
73
+ }
74
+ }
75
+
76
+ &.focused {
77
+ .focusRing {
78
+ opacity: ${(props) => (props.hideFocusRing ? 0 : 1)};
79
+ }
80
+ }
81
+ }
82
+ `;
@@ -0,0 +1,61 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+ import { AriaRadioProps, RadioGroupProps } from '@react-types/radio';
5
+
6
+ import { AbstractRadio } from '@/components';
7
+ import { PermafrostComponent } from '@/types';
8
+ import { StyledRadioGroup } from './RadioButtons.styles';
9
+
10
+ type Props = {
11
+ ['aria-label']: string;
12
+ children?: React.ReactNode;
13
+ hideFocusRing: boolean;
14
+ color: string;
15
+ labelColor: string;
16
+ hoverAndSelectedColor: string;
17
+ focusRingColor: string;
18
+ } & RadioGroupProps &
19
+ PermafrostComponent;
20
+
21
+ /**
22
+ * Renders a group of radio buttons.
23
+ *
24
+ * A group label must be included: either pass a string or markup into the
25
+ * `label` prop, or include an `aria-label` or `aria-labelledby` attribute.
26
+ */
27
+ export function RadioGroup({ children, ...props }: Props) {
28
+ const { color, hideFocusRing, labelColor, hoverAndSelectedColor, focusRingColor } = props;
29
+ return (
30
+ <StyledRadioGroup
31
+ {...props}
32
+ hideFocusRing
33
+ data-cy={props['data-cy']}
34
+ color={color}
35
+ labelColor={labelColor}
36
+ hoverAndSelectedColor={hoverAndSelectedColor}
37
+ focusRingColor={focusRingColor}
38
+ >
39
+ {children}
40
+ </StyledRadioGroup>
41
+ );
42
+ }
43
+
44
+ /**
45
+ * A single radio button and its label.
46
+ */
47
+ export function Radio({ children, ...props }: AriaRadioProps) {
48
+ return (
49
+ <AbstractRadio {...props}>
50
+ <svg viewBox="0 0 20 20" aria-hidden="true" focusable="false" overflow="visible">
51
+ <circle cx={10} cy={10} r={9} fill="none" stroke="currentColor" className="radioCircle" />
52
+
53
+ <circle cx={10} cy={10} r={5} fill="currentColor" stroke="none" className="radioDot" />
54
+
55
+ <circle cx={10} cy={10} r={12} fill="none" className="focusRing" />
56
+ </svg>
57
+
58
+ {children}
59
+ </AbstractRadio>
60
+ );
61
+ }
@@ -0,0 +1 @@
1
+ export { Radio, RadioGroup } from './RadioButtons';
@@ -0,0 +1,66 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React from 'react';
4
+ import { Meta, StoryObj } from '@storybook/react';
5
+
6
+ import { Radio, RadioGroup } from './RadioGroup';
7
+
8
+ const meta = {
9
+ component: RadioGroup,
10
+ title: 'inputs/RadioGroup',
11
+ args: {
12
+ value: 'andy',
13
+ },
14
+ tags: ['autodocs'],
15
+ } satisfies Meta<typeof RadioGroup>;
16
+
17
+ export default meta;
18
+ type Story = StoryObj<typeof RadioGroup>;
19
+
20
+ function StoryRender(props: any) {
21
+ return (
22
+ <RadioGroup {...props} defaultValue="andy">
23
+ <Radio value="andy">Andy</Radio>
24
+ <Radio value="jess">Jess</Radio>
25
+ <Radio value="mike">Mike</Radio>
26
+ </RadioGroup>
27
+ );
28
+ }
29
+
30
+ export const Normal: Story = {
31
+ args: {
32
+ label: 'Select a person:',
33
+ },
34
+ render: (args) => {
35
+ return <StoryRender {...args} />;
36
+ },
37
+ };
38
+
39
+ export const WithHiddenLabel: Story = {
40
+ args: {
41
+ ['aria-label']: 'Select a person:',
42
+ },
43
+ render: (args) => {
44
+ return <StoryRender {...args} />;
45
+ },
46
+ };
47
+
48
+ export const Horizontal: Story = {
49
+ args: {
50
+ label: 'Select a person:',
51
+ orientation: 'horizontal',
52
+ },
53
+ render: (args) => {
54
+ return <StoryRender {...args} />;
55
+ },
56
+ };
57
+
58
+ export const Disabled: Story = {
59
+ args: {
60
+ label: 'Select a person:',
61
+ isDisabled: true,
62
+ },
63
+ render: (args) => {
64
+ return <StoryRender {...args} />;
65
+ },
66
+ };
@@ -0,0 +1,11 @@
1
+ import styled from 'styled-components';
2
+
3
+ export const StyledRadioGroup = styled.div`
4
+ &.horizontal {
5
+ display: flex;
6
+
7
+ > * {
8
+ margin-right: 10px;
9
+ }
10
+ }
11
+ `;
@@ -0,0 +1,120 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React, { createContext, useContext, useRef, useState } from 'react';
4
+ import classNames from 'classnames';
5
+ import { AriaRadioGroupProps, AriaRadioProps } from '@react-types/radio';
6
+ import { useRadio, useRadioGroup } from '@react-aria/radio';
7
+ import { useFocusRing } from '@react-aria/focus';
8
+ import { useVisuallyHidden } from '@react-aria/visually-hidden';
9
+ import { RadioGroupState, useRadioGroupState } from 'react-stately';
10
+
11
+ import { PermafrostComponent } from '@/types';
12
+ import { StyledRadioGroup } from './RadioGroup.styles';
13
+
14
+ export type RadioGroupProps = PermafrostComponent & {
15
+ value?: string;
16
+ onChange?: (value: string) => void;
17
+ children: React.ReactNode;
18
+ className?: string;
19
+ } & AriaRadioGroupProps;
20
+
21
+ export const RadioContext = createContext({} as RadioGroupState);
22
+
23
+ /**
24
+ * Renders a group of radio buttons with no styling. This component is not
25
+ * designed to be user-facing, and should only be used to provide functionality.
26
+ *
27
+ * A group label must be included: either pass a string or markup into the
28
+ * `label` prop, or include an `aria-label` or `aria-labelledby` attribute.
29
+ */
30
+ export function RadioGroup(props: RadioGroupProps) {
31
+ const {
32
+ children,
33
+ className,
34
+ value,
35
+ id,
36
+ isDisabled,
37
+ isReadOnly,
38
+ label,
39
+ name,
40
+ onChange,
41
+ orientation,
42
+ defaultValue,
43
+ } = props;
44
+
45
+ const [lastFocusedValue, setLastFocusedValue] = useState<string | null>(null);
46
+
47
+ const radioGroupState = {
48
+ isDisabled: isDisabled || false,
49
+ isReadOnly: isReadOnly || false,
50
+ lastFocusedValue,
51
+ name: name || '',
52
+ selectedValue: value,
53
+ setLastFocusedValue,
54
+ setSelectedValue: onChange,
55
+ defaultValue,
56
+ };
57
+
58
+ const state = useRadioGroupState(radioGroupState);
59
+ const { radioGroupProps, labelProps } = useRadioGroup(props, state);
60
+
61
+ return (
62
+ <StyledRadioGroup
63
+ {...radioGroupProps}
64
+ className={classNames(className, { horizontal: orientation === 'horizontal' })}
65
+ data-cy={props['data-cy']}
66
+ id={id}
67
+ >
68
+ {label && (
69
+ <div className="groupLabel" {...labelProps}>
70
+ {label}
71
+ </div>
72
+ )}
73
+
74
+ <RadioContext.Provider value={state}>{children}</RadioContext.Provider>
75
+ </StyledRadioGroup>
76
+ );
77
+ }
78
+
79
+ /**
80
+ * A single radio button and its label; no styling is applied, and the native
81
+ * radio button is visually hidden.
82
+ */
83
+ export function Radio(
84
+ props: AriaRadioProps & {
85
+ className?: string;
86
+ isVisuallySelected?: (selectedValue: string) => void;
87
+ },
88
+ ) {
89
+ const { children, className, isDisabled, isVisuallySelected } = props;
90
+ const state = useContext(RadioContext);
91
+ const inputRef = useRef<HTMLInputElement>(null);
92
+
93
+ const { visuallyHiddenProps } = useVisuallyHidden();
94
+
95
+ const { inputProps } = useRadio(props, state, inputRef);
96
+ const { isFocusVisible, focusProps } = useFocusRing();
97
+
98
+ let isSelected;
99
+
100
+ if (isVisuallySelected) {
101
+ isSelected = isVisuallySelected(state.selectedValue as string);
102
+ } else {
103
+ // @ts-ignore
104
+ isSelected = state.selectedValue === props.value || state?.defaultValue === props.value;
105
+ }
106
+
107
+ return (
108
+ <label
109
+ className={classNames(className, {
110
+ disabled: isDisabled || state.isDisabled,
111
+ selected: isSelected,
112
+ focused: isFocusVisible,
113
+ })}
114
+ >
115
+ <input {...inputProps} {...visuallyHiddenProps} {...focusProps} ref={inputRef} />
116
+
117
+ {children}
118
+ </label>
119
+ );
120
+ }
@@ -0,0 +1 @@
1
+ export { Radio as AbstractRadio, RadioGroup as AbstractRadioGroup } from './RadioGroup';
@@ -1,4 +1,4 @@
1
- import styled, { css } from 'styled-components';
1
+ import styled from 'styled-components';
2
2
 
3
3
  import { TYPOGRAPHY } from '@/tokens';
4
4
 
@@ -2,3 +2,5 @@ export { EditableInput } from './EditableInput';
2
2
  export { NumberInput } from './NumberInput';
3
3
  export { SearchInput } from './SearchInput';
4
4
  export { TextInput } from './TextInput';
5
+ export { Radio, RadioGroup } from './RadioButtons';
6
+ export { AbstractRadio, AbstractRadioGroup } from './RadioGroup';
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import type { Meta, StoryObj } from '@storybook/react';
3
2
 
4
3
  import { LoadingIndicator } from './LoadingIndicator';
package/src/index.ts CHANGED
@@ -16,6 +16,8 @@ export {
16
16
  } from './tokens';
17
17
 
18
18
  export {
19
+ AbstractRadio,
20
+ AbstractRadioGroup,
19
21
  Accordion,
20
22
  BarSpinner,
21
23
  BorderSelect,
@@ -35,6 +37,8 @@ export {
35
37
  NumberInput,
36
38
  Pagination,
37
39
  PercentageRing,
40
+ Radio,
41
+ RadioGroup,
38
42
  RandomLoadingMessage,
39
43
  SearchInput,
40
44
  Section,