@indico-data/design-system 1.0.47 → 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 (182) hide show
  1. package/README.md +5 -0
  2. package/jest.config.js +15 -0
  3. package/lib/components/Accordion/Accordion.d.ts +1 -1
  4. package/lib/components/Accordion/Accordion.stories.d.ts +2 -2
  5. package/lib/components/Accordion/Accordion.styles.d.ts +1 -275
  6. package/lib/components/Icon/Icon.stories.d.ts +3 -4
  7. package/lib/components/Icon/indicons.d.ts +143 -125
  8. package/lib/components/Icon/storyHelpers.d.ts +3 -813
  9. package/lib/components/ListTable/Header/Header.d.ts +1 -1
  10. package/lib/components/ListTable/Header/Header.styles.d.ts +1 -272
  11. package/lib/components/ListTable/ListTable.d.ts +1 -1
  12. package/lib/components/ListTable/ListTable.stories.d.ts +1 -1
  13. package/lib/components/ListTable/ListTable.styles.d.ts +1 -272
  14. package/lib/components/LoadingAwareContainer/LoadingAwareContainer.d.ts +15 -0
  15. package/lib/components/LoadingAwareContainer/LoadingAwareContainer.stories.d.ts +22 -0
  16. package/lib/components/LoadingAwareContainer/LoadingAwareContainer.styles.d.ts +3 -0
  17. package/lib/components/LoadingAwareContainer/index.d.ts +1 -0
  18. package/lib/components/Navigation/Drawer/Drawer.d.ts +15 -0
  19. package/lib/components/Navigation/Drawer/Drawer.stories.d.ts +6 -0
  20. package/lib/components/Navigation/Drawer/Drawer.styles.d.ts +7 -0
  21. package/lib/components/Navigation/Drawer/DrawerLinkList.d.ts +9 -0
  22. package/lib/components/Navigation/Drawer/DrawerLinkList.styles.d.ts +2 -0
  23. package/lib/components/Navigation/Drawer/__mocks__/mocks.d.ts +3 -0
  24. package/lib/components/Navigation/Drawer/__tests__/Drawer.test.d.ts +1 -0
  25. package/lib/components/Navigation/Drawer/__tests__/DrawerLinkList.test.d.ts +1 -0
  26. package/lib/components/Navigation/Drawer/index.d.ts +1 -0
  27. package/lib/components/Navigation/Drawer/types.d.ts +7 -0
  28. package/lib/components/Navigation/index.d.ts +1 -0
  29. package/lib/components/Pagination/Pagination.d.ts +1 -2
  30. package/lib/components/Pagination/Pagination.styles.d.ts +1 -272
  31. package/lib/components/Wizard/Wizard.d.ts +48 -0
  32. package/lib/components/Wizard/Wizard.stories.d.ts +29 -0
  33. package/lib/components/Wizard/Wizard.styles.d.ts +4 -0
  34. package/lib/components/Wizard/index.d.ts +2 -0
  35. package/lib/components/WizardWithSidebar/WizardWithSidebar.d.ts +58 -0
  36. package/lib/components/WizardWithSidebar/WizardWithSidebar.stories.d.ts +46 -0
  37. package/lib/components/WizardWithSidebar/WizardWithSidebar.styles.d.ts +9 -0
  38. package/lib/components/WizardWithSidebar/index.d.ts +2 -0
  39. package/lib/components/basic-section/Section/Section.d.ts +1 -1
  40. package/lib/components/basic-section/Section/Section.stories.d.ts +1 -1
  41. package/lib/components/basic-section/Section/Section.styles.d.ts +1 -272
  42. package/lib/components/basic-section/SectionBlock/SectionBlock.d.ts +1 -1
  43. package/lib/components/basic-section/SectionBlock/SectionBlock.styles.d.ts +1 -272
  44. package/lib/components/basic-section/SectionBody/SectionBody.d.ts +1 -1
  45. package/lib/components/basic-section/SectionBody/SectionBody.stories.d.ts +1 -2
  46. package/lib/components/basic-section/SectionBody/SectionBody.styles.d.ts +1 -272
  47. package/lib/components/basic-section/SectionHeader/SectionHeader.d.ts +1 -1
  48. package/lib/components/basic-section/SectionHeader/SectionHeader.stories.d.ts +1 -1
  49. package/lib/components/basic-section/SectionHeader/SectionHeader.styles.d.ts +1 -272
  50. package/lib/components/basic-section/SectionTable/SectionTable.d.ts +1 -2
  51. package/lib/components/basic-section/SectionTable/SectionTable.styles.d.ts +1 -272
  52. package/lib/components/buttons/Button/Button.styles.d.ts +1 -282
  53. package/lib/components/buttons/IconButton/IconButton.d.ts +4 -5
  54. package/lib/components/buttons/IconButton/IconButton.stories.d.ts +3 -3
  55. package/lib/components/buttons/IconButton/IconButton.styles.d.ts +2 -567
  56. package/lib/components/buttons/types.d.ts +2 -1
  57. package/lib/components/dropdowns/BorderSelect/BorderSelect.d.ts +1 -1
  58. package/lib/components/dropdowns/BorderSelect/BorderSelect.stories.d.ts +1 -1
  59. package/lib/components/dropdowns/BorderSelect/BorderSelect.styles.d.ts +2 -543
  60. package/lib/components/dropdowns/MultiCombobox/MultiCombobox.styles.d.ts +1 -84
  61. package/lib/components/dropdowns/Select/Select.d.ts +1 -1
  62. package/lib/components/dropdowns/Select/Select.stories.d.ts +1 -1
  63. package/lib/components/dropdowns/Select/Select.styles.d.ts +1 -272
  64. package/lib/components/dropdowns/SingleCombobox/SingleCombobox.styles.d.ts +1 -84
  65. package/lib/components/dropdowns/utils.d.ts +1 -2
  66. package/lib/components/index.d.ts +7 -2
  67. package/lib/components/inputs/EditableInput/EditableInput.d.ts +1 -1
  68. package/lib/components/inputs/EditableInput/EditableInput.stories.d.ts +1 -2
  69. package/lib/components/inputs/EditableInput/EditableInput.styles.d.ts +1 -272
  70. package/lib/components/inputs/NumberInput/NumberInput.styles.d.ts +1 -272
  71. package/lib/components/inputs/RadioButtons/RadioButtons.d.ts +24 -0
  72. package/lib/components/inputs/RadioButtons/RadioButtons.stories.d.ts +15 -0
  73. package/lib/components/inputs/RadioButtons/RadioButtons.styles.d.ts +14 -0
  74. package/lib/components/inputs/RadioButtons/index.d.ts +1 -0
  75. package/lib/components/inputs/RadioGroup/RadioGroup.d.ts +27 -0
  76. package/lib/components/inputs/RadioGroup/RadioGroup.stories.d.ts +16 -0
  77. package/lib/components/inputs/RadioGroup/RadioGroup.styles.d.ts +2 -0
  78. package/lib/components/inputs/RadioGroup/index.d.ts +1 -0
  79. package/lib/components/inputs/SearchInput/SearchInput.d.ts +1 -1
  80. package/lib/components/inputs/SearchInput/SearchInput.stories.d.ts +1 -1
  81. package/lib/components/inputs/SearchInput/SearchInput.styles.d.ts +1 -5
  82. package/lib/components/inputs/TextInput/TextInput.styles.d.ts +2 -543
  83. package/lib/components/inputs/index.d.ts +2 -0
  84. package/lib/components/loading-indicators/BarSpinner/BarSpinner.styles.d.ts +1 -272
  85. package/lib/components/loading-indicators/CirclePulse/CirclePulse.styles.d.ts +3 -3
  86. package/lib/components/loading-indicators/LoadingIndicator/LoadingIndicator.d.ts +10 -0
  87. package/lib/components/loading-indicators/LoadingIndicator/LoadingIndicator.stories.d.ts +11 -0
  88. package/lib/components/loading-indicators/LoadingIndicator/LoadingIndicator.styles.d.ts +8 -0
  89. package/lib/components/loading-indicators/LoadingIndicator/index.d.ts +1 -0
  90. package/lib/components/loading-indicators/LoadingList/LoadingList.d.ts +1 -2
  91. package/lib/components/loading-indicators/LoadingList/LoadingList.stories.d.ts +1 -2
  92. package/lib/components/loading-indicators/LoadingList/LoadingList.styles.d.ts +1 -272
  93. package/lib/components/loading-indicators/PercentageRing/PercentageRing.d.ts +1 -2
  94. package/lib/components/loading-indicators/PercentageRing/PercentageRing.styles.d.ts +1 -272
  95. package/lib/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.d.ts +1 -2
  96. package/lib/components/loading-indicators/RandomLoadingMessage/RandomLoadingMessage.stories.d.ts +1 -2
  97. package/lib/components/loading-indicators/index.d.ts +1 -0
  98. package/lib/components/modals/ConfirmModal/ConfirmModal.d.ts +17 -0
  99. package/lib/components/modals/ConfirmModal/ConfirmModal.stories.d.ts +44 -0
  100. package/lib/components/modals/ConfirmModal/ConfirmModal.styles.d.ts +2 -0
  101. package/lib/components/modals/ConfirmModal/index.d.ts +1 -0
  102. package/lib/components/modals/ModalBase/ModalBase.d.ts +27 -0
  103. package/lib/components/modals/ModalBase/ModalBase.stories.d.ts +9 -0
  104. package/lib/components/modals/ModalBase/ModalBase.styles.d.ts +4 -0
  105. package/lib/components/modals/ModalBase/index.d.ts +2 -0
  106. package/lib/components/modals/index.d.ts +2 -0
  107. package/lib/components/user-feedback/Shrug/Shrug.stories.d.ts +1 -1
  108. package/lib/components/user-feedback/Shrug/Shrug.styles.d.ts +1 -272
  109. package/lib/index.d.ts +531 -270
  110. package/lib/index.esm.js +5722 -824
  111. package/lib/index.esm.js.map +1 -1
  112. package/lib/index.js +5779 -867
  113. package/lib/index.js.map +1 -1
  114. package/lib/setupTests.d.ts +1 -0
  115. package/lib/styles/globals/index.d.ts +1 -2
  116. package/lib/tokens/colors.d.ts +9 -0
  117. package/lib/tokens/typography.d.ts +12 -0
  118. package/lib/types.d.ts +147 -125
  119. package/package.json +60 -42
  120. package/src/components/Icon/Icon.tsx +1 -0
  121. package/src/components/Icon/indicons.tsx +138 -15
  122. package/src/components/ListTable/ListTable.stories.tsx +1 -1
  123. package/src/components/LoadingAwareContainer/LoadingAwareContainer.stories.tsx +45 -0
  124. package/src/components/LoadingAwareContainer/LoadingAwareContainer.styles.ts +16 -0
  125. package/src/components/LoadingAwareContainer/LoadingAwareContainer.tsx +36 -0
  126. package/src/components/LoadingAwareContainer/index.ts +1 -0
  127. package/src/components/Navigation/Drawer/Drawer.stories.tsx +44 -0
  128. package/src/components/Navigation/Drawer/Drawer.styles.ts +75 -0
  129. package/src/components/Navigation/Drawer/Drawer.tsx +108 -0
  130. package/src/components/Navigation/Drawer/DrawerLinkList.styles.ts +66 -0
  131. package/src/components/Navigation/Drawer/DrawerLinkList.tsx +64 -0
  132. package/src/components/Navigation/Drawer/__mocks__/mocks.ts +49 -0
  133. package/src/components/Navigation/Drawer/__tests__/Drawer.test.tsx +175 -0
  134. package/src/components/Navigation/Drawer/__tests__/DrawerLinkList.test.tsx +66 -0
  135. package/src/components/Navigation/Drawer/index.ts +1 -0
  136. package/src/components/Navigation/Drawer/types.ts +8 -0
  137. package/src/components/Navigation/index.ts +1 -0
  138. package/src/components/Wizard/Wizard.stories.tsx +180 -0
  139. package/src/components/Wizard/Wizard.styles.ts +72 -0
  140. package/src/components/Wizard/Wizard.tsx +211 -0
  141. package/src/components/Wizard/index.ts +2 -0
  142. package/src/components/WizardWithSidebar/WizardWithSidebar.stories.tsx +143 -0
  143. package/src/components/WizardWithSidebar/WizardWithSidebar.styles.ts +123 -0
  144. package/src/components/WizardWithSidebar/WizardWithSidebar.tsx +262 -0
  145. package/src/components/WizardWithSidebar/index.ts +2 -0
  146. package/src/components/buttons/IconButton/IconButton.styles.ts +31 -0
  147. package/src/components/buttons/IconButton/IconButton.tsx +8 -6
  148. package/src/components/buttons/types.ts +2 -1
  149. package/src/components/index.ts +16 -1
  150. package/src/components/inputs/RadioButtons/RadioButtons.stories.tsx +84 -0
  151. package/src/components/inputs/RadioButtons/RadioButtons.styles.ts +82 -0
  152. package/src/components/inputs/RadioButtons/RadioButtons.tsx +61 -0
  153. package/src/components/inputs/RadioButtons/index.tsx +1 -0
  154. package/src/components/inputs/RadioGroup/RadioGroup.stories.tsx +66 -0
  155. package/src/components/inputs/RadioGroup/RadioGroup.styles.ts +11 -0
  156. package/src/components/inputs/RadioGroup/RadioGroup.tsx +120 -0
  157. package/src/components/inputs/RadioGroup/index.ts +1 -0
  158. package/src/components/inputs/SearchInput/SearchInput.styles.ts +28 -42
  159. package/src/components/inputs/SearchInput/SearchInput.tsx +6 -4
  160. package/src/components/inputs/index.ts +2 -0
  161. package/src/components/loading-indicators/CirclePulse/CirclePulse.styles.ts +7 -7
  162. package/src/components/loading-indicators/CirclePulse/CirclePulse.tsx +3 -3
  163. package/src/components/loading-indicators/LoadingIndicator/LoadingIndicator.stories.tsx +22 -0
  164. package/src/components/loading-indicators/LoadingIndicator/LoadingIndicator.styles.ts +81 -0
  165. package/src/components/loading-indicators/LoadingIndicator/LoadingIndicator.tsx +61 -0
  166. package/src/components/loading-indicators/LoadingIndicator/index.ts +1 -0
  167. package/src/components/loading-indicators/index.ts +1 -0
  168. package/src/components/modals/ConfirmModal/ConfirmModal.stories.tsx +76 -0
  169. package/src/components/modals/ConfirmModal/ConfirmModal.styles.ts +30 -0
  170. package/src/components/modals/ConfirmModal/ConfirmModal.tsx +84 -0
  171. package/src/components/modals/ConfirmModal/index.ts +1 -0
  172. package/src/components/modals/ModalBase/ModalBase.stories.tsx +47 -0
  173. package/src/components/modals/ModalBase/ModalBase.styles.tsx +73 -0
  174. package/src/components/modals/ModalBase/ModalBase.tsx +72 -0
  175. package/src/components/modals/ModalBase/index.ts +2 -0
  176. package/src/components/modals/index.ts +2 -0
  177. package/src/index.ts +13 -0
  178. package/src/setupTests.ts +4 -0
  179. package/src/tokens/colors.ts +9 -0
  180. package/src/tokens/typography.ts +7 -1
  181. package/src/types.ts +8 -0
  182. package/tsconfig.json +1 -1
