@indico-data/design-system 2.9.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/lib/index.css +119 -8
  2. package/lib/index.d.ts +52 -8
  3. package/lib/index.esm.css +119 -8
  4. package/lib/index.esm.js +35 -19
  5. package/lib/index.esm.js.map +1 -1
  6. package/lib/index.js +36 -18
  7. package/lib/index.js.map +1 -1
  8. package/lib/src/components/forms/checkbox/Checkbox.d.ts +2 -1
  9. package/lib/src/components/forms/form/Form.d.ts +14 -0
  10. package/lib/src/components/forms/form/Form.stories.d.ts +8 -0
  11. package/lib/src/components/forms/input/Input.d.ts +5 -4
  12. package/lib/src/components/forms/passwordInput/PasswordInput.d.ts +17 -0
  13. package/lib/src/components/forms/passwordInput/PasswordInput.stories.d.ts +11 -0
  14. package/lib/src/components/forms/passwordInput/__tests__/PasswordInput.test.d.ts +1 -0
  15. package/lib/src/components/forms/passwordInput/index.d.ts +1 -0
  16. package/lib/src/components/forms/radio/Radio.d.ts +2 -1
  17. package/lib/src/components/forms/subcomponents/DisplayFormError.d.ts +5 -0
  18. package/lib/src/components/forms/textarea/Textarea.d.ts +4 -3
  19. package/lib/src/components/forms/toggle/Toggle.d.ts +2 -1
  20. package/lib/src/components/index.d.ts +2 -0
  21. package/lib/src/index.d.ts +2 -0
  22. package/package.json +5 -2
  23. package/src/components/forms/checkbox/Checkbox.stories.tsx +2 -2
  24. package/src/components/forms/checkbox/Checkbox.tsx +32 -41
  25. package/src/components/forms/form/Form.mdx +134 -0
  26. package/src/components/forms/form/Form.stories.tsx +413 -0
  27. package/src/components/forms/form/Form.tsx +64 -0
  28. package/src/components/forms/form/__tests__/Form.test.tsx +35 -0
  29. package/src/components/forms/form/index.ts +0 -0
  30. package/src/components/forms/form/styles/Form.scss +3 -0
  31. package/src/components/forms/input/Input.stories.tsx +0 -5
  32. package/src/components/forms/input/Input.tsx +67 -64
  33. package/src/components/forms/input/__tests__/Input.test.tsx +2 -13
  34. package/src/components/forms/input/styles/Input.scss +2 -8
  35. package/src/components/forms/passwordInput/PasswordInput.mdx +28 -0
  36. package/src/components/forms/passwordInput/PasswordInput.stories.tsx +268 -0
  37. package/src/components/forms/passwordInput/PasswordInput.tsx +86 -0
  38. package/src/components/forms/passwordInput/__tests__/PasswordInput.test.tsx +129 -0
  39. package/src/components/forms/passwordInput/index.ts +1 -0
  40. package/src/components/forms/passwordInput/styles/PasswordInput.scss +120 -0
  41. package/src/components/forms/radio/Radio.tsx +32 -35
  42. package/src/components/forms/subcomponents/DisplayFormError.tsx +7 -0
  43. package/src/components/forms/textarea/Textarea.stories.tsx +15 -21
  44. package/src/components/forms/textarea/Textarea.tsx +64 -62
  45. package/src/components/forms/textarea/__tests__/Textarea.test.tsx +1 -1
  46. package/src/components/forms/textarea/styles/Textarea.scss +1 -1
  47. package/src/components/forms/toggle/Toggle.tsx +30 -37
  48. package/src/components/index.ts +2 -0
  49. package/src/index.ts +2 -0
  50. package/src/styles/index.scss +2 -0
  51. package/lib/src/components/forms/subcomponents/ErrorList.d.ts +0 -6
  52. package/src/components/forms/subcomponents/ErrorList.tsx +0 -14
  53. package/src/components/forms/subcomponents/__tests__/ErrorList.test.tsx +0 -16
  54. /package/lib/src/components/forms/{subcomponents/__tests__/ErrorList.test.d.ts → form/__tests__/Form.test.d.ts} +0 -0
@@ -2,85 +2,88 @@ import React from 'react';
2
2
  import { Icon } from '@/components/icons';
