@indico-data/design-system 2.10.0 → 2.12.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.
- package/lib/index.css +99 -8
- package/lib/index.d.ts +47 -15
- package/lib/index.esm.css +99 -8
- package/lib/index.esm.js +61 -28
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +62 -27
- package/lib/index.js.map +1 -1
- package/lib/src/components/forms/checkbox/Checkbox.d.ts +2 -1
- package/lib/src/components/forms/form/Form.d.ts +14 -0
- package/lib/src/components/forms/form/Form.stories.d.ts +8 -0
- package/lib/src/components/forms/form/index.d.ts +1 -0
- package/lib/src/components/forms/input/Input.d.ts +4 -4
- package/lib/src/components/forms/passwordInput/PasswordInput.d.ts +4 -3
- package/lib/src/components/forms/radio/Radio.d.ts +2 -1
- package/lib/src/components/forms/select/Select.d.ts +6 -0
- package/lib/src/components/forms/select/Select.stories.d.ts +7 -0
- package/lib/src/components/forms/select/__tests__/Select.test.d.ts +1 -0
- package/lib/src/components/forms/select/index.d.ts +1 -0
- package/lib/src/components/forms/select/types.d.ts +6 -0
- package/lib/src/components/forms/subcomponents/DisplayFormError.d.ts +5 -0
- package/lib/src/components/forms/textarea/Textarea.d.ts +4 -3
- package/lib/src/components/forms/toggle/Toggle.d.ts +2 -1
- package/lib/src/components/index.d.ts +2 -0
- package/lib/src/index.d.ts +2 -0
- package/lib/src/types.d.ts +2 -0
- package/package.json +5 -2
- package/src/components/forms/checkbox/Checkbox.stories.tsx +2 -2
- package/src/components/forms/checkbox/Checkbox.tsx +32 -41
- package/src/components/forms/form/Form.mdx +134 -0
- package/src/components/forms/form/Form.stories.tsx +413 -0
- package/src/components/forms/form/Form.tsx +64 -0
- package/src/components/forms/form/__tests__/Form.test.tsx +35 -0
- package/src/components/forms/form/index.ts +1 -0
- package/src/components/forms/form/styles/Form.scss +3 -0
- package/src/components/forms/input/Input.tsx +66 -65
- package/src/components/forms/input/__tests__/Input.test.tsx +2 -13
- package/src/components/forms/input/styles/Input.scss +1 -8
- package/src/components/forms/passwordInput/PasswordInput.stories.tsx +11 -12
- package/src/components/forms/passwordInput/PasswordInput.tsx +63 -59
- package/src/components/forms/passwordInput/__tests__/PasswordInput.test.tsx +1 -1
- package/src/components/forms/radio/Radio.tsx +32 -35
- package/src/components/forms/select/Select.stories.tsx +118 -0
- package/src/components/forms/select/Select.tsx +43 -0
- package/src/components/forms/select/__tests__/Select.test.tsx +67 -0
- package/src/components/forms/select/index.ts +1 -0
- package/src/components/forms/select/styles/Select.scss +120 -0
- package/src/components/forms/select/types.ts +6 -0
- package/src/components/forms/subcomponents/DisplayFormError.tsx +7 -0
- package/src/components/forms/textarea/Textarea.stories.tsx +15 -21
- package/src/components/forms/textarea/Textarea.tsx +64 -62
- package/src/components/forms/textarea/__tests__/Textarea.test.tsx +1 -1
- package/src/components/forms/textarea/styles/Textarea.scss +1 -1
- package/src/components/forms/toggle/Toggle.tsx +30 -37
- package/src/components/index.ts +2 -0
- package/src/index.ts +2 -0
- package/src/styles/index.scss +3 -1
- package/src/types.ts +3 -0
- package/lib/src/components/forms/subcomponents/ErrorList.d.ts +0 -6
- package/src/components/forms/subcomponents/ErrorList.tsx +0 -14
- package/src/components/forms/subcomponents/__tests__/ErrorList.test.tsx +0 -16
- /package/lib/src/components/forms/{subcomponents/__tests__/ErrorList.test.d.ts → form/__tests__/Form.test.d.ts} +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// Common Variables
|
|
2
|
+
:root,
|
|
3
|
+
:root [data-theme='light'] {
|
|
4
|
+
--pf-select-background-color: var(--pf-white-color);
|
|
5
|
+
--pf-select-border-color: var(--pf-gray-color);
|
|
6
|
+
--pf-select-text-color: var(--pf-gray-color);
|
|
7
|
+
--pf-select-indicator-color: var(--pf-gray-color);
|
|
8
|
+
--pf-select-placeholder-text-color: var(--pf-gray-color);
|
|
9
|
+
--pf-select-hover-color: var(--pf-gray-color);
|
|
10
|
+
--pf-select-option-selected-color: var(--pf-primary-color-200);
|
|
11
|
+
--pf-select-option-text-color: var(--pf-gray-color);
|
|
12
|
+
--pf-select-option-hover-color: var(--pf-primary-color-100);
|
|
13
|
+
|
|
14
|
+
// Disabled
|
|
15
|
+
--pf-select-disabled-background-color: var(--pf-gray-color-100);
|
|
16
|
+
--pf-select-disabled-color: var(--pf-gray-color-400);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Dark Theme Specific Variables
|
|
20
|
+
:root [data-theme='dark'] {
|
|
21
|
+
--pf-select-background-color: var(--pf-primary-color);
|
|
22
|
+
--pf-select-border-color: var(--pf-gray-color-100);
|
|
23
|
+
--pf-select-text-color: var(--pf-gray-color-100);
|
|
24
|
+
--pf-select-indicator-color: var(--pf-gray-color-100);
|
|
25
|
+
--pf-select-placeholder-text-color: var(--pf-gray-color-100);
|
|
26
|
+
--pf-select-hover-color: var(--pf-gray-color-100);
|
|
27
|
+
--pf-select-option-selected-color: var(--pf-primary-color-200);
|
|
28
|
+
--pf-select-option-text-color: var(--pf-gray-color-100);
|
|
29
|
+
--pf-select-option-hover-color: var(--pf-primary-color-300);
|
|
30
|
+
|
|
31
|
+
// Disabled
|
|
32
|
+
--pf-select-disabled-background-color: var(--pf-primary-color-200);
|
|
33
|
+
--pf-select-disabled-color: var(--pf-gray-color-400);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
.select-wrapper {
|
|
37
|
+
.select__ {
|
|
38
|
+
&control {
|
|
39
|
+
background-color: var(--pf-select-background-color);
|
|
40
|
+
border: 1px solid var(--pf-select-border-color);
|
|
41
|
+
color: var(--pf-select-text-color);
|
|
42
|
+
box-shadow: none;
|
|
43
|
+
|
|
44
|
+
&:hover,
|
|
45
|
+
&:focus,
|
|
46
|
+
&--is-focused {
|
|
47
|
+
border: 1px solid var(--pf-select-hover-color);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&--is-disabled {
|
|
51
|
+
background-color: var(--pf-select-disabled-background-color);
|
|
52
|
+
color: var(--pf-select-disabled-color);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
&placeholder {
|
|
57
|
+
color: var(--pf-select-placeholder-text-color);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
&value-container {
|
|
61
|
+
cursor: text;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
&input-container {
|
|
65
|
+
color: var(--pf-select-text-color);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&menu {
|
|
69
|
+
border: 1px solid var(--pf-select-border-color);
|
|
70
|
+
box-shadow: 0px 1px 8px 0px rgba(0, 0, 0, 0.4);
|
|
71
|
+
margin: 4px 0px;
|
|
72
|
+
background-color: var(--pf-select-background-color);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
&menu-notice {
|
|
76
|
+
color: var(--pf-select-text-color);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&indicator-separator {
|
|
80
|
+
background-color: var(--pf-select-indicator-color);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
&indicator {
|
|
84
|
+
cursor: pointer;
|
|
85
|
+
color: var(--pf-select-indicator-color);
|
|
86
|
+
|
|
87
|
+
&:hover,
|
|
88
|
+
&:focus {
|
|
89
|
+
color: var(--pf-select-hover-color);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
&items {
|
|
94
|
+
display: flex;
|
|
95
|
+
align-items: center;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&item-detail {
|
|
99
|
+
margin-left: auto;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&option {
|
|
103
|
+
cursor: pointer;
|
|
104
|
+
overflow-wrap: break-word;
|
|
105
|
+
color: var(--pf-select-option-text-color);
|
|
106
|
+
&--is-focused,
|
|
107
|
+
&:active {
|
|
108
|
+
background: var(--pf-select-option-hover-color);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
&--is-selected {
|
|
112
|
+
background: var(--pf-select-option-selected-color);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
&single-value {
|
|
117
|
+
color: var(--pf-select-option-text-color);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
@@ -83,7 +83,7 @@ const meta: Meta = {
|
|
|
83
83
|
},
|
|
84
84
|
defaultValue: { summary: 'false' },
|
|
85
85
|
},
|
|
86
|
-
|
|
86
|
+
errorMessage: {
|
|
87
87
|
control: false,
|
|
88
88
|
description: 'An array of error messages',
|
|
89
89
|
table: {
|
|
@@ -214,8 +214,7 @@ export const Default: Story = {
|
|
|
214
214
|
placeholder: 'Please enter a value',
|
|
215
215
|
hasHiddenLabel: false,
|
|
216
216
|
isDisabled: false,
|
|
217
|
-
|
|
218
|
-
value: '',
|
|
217
|
+
errorMessage: '',
|
|
219
218
|
readonly: false,
|
|
220
219
|
cols: 0,
|
|
221
220
|
rows: 0,
|
|
@@ -228,10 +227,10 @@ export const Default: Story = {
|
|
|
228
227
|
const [value, setValue] = useState(args.value);
|
|
229
228
|
|
|
230
229
|
useEffect(() => {
|
|
231
|
-
setValue(args.value);
|
|
230
|
+
setValue(args.value || '');
|
|
232
231
|
}, [args.value]);
|
|
233
232
|
|
|
234
|
-
const handleChange = (e:
|
|
233
|
+
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
235
234
|
setValue(e.target.value);
|
|
236
235
|
};
|
|
237
236
|
|
|
@@ -247,17 +246,16 @@ export const Errors: Story = {
|
|
|
247
246
|
placeholder: 'Please enter a value',
|
|
248
247
|
hasHiddenLabel: false,
|
|
249
248
|
isDisabled: false,
|
|
250
|
-
|
|
251
|
-
value: '',
|
|
249
|
+
errorMessage: 'This Is An Error',
|
|
252
250
|
},
|
|
253
251
|
render: (args) => {
|
|
254
252
|
const [value, setValue] = useState(args.value);
|
|
255
253
|
|
|
256
254
|
useEffect(() => {
|
|
257
|
-
setValue(args.value);
|
|
255
|
+
setValue(args.value || '');
|
|
258
256
|
}, [args.value]);
|
|
259
257
|
|
|
260
|
-
const handleChange = (e:
|
|
258
|
+
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
261
259
|
setValue(e.target.value);
|
|
262
260
|
};
|
|
263
261
|
|
|
@@ -273,16 +271,15 @@ export const HiddenLabel: Story = {
|
|
|
273
271
|
placeholder: 'Please enter a value',
|
|
274
272
|
hasHiddenLabel: true,
|
|
275
273
|
isDisabled: false,
|
|
276
|
-
value: '',
|
|
277
274
|
},
|
|
278
275
|
render: (args) => {
|
|
279
276
|
const [value, setValue] = useState(args.value);
|
|
280
277
|
|
|
281
278
|
useEffect(() => {
|
|
282
|
-
setValue(args.value);
|
|
279
|
+
setValue(args.value || '');
|
|
283
280
|
}, [args.value]);
|
|
284
281
|
|
|
285
|
-
const handleChange = (e:
|
|
282
|
+
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
286
283
|
setValue(e.target.value);
|
|
287
284
|
};
|
|
288
285
|
|
|
@@ -297,16 +294,15 @@ export const HelpText: Story = {
|
|
|
297
294
|
name: 'textarea',
|
|
298
295
|
placeholder: 'Please enter a value',
|
|
299
296
|
isDisabled: false,
|
|
300
|
-
value: '',
|
|
301
297
|
},
|
|
302
298
|
render: (args) => {
|
|
303
299
|
const [value, setValue] = useState(args.value);
|
|
304
300
|
|
|
305
301
|
useEffect(() => {
|
|
306
|
-
setValue(args.value);
|
|
302
|
+
setValue(args.value || '');
|
|
307
303
|
}, [args.value]);
|
|
308
304
|
|
|
309
|
-
const handleChange = (e:
|
|
305
|
+
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
310
306
|
setValue(e.target.value);
|
|
311
307
|
};
|
|
312
308
|
|
|
@@ -321,16 +317,15 @@ export const Disabled: Story = {
|
|
|
321
317
|
name: 'textarea',
|
|
322
318
|
placeholder: 'Please enter a value',
|
|
323
319
|
isDisabled: true,
|
|
324
|
-
value: '',
|
|
325
320
|
},
|
|
326
321
|
render: (args) => {
|
|
327
322
|
const [value, setValue] = useState(args.value);
|
|
328
323
|
|
|
329
324
|
useEffect(() => {
|
|
330
|
-
setValue(args.value);
|
|
325
|
+
setValue(args.value || '');
|
|
331
326
|
}, [args.value]);
|
|
332
327
|
|
|
333
|
-
const handleChange = (e:
|
|
328
|
+
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
334
329
|
setValue(e.target.value);
|
|
335
330
|
};
|
|
336
331
|
|
|
@@ -344,17 +339,16 @@ export const Readonly: Story = {
|
|
|
344
339
|
label: 'Label Name',
|
|
345
340
|
name: 'textarea',
|
|
346
341
|
placeholder: 'Please enter a value',
|
|
347
|
-
value: '',
|
|
348
342
|
readonly: true,
|
|
349
343
|
},
|
|
350
344
|
render: (args) => {
|
|
351
345
|
const [value, setValue] = useState(args.value);
|
|
352
346
|
|
|
353
347
|
useEffect(() => {
|
|
354
|
-
setValue(args.value);
|
|
348
|
+
setValue(args.value || '');
|
|
355
349
|
}, [args.value]);
|
|
356
350
|
|
|
357
|
-
const handleChange = (e:
|
|
351
|
+
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
|
358
352
|
setValue(e.target.value);
|
|
359
353
|
};
|
|
360
354
|
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Label } from '../subcomponents/Label';
|
|
3
|
-
import {
|
|
3
|
+
import { DisplayFormError } from '../subcomponents/DisplayFormError';
|
|
4
4
|
|
|
5
5
|
export interface TextareaProps {
|
|
6
6
|
ref?: React.LegacyRef<HTMLTextAreaElement>;
|
|
7
7
|
label: string;
|
|
8
8
|
name: string;
|
|
9
9
|
placeholder: string;
|
|
10
|
-
value
|
|
10
|
+
value?: string | undefined;
|
|
11
11
|
onChange: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
|
|
12
12
|
isRequired?: boolean;
|
|
13
13
|
isDisabled?: boolean;
|
|
14
|
-
|
|
14
|
+
errorMessage?: string | undefined;
|
|
15
15
|
helpText?: string;
|
|
16
16
|
hasHiddenLabel?: boolean;
|
|
17
17
|
rows?: number;
|
|
@@ -21,65 +21,67 @@ export interface TextareaProps {
|
|
|
21
21
|
form?: string;
|
|
22
22
|
maxLength?: number;
|
|
23
23
|
autofocus?: boolean;
|
|
24
|
+
defaultValue?: string;
|
|
24
25
|
}
|
|
26
|
+
export const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
27
|
+
(
|
|
28
|
+
{
|
|
29
|
+
label,
|
|
30
|
+
name,
|
|
31
|
+
placeholder,
|
|
32
|
+
value,
|
|
33
|
+
onChange,
|
|
34
|
+
isRequired,
|
|
35
|
+
isDisabled,
|
|
36
|
+
errorMessage,
|
|
37
|
+
helpText,
|
|
38
|
+
hasHiddenLabel,
|
|
39
|
+
rows,
|
|
40
|
+
cols,
|
|
41
|
+
readonly,
|
|
42
|
+
wrap,
|
|
43
|
+
form,
|
|
44
|
+
maxLength,
|
|
45
|
+
autofocus,
|
|
46
|
+
...rest
|
|
47
|
+
},
|
|
48
|
+
ref,
|
|
49
|
+
) => {
|
|
50
|
+
const hasErrors = errorMessage && errorMessage.length > 0;
|
|
25
51
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
<Label label={label} name={name} isRequired={isRequired} hasHiddenLabel={hasHiddenLabel} />
|
|
52
|
-
<div className="textarea-wrapper">
|
|
53
|
-
<textarea
|
|
54
|
-
ref={ref}
|
|
55
|
-
rows={rows}
|
|
56
|
-
cols={cols}
|
|
57
|
-
autoFocus={autofocus}
|
|
58
|
-
wrap={wrap}
|
|
59
|
-
form={form}
|
|
60
|
-
value={value}
|
|
61
|
-
maxLength={maxLength}
|
|
62
|
-
readOnly={readonly}
|
|
63
|
-
data-testid={`form-textarea-${name}`}
|
|
64
|
-
name={name}
|
|
65
|
-
disabled={isDisabled}
|
|
66
|
-
required={isRequired}
|
|
67
|
-
placeholder={placeholder}
|
|
68
|
-
onChange={onChange}
|
|
69
|
-
className={`textarea ${hasErrors ? 'error' : ''}`}
|
|
70
|
-
aria-invalid={hasErrors}
|
|
71
|
-
aria-describedby={hasErrors || helpText ? `${name}-helper` : undefined}
|
|
72
|
-
aria-required={isRequired}
|
|
73
|
-
aria-label={label}
|
|
74
|
-
{...rest}
|
|
75
|
-
/>
|
|
76
|
-
</div>
|
|
77
|
-
{hasErrors && <ErrorList errorList={errorList} name={name} />}
|
|
78
|
-
{helpText && (
|
|
79
|
-
<div data-testid={`${name}-help-text`} className="help-text" id={`${name}-helper`}>
|
|
80
|
-
{helpText}
|
|
52
|
+
return (
|
|
53
|
+
<div className="form-control">
|
|
54
|
+
<Label label={label} name={name} isRequired={isRequired} hasHiddenLabel={hasHiddenLabel} />
|
|
55
|
+
<div className="textarea-wrapper">
|
|
56
|
+
<textarea
|
|
57
|
+
ref={ref}
|
|
58
|
+
rows={rows}
|
|
59
|
+
cols={cols}
|
|
60
|
+
autoFocus={autofocus}
|
|
61
|
+
wrap={wrap}
|
|
62
|
+
form={form}
|
|
63
|
+
maxLength={maxLength}
|
|
64
|
+
readOnly={readonly}
|
|
65
|
+
data-testid={`form-textarea-${name}`}
|
|
66
|
+
name={name}
|
|
67
|
+
disabled={isDisabled}
|
|
68
|
+
placeholder={placeholder}
|
|
69
|
+
onChange={onChange}
|
|
70
|
+
className={`textarea ${hasErrors ? 'error' : ''}`}
|
|
71
|
+
aria-invalid={hasErrors ? true : undefined}
|
|
72
|
+
aria-describedby={hasErrors || helpText ? `${name}-helper` : undefined}
|
|
73
|
+
aria-required={isRequired}
|
|
74
|
+
aria-label={label}
|
|
75
|
+
{...rest}
|
|
76
|
+
/>
|
|
81
77
|
</div>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
78
|
+
{hasErrors && <DisplayFormError message={errorMessage} />}
|
|
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
|
+
);
|
|
@@ -25,7 +25,7 @@ describe('Textarea', () => {
|
|
|
25
25
|
render(
|
|
26
26
|
<Textarea
|
|
27
27
|
isRequired={true}
|
|
28
|
-
|
|
28
|
+
errorMessage="You require a username value."
|
|
29
29
|
label="Enter your name"
|
|
30
30
|
helpText="In order to submit the form, this field is required."
|
|
31
31
|
name="name"
|
|
@@ -9,43 +9,36 @@ export interface ToggleProps {
|
|
|
9
9
|
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
10
10
|
isDisabled?: boolean;
|
|
11
11
|
isChecked?: boolean;
|
|
12
|
+
defaultChecked?: boolean;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
export const Toggle = (
|
|
15
|
-
ref
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
aria-describedby={id}
|
|
41
|
-
aria-label={label}
|
|
42
|
-
{...rest}
|
|
43
|
-
/>
|
|
44
|
-
<label htmlFor={id} className="switch"></label>
|
|
45
|
-
<label className={'toggle-label'} htmlFor={id}>
|
|
46
|
-
{label}
|
|
47
|
-
</label>
|
|
15
|
+
export const Toggle = React.forwardRef<HTMLInputElement, ToggleProps>(
|
|
16
|
+
({ id, label, name, value, onChange, isDisabled, isChecked, ...rest }, ref) => {
|
|
17
|
+
return (
|
|
18
|
+
<div className="form-control">
|
|
19
|
+
<div className="toggle-wrapper">
|
|
20
|
+
<input
|
|
21
|
+
data-testid={`form-toggle-input-${name}`}
|
|
22
|
+
className="toggle-input"
|
|
23
|
+
type="checkbox"
|
|
24
|
+
id={id}
|
|
25
|
+
checked={isChecked}
|
|
26
|
+
name={name}
|
|
27
|
+
value={value}
|
|
28
|
+
disabled={isDisabled}
|
|
29
|
+
ref={ref}
|
|
30
|
+
onChange={onChange}
|
|
31
|
+
tabIndex={0}
|
|
32
|
+
aria-describedby={id}
|
|
33
|
+
aria-label={label}
|
|
34
|
+
{...rest}
|
|
35
|
+
/>
|
|
36
|
+
<label htmlFor={id} className="switch"></label>
|
|
37
|
+
<label className={'toggle-label'} htmlFor={id}>
|
|
38
|
+
{label}
|
|
39
|
+
</label>
|
|
40
|
+
</div>
|
|
48
41
|
</div>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
);
|
|
43
|
+
},
|
|
44
|
+
);
|
package/src/components/index.ts
CHANGED
|
@@ -8,3 +8,5 @@ export { Checkbox } from './forms/checkbox';
|
|
|
8
8
|
export { Toggle } from './forms/toggle';
|
|
9
9
|
export { Textarea } from './forms/textarea';
|
|
10
10
|
export { PasswordInput } from './forms/passwordInput';
|
|
11
|
+
export { Select } from './forms/select';
|
|
12
|
+
export { Form } from './forms/form';
|
package/src/index.ts
CHANGED
|
@@ -67,3 +67,5 @@ export { Checkbox } from './components/forms/checkbox';
|
|
|
67
67
|
export { Toggle as ToggleInput } from './components/forms/toggle';
|
|
68
68
|
export { Textarea } from './components/forms/textarea';
|
|
69
69
|
export { PasswordInput } from './components/forms/passwordInput';
|
|
70
|
+
export { Select as SelectInput } from './components/forms/select';
|
|
71
|
+
export { Form } from './components/forms/form';
|
package/src/styles/index.scss
CHANGED
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
@import '../components/forms/checkbox/styles/Checkbox.scss';
|
|
12
12
|
@import '../components/forms/textarea/styles/Textarea.scss';
|
|
13
13
|
@import '../components/forms/passwordInput/styles/PasswordInput.scss';
|
|
14
|
-
|
|
14
|
+
@import '../components/forms/form/styles/Form.scss';
|
|
15
|
+
@import '../components/forms/select/styles/Select.scss';
|
|
15
16
|
@import '../components/forms/toggle/styles/Toggle.scss';
|
|
17
|
+
|
|
16
18
|
@import 'typography';
|
|
17
19
|
@import 'colors';
|
|
18
20
|
@import 'borders';
|
package/src/types.ts
CHANGED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
interface ErrorListProps {
|
|
2
|
-
name: string;
|
|
3
|
-
errorList: string[];
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export const ErrorList = ({ errorList, name }: ErrorListProps) => {
|
|
7
|
-
return (
|
|
8
|
-
<ul className="error-list" id={`${name}-helper`}>
|
|
9
|
-
{(errorList ?? []).map((error, index) => (
|
|
10
|
-
<li key={index}>{error}</li>
|
|
11
|
-
))}
|
|
12
|
-
</ul>
|
|
13
|
-
);
|
|
14
|
-
};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import { ErrorList } from '@/components/forms/subcomponents/ErrorList';
|
|
3
|
-
|
|
4
|
-
describe('ErrorList', () => {
|
|
5
|
-
it('renders the error list', () => {
|
|
6
|
-
render(<ErrorList name="name" errorList={['error1', 'error2']} />);
|
|
7
|
-
expect(screen.getByText('error1')).toBeInTheDocument();
|
|
8
|
-
expect(screen.getByText('error2')).toBeInTheDocument();
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
it('does not render the error list when it is empty', () => {
|
|
12
|
-
render(<ErrorList name="name" errorList={[]} />);
|
|
13
|
-
expect(screen.queryByText('error1')).not.toBeInTheDocument();
|
|
14
|
-
expect(screen.queryByText('error2')).not.toBeInTheDocument();
|
|
15
|
-
});
|
|
16
|
-
});
|
|
File without changes
|