@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.
- package/lib/components/Accordion/Accordion.styles.d.ts +1 -275
- package/lib/components/Icon/Icon.stories.d.ts +2 -2
- package/lib/components/Icon/storyHelpers.d.ts +3 -813
- package/lib/components/ListTable/Header/Header.styles.d.ts +1 -272
- package/lib/components/ListTable/ListTable.styles.d.ts +1 -272
- package/lib/components/LoadingAwareContainer/LoadingAwareContainer.styles.d.ts +2 -543
- package/lib/components/Navigation/Drawer/DrawerLinkList.styles.d.ts +1 -272
- package/lib/components/Pagination/Pagination.styles.d.ts +1 -272
- package/lib/components/Wizard/Wizard.styles.d.ts +3 -814
- package/lib/components/basic-section/Section/Section.styles.d.ts +1 -272
- package/lib/components/basic-section/SectionBlock/SectionBlock.styles.d.ts +1 -272
- package/lib/components/basic-section/SectionBody/SectionBody.styles.d.ts +1 -272
- package/lib/components/basic-section/SectionHeader/SectionHeader.styles.d.ts +1 -272
- package/lib/components/basic-section/SectionTable/SectionTable.styles.d.ts +1 -272
- package/lib/components/buttons/Button/Button.styles.d.ts +1 -282
- package/lib/components/buttons/IconButton/IconButton.styles.d.ts +2 -567
- package/lib/components/dropdowns/BorderSelect/BorderSelect.styles.d.ts +2 -543
- package/lib/components/dropdowns/MultiCombobox/MultiCombobox.styles.d.ts +1 -84
- package/lib/components/dropdowns/Select/Select.styles.d.ts +1 -272
- package/lib/components/dropdowns/SingleCombobox/SingleCombobox.styles.d.ts +1 -84
- package/lib/components/index.d.ts +1 -1
- package/lib/components/inputs/EditableInput/EditableInput.styles.d.ts +1 -272
- package/lib/components/inputs/NumberInput/NumberInput.styles.d.ts +1 -272
- package/lib/components/inputs/RadioButtons/RadioButtons.d.ts +24 -0
- package/lib/components/inputs/RadioButtons/RadioButtons.stories.d.ts +15 -0
- package/lib/components/inputs/RadioButtons/RadioButtons.styles.d.ts +14 -0
- package/lib/components/inputs/RadioButtons/index.d.ts +1 -0
- package/lib/components/inputs/RadioGroup/RadioGroup.d.ts +27 -0
- package/lib/components/inputs/RadioGroup/RadioGroup.stories.d.ts +16 -0
- package/lib/components/inputs/RadioGroup/RadioGroup.styles.d.ts +2 -0
- package/lib/components/inputs/RadioGroup/index.d.ts +1 -0
- package/lib/components/inputs/SearchInput/SearchInput.styles.d.ts +1 -272
- package/lib/components/inputs/TextInput/TextInput.styles.d.ts +2 -543
- package/lib/components/inputs/index.d.ts +2 -0
- package/lib/components/loading-indicators/BarSpinner/BarSpinner.styles.d.ts +1 -272
- package/lib/components/loading-indicators/LoadingList/LoadingList.styles.d.ts +1 -272
- package/lib/components/loading-indicators/PercentageRing/PercentageRing.styles.d.ts +1 -272
- package/lib/components/modals/ConfirmModal/ConfirmModal.styles.d.ts +1 -272
- package/lib/components/modals/ModalBase/ModalBase.styles.d.ts +1 -3
- package/lib/components/user-feedback/Shrug/Shrug.styles.d.ts +1 -272
- package/lib/index.d.ts +191 -953
- package/lib/index.esm.js +1624 -186
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +1626 -184
- package/lib/index.js.map +1 -1
- package/lib/tokens/colors.d.ts +2 -0
- package/package.json +45 -42
- package/src/components/Wizard/Wizard.tsx +0 -1
- package/src/components/WizardWithSidebar/WizardWithSidebar.tsx +1 -0
- package/src/components/index.ts +10 -1
- package/src/components/inputs/RadioButtons/RadioButtons.stories.tsx +84 -0
- package/src/components/inputs/RadioButtons/RadioButtons.styles.ts +82 -0
- package/src/components/inputs/RadioButtons/RadioButtons.tsx +61 -0
- package/src/components/inputs/RadioButtons/index.tsx +1 -0
- package/src/components/inputs/RadioGroup/RadioGroup.stories.tsx +66 -0
- package/src/components/inputs/RadioGroup/RadioGroup.styles.ts +11 -0
- package/src/components/inputs/RadioGroup/RadioGroup.tsx +120 -0
- package/src/components/inputs/RadioGroup/index.ts +1 -0
- package/src/components/inputs/SearchInput/SearchInput.styles.ts +1 -1
- package/src/components/inputs/index.ts +2 -0
- package/src/components/loading-indicators/LoadingIndicator/LoadingIndicator.stories.tsx +0 -1
- package/src/index.ts +4 -0
- package/src/tokens/colors.ts +2 -0
- package/lib/components/Navigation/Drawer/constants.d.ts +0 -3
package/lib/tokens/colors.d.ts
CHANGED
|
@@ -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.
|
|
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.
|
|
23
|
-
"@fortawesome/free-regular-svg-icons": "^6.
|
|
24
|
-
"@fortawesome/free-solid-svg-icons": "^6.
|
|
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.
|
|
30
|
-
"date-fns": "^
|
|
31
|
-
"html-webpack-plugin": "^5.
|
|
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
|
|
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.
|
|
46
|
+
"@babel/core": "^7.23.7",
|
|
43
47
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
44
|
-
"@babel/preset-env": "^7.23.
|
|
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.
|
|
48
|
-
"@react-aria/focus": "^3.
|
|
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.
|
|
54
|
-
"@storybook/addon-a11y": "^7.
|
|
55
|
-
"@storybook/addon-docs": "^7.
|
|
56
|
-
"@storybook/addon-essentials": "^7.
|
|
57
|
-
"@storybook/addon-interactions": "^7.
|
|
58
|
-
"@storybook/addon-links": "^7.
|
|
59
|
-
"@storybook/addon-onboarding": "^1.0.
|
|
60
|
-
"@storybook/addon-styling": "^
|
|
61
|
-
"@storybook/addon-styling-webpack": "^0.0.
|
|
62
|
-
"@storybook/addon-themes": "^7.
|
|
63
|
-
"@storybook/blocks": "^7.
|
|
64
|
-
"@storybook/react": "^7.
|
|
65
|
-
"@storybook/react-webpack5": "^7.
|
|
66
|
-
"@storybook/test": "^7.6.
|
|
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.
|
|
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.
|
|
79
|
-
"@typescript-eslint/parser": "^6.
|
|
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.
|
|
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.
|
|
90
|
-
"prettier": "3.
|
|
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.
|
|
97
|
+
"react-router-dom": "^6.21.3",
|
|
94
98
|
"react-select": "^5.8.0",
|
|
95
|
-
"rollup": "^4.6
|
|
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.
|
|
100
|
-
"styled-components": "^6.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.
|
|
107
|
+
"typescript": "^5.3.3"
|
|
105
108
|
},
|
|
106
109
|
"resolutions": {
|
|
107
110
|
"jackspeak": "2.1.1"
|
package/src/components/index.ts
CHANGED
|
@@ -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 {
|
|
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,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';
|
|
@@ -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';
|
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,
|