3
3
  import { IconName } from '@/types';
4
4
  import { Label } from '../subcomponents/Label';
5
- import { ErrorList } from '../subcomponents/ErrorList';
5
+ import { DisplayFormError } from '../subcomponents/DisplayFormError';
6
6
 
7
7
  export interface InputProps {
8
- ref?: React.LegacyRef<HTMLInputElement>;
9
8
  label: string;
10
9
  name: string;
10
+ value?: string | undefined;
11
11
  placeholder: string;
12
- value: string;
13
12
  onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
14
13
  isRequired?: boolean;
15
14
  isDisabled?: boolean;
16
- errorList?: string[];
15
+ errorMessage?: string | undefined;
17
16
  helpText?: string;
18
17
  hasHiddenLabel?: boolean;
19
18
  iconName?: IconName;
20
19
  isClearable?: boolean;
20
+ className?: string;
21
+ defaultValue?: string;
21
22
  }
22
23
 
23
- export const Input = ({
24
- ref,
25
- label,
26
- name,
27
- placeholder,
28
- value,
29
- onChange,
30
- isRequired,
31
- isDisabled,
32
- errorList,
33
- helpText,
34
- iconName,
35
- hasHiddenLabel,
36
- isClearable,
37
- ...rest
38
- }: InputProps) => {
39
- const hasErrors = errorList && errorList.length > 0;
40
- const handleClear = () => {
41
- onChange({ target: { value: '' } } as React.ChangeEvent<HTMLInputElement>);
42
- };
24
+ export const Input = React.forwardRef<HTMLInputElement, InputProps>(
25
+ (
26
+ {
27
+ label,
28
+ name,
29
+ placeholder,
30
+ onChange,
31
+ isRequired,
32
+ isDisabled,
33
+ isClearable,
34
+ errorMessage,
35
+ helpText,
36
+ iconName,
37
+ hasHiddenLabel,
38
+ className,
39
+ ...rest
40
+ },
41
+ ref,
42
+ ) => {
43
+ const hasErrors = errorMessage && errorMessage.length > 0;
44
+ const handleClear = () => {
45
+ onChange({ target: { value: '' } } as React.ChangeEvent<HTMLInputElement>);
46
+ };
43
47
 
44
- return (
45
- <div className="form-control">
46
- <Label label={label} name={name} isRequired={isRequired} hasHiddenLabel={hasHiddenLabel} />
47
- <div className="input-wrapper">
48
- {iconName && (
49
- <Icon name={iconName} data-testid={`${name}-embedded-icon`} className="embedded-icon" />
50
- )}
51
- <input
52
- ref={ref}
53
- data-testid={`form-input-${name}`}
54
- name={name}
55
- type="text"
56
- disabled={isDisabled}
57
- required={isRequired}
58
- placeholder={placeholder}
59
- value={value}
60
- onChange={onChange}
61
- className={`input ${hasErrors ? 'error' : ''} ${iconName ? 'input--has-icon' : ''}`}
62
- aria-invalid={hasErrors}
63
- aria-describedby={hasErrors || helpText ? `${name}-helper` : undefined}
64
- aria-required={isRequired}
65
- aria-label={label}
66
- {...rest}
67
- />
68
- {isClearable && (
69
- <Icon
70
- name="x-close"
71
- data-testid={`${name}-clearable-icon`}
72
- size="sm"
73
- onClick={handleClear}
74
- className="clearable-icon"
48
+ return (
49
+ <div className="form-control">
50
+ <Label label={label} name={name} isRequired={isRequired} hasHiddenLabel={hasHiddenLabel} />
51
+ <div className="input-wrapper">
52
+ {iconName && (
53
+ <Icon name={iconName} data-testid={`${name}-embedded-icon`} className="embedded-icon" />
54
+ )}
55
+ <input
56
+ ref={ref}
57
+ data-testid={`form-input-${name}`}
58
+ name={name}
59
+ type="text"
60
+ disabled={isDisabled}
61
+ placeholder={placeholder}
62
+ onChange={onChange}
63
+ className={`input ${hasErrors ? 'error' : ''} ${iconName ? 'input--has-icon' : ''} ${className}`}
64
+ aria-invalid={hasErrors ? true : undefined}
65
+ aria-describedby={hasErrors || helpText ? `${name}-helper` : undefined}
66
+ aria-required={isRequired}
67
+ aria-label={label}
68
+ {...rest}
75
69
  />
70
+ {isClearable && (
71
+ <Icon
72
+ name="x-close"
73
+ data-testid={`${name}-clearable-icon`}
74
+ size="sm"
75
+ onClick={handleClear}
76
+ className="clearable-icon"
77
+ />
78
+ )}
79
+ </div>
80
+ {hasErrors && <DisplayFormError message={errorMessage} />}
81
+ {helpText && (
82
+ <div data-testid={`${name}-help-text`} className="help-text" id={`${name}-helper`}>
83
+ {helpText}
84
+ </div>
76
85
  )}
77
86
  </div>
78
- {hasErrors && <ErrorList errorList={errorList} name={name} />}
79
- {helpText && (
80
- <div data-testid={`${name}-help-text`} className="help-text" id={`${name}-helper`}>
81
- {helpText}
82
- </div>
83
- )}
84
- </div>
85
- );
86
- };
87
+ );
88
+ },
89
+ );
@@ -17,7 +17,6 @@ describe('Input', () => {
17
17
  iconName="user"
18
18
  isClearable={true}
19
19
  ref={undefined}
20
- value={''}
21
20
  onChange={handleOnChange}
22
21
  />,
23
22
  );
@@ -34,7 +33,6 @@ describe('Input', () => {
34
33
  iconName="user"
35
34
  isClearable={true}
36
35
  ref={undefined}
37
- value={''}
38
36
  onChange={handleOnChange}
39
37
  />,
40
38
  );
@@ -53,7 +51,6 @@ describe('Input', () => {
53
51
  iconName="user"
54
52
  isClearable={false}
55
53
  ref={undefined}
56
- value={''}
57
54
  onChange={handleOnChange}
58
55
  />,
59
56
  );
@@ -71,9 +68,8 @@ describe('Input', () => {
71
68
  placeholder="Please enter a value"
72
69
  iconName="user"
73
70
  isClearable={true}
74
- ref={undefined}
75
- value={'test'}
76
71
  onChange={handleOnChange}
72
+ value="test"
77
73
  />,
78
74
  );
79
75
  const input = screen.getByTestId('form-input-name');
@@ -95,8 +91,6 @@ describe('Input', () => {
95
91
  placeholder="Please enter a value"
96
92
  iconName="user"
97
93
  isClearable={true}
98
- ref={undefined}
99
- value={'test'}
100
94
  onChange={handleOnChange}
101
95
  />,
102
96
  );
@@ -113,8 +107,6 @@ describe('Input', () => {
113
107
  name="name"
114
108
  placeholder="Please enter a value"
115
109
  isClearable={true}
116
- ref={undefined}
117
- value={'test'}
118
110
  onChange={handleOnChange}
119
111
  />,
120
112
  );
@@ -126,13 +118,12 @@ describe('Input', () => {
126
118
  render(
127
119
  <Input
128
120
  isRequired={true}
129
- errorList={['You require a username value.']}
121
+ errorMessage="You require a username value."
130
122
  label="Enter your name"
131
123
  helpText="In order to submit the form, this field is required."
132
124
  name="name"
133
125
  placeholder="Please enter a value"
134
126
  isClearable={true}
135
- ref={undefined}
136
127
  value={'test'}
137
128
  onChange={handleOnChange}
138
129
  />,
@@ -201,8 +192,6 @@ describe('Input', () => {
201
192
  label="Enter your name"
202
193
  name="name"
203
194
  placeholder="Please enter a value"
204
- ref={undefined}
205
- value={''}
206
195
  onChange={handleOnChange}
207
196
  />,
208
197
  );
@@ -73,14 +73,7 @@
73
73
  }
74
74
 
75
75
  .form-control {
76
- .error-list {
77
- list-style: none;
78
- padding: 0;
79
- margin: 0;
80
- margin-top: var(--pf-margin-2);
81
- margin-bottom: var(--pf-margin-2);
82
- color: var(--pf-error-color);
83
- }
76
+ margin-bottom: var(--pf-margin-3);
84
77
  .help-text {
85
78
  margin-top: var(--pf-margin-2);
86
79
  margin-bottom: var(--pf-margin-2);
@@ -100,6 +93,7 @@
100
93
  top: var(--pf-margin-3);
101
94
  right: var(--pf-margin-2);
102
95
  color: var(--pf-input-text-color);
96
+ cursor: pointer;
103
97
  }
104
98
  }
105
99
  .is-visually-hidden {
@@ -0,0 +1,28 @@
1
+ import { Canvas, Meta, Controls } from '@storybook/blocks';
2
+ import * as PasswordInput from './PasswordInput.stories';
3
+
4
+ <Meta title="Forms/PasswordInput" name="PasswordInput" />
5
+
6
+ # Password Input
7
+
8
+ The password input component is the building block of any form. Below you will find the accepted properties for this component. It is encouraged to build forms utilizing [React Hook Form](https://react-hook-form.com/) library in your application. This will facilitate form state management and enforce best practices. (***Our components are compatible with but do not provide the plugin***)
9
+
10
+ <Canvas
11
+ of={PasswordInput.Default}
12
+ source={{
13
+ code: `
14
+ <PasswordInput
15
+ name="first_name"
16
+ isRequired
17
+ hasShowPassword
18
+ placeholder="Placeholder Text"
19
+ value=''
20
+ onChange={() => {}}
21
+ helpText="This Is Help Text"
22
+ label="Label Name"
23
+ />
24
+ `,
25
+ }}
26
+ />
27
+
28
+ <Controls of={PasswordInput.Default} />
@@ -0,0 +1,268 @@
1
+ import { Meta, StoryObj } from '@storybook/react';
2
+ import { PasswordInput, PasswordInputProps } from './PasswordInput';
3
+ import { SetStateAction, useEffect, useState } from 'react';
4
+ import { iconNames } from 'build/generated/iconTypes';
5
+
6
+ const meta: Meta = {
7
+ title: 'Forms/PasswordInput',
8
+ component: PasswordInput,
9
+ argTypes: {
10
+ hasShowPassword: {
11
+ control: 'boolean',
12
+ description: 'Toggles the visibility of the password',
13
+ table: {
14
+ category: 'Props',
15
+ type: {
16
+ summary: 'boolean',
17
+ },
18
+ },
19
+ defaultValue: { summary: true },
20
+ },
21
+ onChange: {
22
+ control: false,
23
+ description: 'onChange event handler',
24
+ table: {
25
+ category: 'Callbacks',
26
+ type: {
27
+ summary: '(e: React.ChangeEvent<HTMLInputElement>) => void',
28
+ },
29
+ },
30
+ action: 'onChange',
31
+ },
32
+ label: {
33
+ control: 'text',
34
+ description: 'The label for the password field',
35
+ table: {
36
+ category: 'Props',
37
+ type: {
38
+ summary: 'string',
39
+ },
40
+ },
41
+ },
42
+ name: {
43
+ control: 'text',
44
+ description: 'The name for the password field',
45
+ table: {
46
+ category: 'Props',
47
+ type: {
48
+ summary: 'string',
49
+ },
50
+ },
51
+ },
52
+ placeholder: {
53
+ control: 'text',
54
+ description: 'The placeholder for the password field',
55
+ table: {
56
+ category: 'Props',
57
+ type: {
58
+ summary: 'string',
59
+ },
60
+ },
61
+ },
62
+ value: {
63
+ control: 'text',
64
+ description: 'The value for the password field',
65
+ table: {
66
+ category: 'Props',
67
+ type: {
68
+ summary: 'string',
69
+ },
70
+ },
71
+ },
72
+ isRequired: {
73
+ control: 'boolean',
74
+ description: 'Toggles the required astherisk on the label',
75
+ table: {
76
+ category: 'Props',
77
+ type: {
78
+ summary: 'boolean',
79
+ },
80
+ },
81
+ defaultValue: { summary: 'false' },
82
+ },
83
+ isDisabled: {
84
+ control: 'boolean',
85
+ description: 'Toggles the disabled state of the input',
86
+ table: {
87
+ category: 'Props',
88
+ type: {
89
+ summary: 'boolean',
90
+ },
91
+ },
92
+ defaultValue: { summary: 'false' },
93
+ },
94
+ errorMessage: {
95
+ control: false,
96
+ description: 'An array of error messages',
97
+ table: {
98
+ category: 'Props',
99
+ type: {
100
+ summary: 'string',
101
+ },
102
+ },
103
+ defaultValue: { summary: undefined },
104
+ },
105
+ helpText: {
106
+ control: 'text',
107
+ description: 'The help text for the password field',
108
+ table: {
109
+ category: 'Props',
110
+ type: {
111
+ summary: 'string',
112
+ },
113
+ },
114
+ },
115
+ hasHiddenLabel: {
116
+ control: 'boolean',
117
+ description: 'Hides the label visually (retains it for screen readers)',
118
+ table: {
119
+ category: 'Props',
120
+ type: {
121
+ summary: 'boolean',
122
+ },
123
+ },
124
+ defaultValue: { summary: 'false' },
125
+ },
126
+ ref: {
127
+ table: {
128
+ disable: true,
129
+ },
130
+ },
131
+ },
132
+ };
133
+
134
+ export default meta;
135
+
136
+ type Story = StoryObj<typeof PasswordInput>;
137
+
138
+ const defaultArgs = {
139
+ label: 'Enter your name',
140
+ name: 'first_name',
141
+ placeholder: 'Please enter a value',
142
+ } as PasswordInputProps;
143
+
144
+ export const Default: Story = {
145
+ args: {
146
+ isRequired: false,
147
+ helpText: 'This Is Help Text',
148
+ label: 'Label Name',
149
+ name: 'first_name',
150
+ placeholder: 'Please enter a value',
151
+ hasHiddenLabel: false,
152
+ hasShowPassword: true,
153
+ isDisabled: false,
154
+ errorMessage: '',
155
+ },
156
+ render: (args) => {
157
+ const [value, setValue] = useState('');
158
+
159
+ useEffect(() => {
160
+ setValue(args.value || '');
161
+ }, [args.value]);
162
+
163
+ const handleChange = (e: { target: { value: SetStateAction<string> } }) => {
164
+ setValue(e.target.value);
165
+ };
166
+ return <PasswordInput {...args} value={value} onChange={handleChange} />;
167
+ },
168
+ };
169
+
170
+ export const Errors: Story = {
171
+ args: {
172
+ ...defaultArgs,
173
+ errorMessage: 'You require a password value.',
174
+ },
175
+ render: (args) => {
176
+ const [value, setValue] = useState('');
177
+
178
+ useEffect(() => {
179
+ setValue(args.value || '');
180
+ }, [args.value]);
181
+
182
+ const handleChange = (e: { target: { value: SetStateAction<string> } }) => {
183
+ setValue(e.target.value);
184
+ };
185
+
186
+ return <PasswordInput {...args} value={value} onChange={handleChange} />;
187
+ },
188
+ };
189
+
190
+ export const HiddenLabel: Story = {
191
+ args: {
192
+ ...defaultArgs,
193
+ hasHiddenLabel: true,
194
+ },
195
+ render: (args) => {
196
+ const [value, setValue] = useState('');
197
+
198
+ useEffect(() => {
199
+ setValue(args.value || '');
200
+ }, [args.value]);
201
+
202
+ const handleChange = (e: { target: { value: SetStateAction<string> } }) => {
203
+ setValue(e.target.value);
204
+ };
205
+
206
+ return <PasswordInput {...args} value={value} onChange={handleChange} />;
207
+ },
208
+ };
209
+
210
+ export const HelpText: Story = {
211
+ args: {
212
+ ...defaultArgs,
213
+ helpText: 'In order to submit the form, this field is required.',
214
+ },
215
+ render: (args) => {
216
+ const [value, setValue] = useState('');
217
+
218
+ useEffect(() => {
219
+ setValue(args.value || '');
220
+ }, [args.value]);
221
+
222
+ const handleChange = (e: { target: { value: SetStateAction<string> } }) => {
223
+ setValue(e.target.value);
224
+ };
225
+
226
+ return <PasswordInput {...args} value={value} onChange={handleChange} />;
227
+ },
228
+ };
229
+
230
+ export const Required: Story = {
231
+ args: {
232
+ ...defaultArgs,
233
+ isRequired: true,
234
+ },
235
+ render: (args) => {
236
+ const [value, setValue] = useState('');
237
+
238
+ useEffect(() => {
239
+ setValue(args.value || '');
240
+ }, [args.value]);
241
+
242
+ const handleChange = (e: { target: { value: SetStateAction<string> } }) => {
243
+ setValue(e.target.value);
244
+ };
245
+
246
+ return <PasswordInput {...args} value={value} onChange={handleChange} />;
247
+ },
248
+ };
249
+
250
+ export const NoTogglePasswordVisibility: Story = {
251
+ args: {
252
+ ...defaultArgs,
253
+ hasShowPassword: false,
254
+ },
255
+ render: (args) => {
256
+ const [value, setValue] = useState('');
257
+
258
+ useEffect(() => {
259
+ setValue(args.value || '');
260
+ }, [args.value]);
261
+
262
+ const handleChange = (e: { target: { value: SetStateAction<string> } }) => {
263
+ setValue(e.target.value);
264
+ };
265
+
266
+ return <PasswordInput {...args} value={value} onChange={handleChange} />;
267
+ },
268
+ };
@@ -0,0 +1,86 @@
1
+ import React, { useState } from 'react';
2
+ import { Icon } from '@/components/icons';
3
+ import { Label } from '../subcomponents/Label';
4
+ import { DisplayFormError } from '../subcomponents/DisplayFormError';
5
+
6
+ export interface PasswordInputProps {
7
+ ref?: React.LegacyRef<HTMLInputElement>;
8
+ label: string;
9
+ value?: string | undefined;
10
+ name: string;
11
+ placeholder: string;
12
+ onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
13
+ isRequired?: boolean;
14
+ isDisabled?: boolean;
15
+ errorMessage?: string | undefined;
16
+ helpText?: string;
17
+ hasHiddenLabel?: boolean;
18
+ hasShowPassword?: boolean;
19
+ defaultValue?: string;
20
+ }
21
+
22
+ export const PasswordInput = React.forwardRef<HTMLInputElement, PasswordInputProps>(
23
+ (
24
+ {
25
+ label,
26
+ name,
27
+ placeholder,
28
+ onChange,
29
+ isRequired,
30
+ isDisabled,
31
+ errorMessage,
32
+ helpText,
33
+ hasHiddenLabel,
34
+ hasShowPassword = true,
35
+ ...rest
36
+ },
37
+ ref,
38
+ ) => {
39
+ const hasErrors = errorMessage && errorMessage.length > 0;
40
+
41
+ const [showPassword, setShowPassword] = useState(false);
42
+
43
+ const handleShowPassword = () => {
44
+ setShowPassword((prevShowPassword) => !prevShowPassword);
45
+ };
46
+
47
+ return (
48
+ <div className="form-control">
49
+ <Label label={label} name={name} isRequired={isRequired} hasHiddenLabel={hasHiddenLabel} />
50
+ <div className="password-input-wrapper">
51
+ <Icon name="lock" data-testid={`${name}-embedded-icon`} className="embedded-icon" />
52
+ <input
53
+ ref={ref}
54
+ data-testid={`form-password-input-${name}`}
55
+ name={name}
56
+ type={showPassword ? 'text' : 'password'}
57
+ disabled={isDisabled}
58
+ placeholder={placeholder}
59
+ onChange={onChange}
60
+ className={`password-input ${hasErrors ? 'error' : ''} password-input--has-icon`}
61
+ aria-invalid={hasErrors ? 'true' : 'false'}
62
+ aria-describedby={hasErrors || helpText ? `${name}-helper` : undefined}
63
+ aria-required={isRequired}
64
+ aria-label={label}
65
+ {...rest}
66
+ />
67
+ {hasShowPassword && (
68
+ <Icon
69
+ name={showPassword ? 'fa-eye-slash' : 'eye'}
70
+ data-testid={`${name}-${showPassword ? 'hide' : 'show'}-password-icon`}
71
+ size="md"
72
+ onClick={handleShowPassword}
73
+ className="toggle-show-password-icon"
74
+ />
75
+ )}
76
+ </div>
77
+ {hasErrors && <DisplayFormError message={errorMessage} />}
78
+ {helpText && (
79
+ <div data-testid={`${name}-help-text`} className="help-text" id={`${name}-helper`}>
80
+ {helpText}
81
+ </div>
82
+ )}
83
+ </div>
84
+ );
85
+ },
86
+ );