@@ -0,0 +1,262 @@
1
+ // TODO: This component's migration was fast-tracked for Insights. Assess for potential refactor and documentation.
2
+
3
+ import React, { useEffect, useMemo, useState } from 'react';
4
+ import classNames from 'classnames';
5
+
6
+ import { Button, ConfirmModal, Icon, IconButton } from '@/components';
7
+ import { PermafrostComponent } from '@/types';
8
+
9
+ import { StyledWizardWithSidebar } from './WizardWithSidebar.styles';
10
+
11
+ export type CancelText = {
12
+ // "confirm" button text
13
+ confirmText: string;
14
+ message?: string;
15
+ // "reject" button text
16
+ rejectText: string;
17
+ title: string;
18
+ // Optional, supporting text
19
+ };
20
+
21
+ type Props = PermafrostComponent & {
22
+ children: React.ReactNode;
23
+ /**
24
+ * text for the cancel confirmation modal
25
+ */
26
+ confirmCancel: CancelText;
27
+ disableNextStep?: boolean;
28
+ disablePrevStep?: boolean;
29
+ disableSubmit?: boolean;
30
+ isLastStep?: boolean;
31
+ /**
32
+ * for testing/mocking purposes
33
+ */
34
+ startingStep?: string;
35
+ stepSchema: {
36
+ [key: string]: {
37
+ inputsRequiringValidation: string[];
38
+ description: string[];
39
+ };
40
+ };
41
+ /**
42
+ * the text to appear on the submit button
43
+ */
44
+ submitButtonLabel: string;
45
+ /**
46
+ * Puts button in "busy" mode, and replaces button label with this text
47
+ */
48
+ submitProcessing?: string;
49
+ wizardTitle: string;
50
+ onCancel?(): void;
51
+ onNextPress?(): boolean;
52
+ /**
53
+ * returns the current step name to the parent component
54
+ */
55
+ onStepChange(stepName: string): void;
56
+ onSubmit(): void;
57
+ /**
58
+ * Allows for any custom attribute to be added directly to "next button" in wizard
59
+ */
60
+ nextButtonProps?: {
61
+ 'data-cy': string;
62
+ };
63
+
64
+ bottomNav?: boolean;
65
+ validationErrors?: any;
66
+ backgroundColor?: string;
67
+ color?: string;
68
+ buttonColor?: string;
69
+ };
70
+
71
+ export function WizardWithSidebar(props: Props) {
72
+ const {
73
+ children,
74
+ className,
75
+ confirmCancel,
76
+ disableNextStep,
77
+ disablePrevStep,
78
+ disableSubmit,
79
+ id,
80
+ isLastStep,
81
+ onCancel,
82
+ onNextPress,
83
+ onStepChange,
84
+ onSubmit,
85
+ startingStep,
86
+ stepSchema,
87
+ submitButtonLabel,
88
+ submitProcessing = '',
89
+ wizardTitle,
90
+ nextButtonProps,
91
+ validationErrors,
92
+ backgroundColor,
93
+ color,
94
+ buttonColor,
95
+ } = props;
96
+
97
+ const steps = Object.keys(stepSchema);
98
+ const [currentStep, setCurrentStep] = useState<string>(startingStep || steps[0]);
99
+ const [openCancelConfirm, setOpenCancelConfirm] = useState<boolean>(false);
100
+
101
+ const onLastStep: boolean = useMemo(() => {
102
+ if (isLastStep !== undefined) {
103
+ return isLastStep;
104
+ }
105
+
106
+ return steps.indexOf(currentStep) === steps.length - 1;
107
+ }, [isLastStep, steps, currentStep]);
108
+
109
+ const isBusy = !!(submitProcessing && submitProcessing.length > 0);
110
+
111
+ const nextStep = () => {
112
+ if (!onLastStep) {
113
+ const currentIndex = steps.indexOf(currentStep);
114
+
115
+ setCurrentStep(steps[currentIndex + 1]);
116
+ }
117
+ };
118
+
119
+ const prevStep = () => {
120
+ const currentIndex = steps.indexOf(currentStep);
121
+
122
+ if (currentIndex !== 0) {
123
+ setCurrentStep(steps[currentIndex - 1]);
124
+ }
125
+ };
126
+
127
+ // handles the user's selection in the cancel confirmation modal
128
+ const handleCancelRequest = (confirmCancel: boolean) => {
129
+ if (confirmCancel && onCancel) {
130
+ onCancel();
131
+ }
132
+
133
+ setOpenCancelConfirm(false);
134
+ };
135
+
136
+ const handleNextPress = () => {
137
+ const allowNext = onNextPress ? onNextPress() : true;
138
+
139
+ if (!allowNext) {
140
+ return;
141
+ }
142
+
143
+ if (onLastStep) {
144
+ handleSubmit();
145
+ } else {
146
+ nextStep();
147
+ }
148
+ };
149
+
150
+ const handleSubmit = () => {
151
+ onSubmit();
152
+ };
153
+
154
+ // report current step to the consuming component
155
+ useEffect(() => {
156
+ onStepChange(currentStep);
157
+ }, [currentStep]);
158
+
159
+ // ensures `currentStep` is reset on unmount, just in case
160
+ useEffect(() => {
161
+ return () => setCurrentStep(steps[0] || '');
162
+ }, []);
163
+
164
+ return (
165
+ <StyledWizardWithSidebar
166
+ className={className}
167
+ data-cy={props['data-cy']}
168
+ id={id}
169
+ backgroundcolor={backgroundColor}
170
+ color={color}
171
+ buttoncolor={buttonColor}
172
+ >
173
+ <div className="wizard-sidebar">
174
+ <h2> {wizardTitle}</h2>
175
+
176
+ {steps.map((step: string, index: number) => {
177
+ return (
178
+ <div
179
+ className={classNames('sidebar-step', {
180
+ ['current-step']: index === steps.indexOf(currentStep),
181
+ ['prior-step']: index < steps.indexOf(currentStep),
182
+ })}
183
+ key={step}
184
+ >
185
+ {(Object.keys(validationErrors ? validationErrors : []).some((error) =>
186
+ stepSchema[step].inputsRequiringValidation.includes(error),
187
+ ) ||
188
+ index > steps.indexOf(currentStep)) && (
189
+ <div className="sidebar-step__number-icon">{index + 1}</div>
190
+ )}
191
+
192
+ {!Object.keys(validationErrors ? validationErrors : []).some((error) =>
193
+ stepSchema[step].inputsRequiringValidation.includes(error),
194
+ ) &&
195
+ index <= steps.indexOf(currentStep) && (
196
+ <Icon name="fa-check-circle" className="sidebar-step__check-icon" />
197
+ )}
198
+ {step}
199
+ </div>
200
+ );
201
+ })}
202
+ </div>
203
+
204
+ <div className="wizard-content">
205
+ <div className="wizard-content__header">
206
+ <h2>{currentStep}</h2>
207
+ </div>
208
+ <div className="wizard-content__body">{children}</div>
209
+
210
+ <nav>
211
+ <div className="wizard-buttons">
212
+ <Button onClick={() => setOpenCancelConfirm(true)} variant="link-style">
213
+ Cancel
214
+ </Button>
215
+
216
+ {steps.indexOf(currentStep) !== 0 && (
217
+ <IconButton
218
+ variant="outline"
219
+ iconName="fa-arrow-left"
220
+ label="Previous Step"
221
+ onPress={prevStep}
222
+ isDisabled={disablePrevStep}
223
+ />
224
+ )}
225
+
226
+ {onLastStep ? (
227
+ <IconButton
228
+ variant="primary"
229
+ iconName="check"
230
+ busy={isBusy}
231
+ label={isBusy ? submitProcessing : submitButtonLabel}
232
+ onPress={handleNextPress}
233
+ isDisabled={disableSubmit}
234
+ />
235
+ ) : (
236
+ <IconButton
237
+ variant="primary"
238
+ iconSide="end"
239
+ iconName="fa-arrow-right"
240
+ label="Next Step"
241
+ onPress={handleNextPress}
242
+ isDisabled={disableNextStep}
243
+ {...nextButtonProps}
244
+ />
245
+ )}
246
+ </div>
247
+ </nav>
248
+ </div>
249
+
250
+ <ConfirmModal
251
+ title={confirmCancel.title}
252
+ message={confirmCancel.message}
253
+ confirmText={confirmCancel.confirmText}
254
+ rejectText={confirmCancel.rejectText}
255
+ open={openCancelConfirm}
256
+ clickOutsideHandler={() => setOpenCancelConfirm(false)}
257
+ responseHandler={handleCancelRequest}
258
+ width={430}
259
+ />
260
+ </StyledWizardWithSidebar>
261
+ );
262
+ }
@@ -0,0 +1,2 @@
1
+ export { WizardWithSidebar } from './WizardWithSidebar';
2
+ export { StyledWizardWithSidebar } from './WizardWithSidebar.styles';
@@ -9,6 +9,7 @@ import {
9
9
  variantPrimary,
10
10
  disabledOverrides,
11
11
  } from '../commonStyles';
12
+ import { COLORS, ANIMATION } from '@/tokens';
12
13
 
13
14
  const iconMargin = '0.5em';
14
15
 
@@ -43,6 +44,36 @@ export const iconButton = css`
43
44
  ${variantPrimary};
44
45
  }
45
46
 
47
+ &.outline {
48
+ color: ${COLORS.midFontColor};
49
+ background: transparent;
50
+ border: 1px solid ${COLORS.midFontColor};
51
+ transition:
52
+ border ${ANIMATION.duration} ${ANIMATION.timing},
53
+ color ${ANIMATION.duration} ${ANIMATION.timing};
54
+
55
+ &:hover,
56
+ &:focus {
57
+ border: 1px solid ${COLORS.defaultFontColor};
58
+ color: ${COLORS.defaultFontColor};
59
+ background: transparent;
60
+ }
61
+
62
+ &:disabled {
63
+ border: 1px solid ${COLORS.midFontColor};
64
+ color: ${COLORS.midFontColor};
65
+ background: transparent;
66
+ opacity: 0.6;
67
+
68
+ &:hover {
69
+ background: transparent;
70
+ border: 1px solid ${COLORS.midFontColor};
71
+ color: ${COLORS.midFontColor};
72
+ opacity: 0.6;
73
+ }
74
+ }
75
+ }
76
+
46
77
  // todo: use this rule/selector after global styling removed
47
78
  //:not(:disabled):hover {
48
79
  // background-color: #bebebe;
@@ -6,11 +6,10 @@ import { useButton } from '@react-aria/button';
6
6
  import { useFocusRing } from '@react-aria/focus';
7
7
  import { AriaButtonProps } from '@react-types/button';
8
8
 
9
- import { IconName } from '@/types';
10
- import { Icon } from '@/components/Icon';
11
- import { CircleSpinner } from '@/components/loading-indicators';
12
- import { PermafrostComponent } from '@/types';
13
- import { ButtonSize, ButtonVariant } from '../types';
9
+ import { SPACING } from '@/tokens';
10
+ import { IconName, PermafrostComponent } from '@/types';
11
+ import { Icon, CircleSpinner } from '@/components';
12
+ import { ButtonSize, IconButtonVariant } from '../types';
14
13
 
15
14
  import { StyledIconButton, StyledIconButtonLink } from './IconButton.styles';
16
15
 
@@ -30,7 +29,7 @@ type Props = PermafrostComponent & {
30
29
  label?: string;
31
30
  size?: ButtonSize;
32
31
  style?: React.CSSProperties;
33
- variant?: ButtonVariant;
32
+ variant?: IconButtonVariant;
34
33
  } & AriaButtonProps;
35
34
 
36
35
  /**
@@ -60,6 +59,7 @@ export function IconButton(props: Props) {
60
59
  const buttonEl = useRef();
61
60
  const { buttonProps } = useButton(
62
61
  { ...props, onPress: busy ? undefined : props.onPress },
62
+ // @ts-ignore
63
63
  buttonEl,
64
64
  );
65
65
  const { isFocusVisible, focusProps } = useFocusRing();
@@ -85,6 +85,7 @@ export function IconButton(props: Props) {
85
85
  style={{
86
86
  marginTop: `${adjustAlignment}px`,
87
87
  marginBottom: `${Math.abs(adjustAlignment)}px`,
88
+ marginRight: `${SPACING.xs}`,
88
89
  }}
89
90
  />
90
91
  ) : (
@@ -105,6 +106,7 @@ export function IconButton(props: Props) {
105
106
  }
106
107
 
107
108
  return (
109
+ // @ts-ignore
108
110
  <StyledIconButton {...commonProps}>
109
111
  {iconElement} {labelElement}
110
112
  </StyledIconButton>
@@ -1,2 +1,3 @@
1
- export type ButtonVariant = 'default' | 'primary' | 'destructive';
1
+ export type ButtonVariant = 'primary' | 'cta' | 'normal' | 'link-style' | 'no-style' | 'outline';
2
+ export type IconButtonVariant = 'default' | 'primary' | 'destructive' | 'outline';
2
3
  export type ButtonSize = 'normal' | 'large';
@@ -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,
@@ -11,7 +20,13 @@ export {
11
20
  LoadingList,
12
21
  PercentageRing,
13
22
  RandomLoadingMessage,
23
+ LoadingIndicator,
14
24
  } from './loading-indicators';
15
25
  export { ListTable } from './ListTable';
16
26
  export { Pagination } from './Pagination';
17
27
  export { Shrug } from './user-feedback';
28
+ export { ConfirmModal, ModalBase } from './modals';
29
+ export { LoadingAwareContainer } from './LoadingAwareContainer';
30
+ export { Wizard, WizardCard, WizardSection, StyledWizard } from './Wizard';
31
+ export { WizardWithSidebar } from './WizardWithSidebar';
32
+ export { Drawer } from './Navigation/Drawer';
@@ -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
+ };