@popsure/dirty-swan 0.57.8 → 0.58.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/dist/cjs/index.js +98 -63
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/components/input/checkbox/index.d.ts +2 -1
- package/dist/cjs/lib/components/input/checkbox/index.stories.d.ts +11 -7
- package/dist/cjs/lib/components/input/radio/index.d.ts +3 -1
- package/dist/cjs/lib/components/input/radio/index.stories.d.ts +10 -2
- package/dist/cjs/lib/components/multiDropzone/utils/index.d.ts +9 -2
- package/dist/esm/{TableSection-a26ba0c5.js → TableSection-ebace923.js} +1 -1
- package/dist/esm/{TableSection-a26ba0c5.js.map → TableSection-ebace923.js.map} +1 -1
- package/dist/esm/components/chip/index.js +2 -2
- package/dist/esm/components/chip/index.js.map +1 -1
- package/dist/esm/components/comparisonTable/components/TableInfoButton/index.js +1 -1
- package/dist/esm/components/comparisonTable/components/TableInfoButton/index.js.map +1 -1
- package/dist/esm/components/input/checkbox/index.js +19 -16
- package/dist/esm/components/input/checkbox/index.js.map +1 -1
- package/dist/esm/components/input/checkbox/index.stories.js +24 -20
- package/dist/esm/components/input/checkbox/index.stories.js.map +1 -1
- package/dist/esm/components/input/index.js +1 -1
- package/dist/esm/components/input/index.js.map +1 -1
- package/dist/esm/components/input/radio/index.js +23 -21
- package/dist/esm/components/input/radio/index.js.map +1 -1
- package/dist/esm/components/input/radio/index.stories.js +12 -3
- package/dist/esm/components/input/radio/index.stories.js.map +1 -1
- package/dist/esm/components/input/radio/index.test.js +1 -0
- package/dist/esm/components/input/radio/index.test.js.map +1 -1
- package/dist/esm/components/multiDropzone/UploadFileCell/index.js +6 -7
- package/dist/esm/components/multiDropzone/UploadFileCell/index.js.map +1 -1
- package/dist/esm/components/multiDropzone/index.js +51 -17
- package/dist/esm/components/multiDropzone/index.js.map +1 -1
- package/dist/esm/components/multiDropzone/index.stories.js +1 -0
- package/dist/esm/components/multiDropzone/index.stories.js.map +1 -1
- package/dist/esm/components/multiDropzone/index.test.js +1 -0
- package/dist/esm/components/multiDropzone/index.test.js.map +1 -1
- package/dist/esm/components/table/Table.js +1 -1
- package/dist/esm/components/table/Table.stories.js +1 -1
- package/dist/esm/components/table/Table.test.js +1 -1
- package/dist/esm/components/table/components/TableContents/TableContents.js +1 -1
- package/dist/esm/components/table/components/TableContents/TableContents.test.js +1 -1
- package/dist/esm/components/table/components/TableSection/TableSection.js +1 -1
- package/dist/esm/components/table/components/TableSection/TableSection.test.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/lib/components/input/checkbox/index.d.ts +2 -1
- package/dist/esm/lib/components/input/checkbox/index.stories.d.ts +11 -7
- package/dist/esm/lib/components/input/radio/index.d.ts +3 -1
- package/dist/esm/lib/components/input/radio/index.stories.d.ts +10 -2
- package/dist/esm/lib/components/multiDropzone/utils/index.d.ts +9 -2
- package/package.json +1 -1
- package/src/lib/components/chip/index.tsx +1 -0
- package/src/lib/components/chip/style.module.scss +5 -0
- package/src/lib/components/comparisonTable/components/TableInfoButton/index.tsx +2 -0
- package/src/lib/components/input/checkbox/index.stories.tsx +81 -58
- package/src/lib/components/input/checkbox/index.tsx +11 -2
- package/src/lib/components/input/checkbox/styles.module.scss +4 -0
- package/src/lib/components/input/index.tsx +2 -0
- package/src/lib/components/input/radio/index.stories.tsx +17 -2
- package/src/lib/components/input/radio/index.tsx +11 -2
- package/src/lib/components/input/radio/styles.module.scss +5 -1
- package/src/lib/components/multiDropzone/UploadFileCell/index.tsx +25 -19
- package/src/lib/components/multiDropzone/UploadFileCell/style.module.scss +11 -29
- package/src/lib/components/multiDropzone/index.tsx +17 -5
- package/src/lib/components/multiDropzone/style.module.scss +12 -9
- package/src/lib/components/multiDropzone/utils/index.test.ts +128 -45
- package/src/lib/components/multiDropzone/utils/index.ts +89 -36
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import { useState } from 'react';
|
|
3
2
|
import { Checkbox, CheckboxProps } from '.';
|
|
4
3
|
import { images } from '../../../util/images';
|
|
@@ -9,28 +8,36 @@ const story = {
|
|
|
9
8
|
component: Checkbox,
|
|
10
9
|
argTypes: {
|
|
11
10
|
options: {
|
|
12
|
-
description:
|
|
11
|
+
description:
|
|
12
|
+
'Object that contains the possible options for rendering in the input.',
|
|
13
13
|
},
|
|
14
14
|
value: {
|
|
15
15
|
description: 'Current checked values.',
|
|
16
16
|
},
|
|
17
|
+
fieldLegend: {
|
|
18
|
+
description:
|
|
19
|
+
'Accessibility property that describes the purpose of a group of checkbox buttons, read aloud by screen readers to provide context.',
|
|
20
|
+
},
|
|
17
21
|
onChange: {
|
|
18
22
|
description: 'Function called everytime a value changes.',
|
|
19
23
|
action: true,
|
|
20
24
|
table: {
|
|
21
|
-
category:
|
|
25
|
+
category: 'Callbacks',
|
|
22
26
|
},
|
|
23
27
|
},
|
|
24
28
|
wide: {
|
|
25
|
-
description:
|
|
26
|
-
|
|
29
|
+
description:
|
|
30
|
+
'Property that defines if options should fill 100% of available horizontal space',
|
|
31
|
+
defaultValue: false,
|
|
27
32
|
},
|
|
28
33
|
bordered: {
|
|
29
34
|
control: 'boolean',
|
|
30
|
-
description:
|
|
35
|
+
description:
|
|
36
|
+
'Property that defines if checkbox should show the border around each label',
|
|
31
37
|
},
|
|
32
38
|
inlineLayout: {
|
|
33
|
-
description:
|
|
39
|
+
description:
|
|
40
|
+
'Property that defines if options should show inline instead of block. Check inline checkbox options story for examples.',
|
|
34
41
|
},
|
|
35
42
|
className: {
|
|
36
43
|
description: 'ClassNames for custom styling',
|
|
@@ -38,133 +45,144 @@ const story = {
|
|
|
38
45
|
},
|
|
39
46
|
args: {
|
|
40
47
|
options: {
|
|
41
|
-
CAT:{
|
|
48
|
+
CAT: {
|
|
42
49
|
title: 'Cat',
|
|
43
|
-
description: 'At least 1'
|
|
50
|
+
description: 'At least 1',
|
|
44
51
|
},
|
|
45
|
-
DOG:{
|
|
52
|
+
DOG: {
|
|
46
53
|
title: 'Dog',
|
|
47
|
-
description: 'At least 2'
|
|
54
|
+
description: 'At least 2',
|
|
48
55
|
},
|
|
49
|
-
NONE:{
|
|
56
|
+
NONE: {
|
|
50
57
|
title: 'None',
|
|
51
|
-
description: 'No pets'
|
|
52
|
-
}
|
|
58
|
+
description: 'No pets',
|
|
59
|
+
},
|
|
53
60
|
},
|
|
61
|
+
fieldLegend: 'Owned pets',
|
|
54
62
|
wide: false,
|
|
55
63
|
bordered: true,
|
|
56
64
|
inlineLayout: false,
|
|
57
65
|
classNames: {
|
|
58
66
|
container: '',
|
|
59
67
|
label: '',
|
|
60
|
-
option: ''
|
|
68
|
+
option: '',
|
|
61
69
|
},
|
|
62
70
|
value: [],
|
|
63
|
-
className: ''
|
|
64
|
-
}
|
|
71
|
+
className: '',
|
|
72
|
+
},
|
|
65
73
|
};
|
|
66
74
|
|
|
67
|
-
export const CheckboxStory = ({
|
|
75
|
+
export const CheckboxStory = ({
|
|
68
76
|
onChange,
|
|
69
77
|
options,
|
|
70
78
|
wide,
|
|
71
79
|
bordered,
|
|
72
80
|
classNames,
|
|
73
81
|
inlineLayout,
|
|
82
|
+
fieldLegend,
|
|
74
83
|
}: CheckboxProps<string>) => {
|
|
75
84
|
const [checkedValues, setCheckedValues] = useState<string[]>([]);
|
|
76
85
|
|
|
77
86
|
const handleOnChange = (newValue: string[]) => {
|
|
78
87
|
setCheckedValues(newValue);
|
|
79
88
|
onChange(newValue);
|
|
80
|
-
}
|
|
89
|
+
};
|
|
81
90
|
|
|
82
91
|
return (
|
|
83
|
-
<Checkbox
|
|
92
|
+
<Checkbox
|
|
84
93
|
wide={wide}
|
|
85
|
-
options={options}
|
|
94
|
+
options={options}
|
|
86
95
|
onChange={handleOnChange}
|
|
87
96
|
value={checkedValues}
|
|
88
97
|
bordered={bordered}
|
|
89
98
|
classNames={classNames}
|
|
90
99
|
inlineLayout={inlineLayout}
|
|
100
|
+
fieldLegend={fieldLegend}
|
|
91
101
|
/>
|
|
92
102
|
);
|
|
93
|
-
}
|
|
103
|
+
};
|
|
94
104
|
|
|
95
|
-
export const CheckboxWithCustomWrapperStyles = ({
|
|
105
|
+
export const CheckboxWithCustomWrapperStyles = ({
|
|
106
|
+
onChange,
|
|
107
|
+
}: CheckboxProps<string>) => {
|
|
96
108
|
const [checkedValues, setCheckedValues] = useState<string[]>([]);
|
|
97
109
|
|
|
98
110
|
const handleOnChange = (newValue: string[] = []) => {
|
|
99
111
|
setCheckedValues(newValue);
|
|
100
112
|
onChange(newValue);
|
|
101
|
-
}
|
|
113
|
+
};
|
|
102
114
|
|
|
103
115
|
return (
|
|
104
|
-
<Checkbox
|
|
116
|
+
<Checkbox
|
|
105
117
|
onChange={handleOnChange}
|
|
106
118
|
value={checkedValues}
|
|
107
119
|
options={{
|
|
108
120
|
CAT1: 'Cat',
|
|
109
121
|
DOG1: 'Dog',
|
|
110
|
-
}}
|
|
111
|
-
classNames={{ container:
|
|
122
|
+
}}
|
|
123
|
+
classNames={{ container: 'p32 bg-primary-300 br24 bs-lg' }}
|
|
112
124
|
/>
|
|
113
125
|
);
|
|
114
|
-
}
|
|
126
|
+
};
|
|
115
127
|
|
|
116
|
-
export const CheckboxWithCustomOptionStyles = ({
|
|
128
|
+
export const CheckboxWithCustomOptionStyles = ({
|
|
129
|
+
onChange,
|
|
130
|
+
}: CheckboxProps<string>) => {
|
|
117
131
|
const [checkedValues, setCheckedValues] = useState<string[]>([]);
|
|
118
132
|
|
|
119
133
|
const handleOnChange = (newValue: string[] = []) => {
|
|
120
134
|
setCheckedValues(newValue);
|
|
121
135
|
onChange(newValue);
|
|
122
|
-
}
|
|
136
|
+
};
|
|
123
137
|
|
|
124
138
|
return (
|
|
125
|
-
<Checkbox
|
|
139
|
+
<Checkbox
|
|
126
140
|
onChange={handleOnChange}
|
|
127
141
|
value={checkedValues}
|
|
128
142
|
options={{
|
|
129
143
|
CAT2: 'Cat',
|
|
130
144
|
DOG2: 'Dog',
|
|
131
|
-
}}
|
|
132
|
-
classNames={{ option:
|
|
145
|
+
}}
|
|
146
|
+
classNames={{ option: 'mb32 p24 bg-green-100 br12 bs-lg' }}
|
|
133
147
|
/>
|
|
134
148
|
);
|
|
135
|
-
}
|
|
149
|
+
};
|
|
136
150
|
|
|
137
|
-
export const CheckboxWithCustomLabelStyles = ({
|
|
151
|
+
export const CheckboxWithCustomLabelStyles = ({
|
|
152
|
+
onChange,
|
|
153
|
+
}: CheckboxProps<string>) => {
|
|
138
154
|
const [checkedValues, setCheckedValues] = useState<string[]>([]);
|
|
139
155
|
|
|
140
156
|
const handleOnChange = (newValue: string[] = []) => {
|
|
141
157
|
setCheckedValues(newValue);
|
|
142
158
|
onChange(newValue);
|
|
143
|
-
}
|
|
159
|
+
};
|
|
144
160
|
|
|
145
161
|
return (
|
|
146
|
-
<Checkbox
|
|
162
|
+
<Checkbox
|
|
147
163
|
onChange={handleOnChange}
|
|
148
164
|
value={checkedValues}
|
|
149
165
|
options={{
|
|
150
166
|
CAT3: 'Cat',
|
|
151
167
|
DOG3: 'Dog',
|
|
152
|
-
}}
|
|
153
|
-
classNames={{ label:
|
|
168
|
+
}}
|
|
169
|
+
classNames={{ label: 'bg-grey-900 tc-white' }}
|
|
154
170
|
/>
|
|
155
171
|
);
|
|
156
|
-
}
|
|
172
|
+
};
|
|
157
173
|
|
|
158
|
-
export const CheckboxWithInlineLayout = ({
|
|
174
|
+
export const CheckboxWithInlineLayout = ({
|
|
175
|
+
onChange,
|
|
176
|
+
}: CheckboxProps<string>) => {
|
|
159
177
|
const [checkedValues, setCheckedValues] = useState<string[]>([]);
|
|
160
178
|
|
|
161
179
|
const handleOnChange = (newValue: string[] = []) => {
|
|
162
180
|
setCheckedValues(newValue);
|
|
163
181
|
onChange(newValue);
|
|
164
|
-
}
|
|
182
|
+
};
|
|
165
183
|
|
|
166
184
|
return (
|
|
167
|
-
<Checkbox
|
|
185
|
+
<Checkbox
|
|
168
186
|
onChange={handleOnChange}
|
|
169
187
|
value={checkedValues}
|
|
170
188
|
options={{
|
|
@@ -174,45 +192,50 @@ export const CheckboxWithInlineLayout = ({ onChange }: CheckboxProps<string>) =>
|
|
|
174
192
|
RABBIT: 'Rabbit',
|
|
175
193
|
RAT: 'Rat',
|
|
176
194
|
ANOTHER: 'Other',
|
|
177
|
-
}}
|
|
178
|
-
classNames={{ option:
|
|
195
|
+
}}
|
|
196
|
+
classNames={{ option: 'w30' }}
|
|
179
197
|
inlineLayout
|
|
180
198
|
wide
|
|
181
199
|
/>
|
|
182
200
|
);
|
|
183
|
-
}
|
|
201
|
+
};
|
|
184
202
|
|
|
185
|
-
export const CheckboxWithCustomLabel = ({
|
|
203
|
+
export const CheckboxWithCustomLabel = ({
|
|
204
|
+
onChange,
|
|
205
|
+
wide,
|
|
206
|
+
classNames,
|
|
207
|
+
inlineLayout,
|
|
208
|
+
}: CheckboxProps<string>) => {
|
|
186
209
|
const [checkedValues, setCheckedValues] = useState<string[]>([]);
|
|
187
210
|
|
|
188
211
|
const handleOnChange = (newValue: string[] = []) => {
|
|
189
212
|
setCheckedValues(newValue);
|
|
190
213
|
onChange(newValue);
|
|
191
|
-
}
|
|
214
|
+
};
|
|
192
215
|
|
|
193
216
|
return (
|
|
194
|
-
<Checkbox
|
|
217
|
+
<Checkbox
|
|
195
218
|
options={{
|
|
196
219
|
BIGDOG: {
|
|
197
|
-
icon: () => <img src={images.bigDog} alt=
|
|
220
|
+
icon: () => <img src={images.bigDog} alt="" />,
|
|
198
221
|
title: 'Dog',
|
|
199
222
|
},
|
|
200
|
-
FISH:{
|
|
201
|
-
icon: () => <img src={images.brokenAquarium} alt=
|
|
223
|
+
FISH: {
|
|
224
|
+
icon: () => <img src={images.brokenAquarium} alt="" />,
|
|
202
225
|
title: 'Fish',
|
|
203
226
|
},
|
|
204
|
-
OTHER:{
|
|
205
|
-
icon: () => <img src={images.brokenGlass} alt=
|
|
227
|
+
OTHER: {
|
|
228
|
+
icon: () => <img src={images.brokenGlass} alt="" />,
|
|
206
229
|
title: 'Other',
|
|
207
|
-
}
|
|
208
|
-
}}
|
|
230
|
+
},
|
|
231
|
+
}}
|
|
209
232
|
onChange={handleOnChange}
|
|
210
233
|
value={checkedValues}
|
|
211
|
-
classNames={{ option:
|
|
234
|
+
classNames={{ option: 'w30' }}
|
|
212
235
|
inlineLayout
|
|
213
236
|
/>
|
|
214
237
|
);
|
|
215
|
-
}
|
|
238
|
+
};
|
|
216
239
|
|
|
217
240
|
CheckboxStory.storyName = 'Checkbox';
|
|
218
241
|
|
|
@@ -20,6 +20,7 @@ export interface CheckboxProps<ValueType extends string> {
|
|
|
20
20
|
label?: string;
|
|
21
21
|
option?: string;
|
|
22
22
|
};
|
|
23
|
+
fieldLegend?: string;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export const Checkbox = <ValueType extends string>({
|
|
@@ -30,6 +31,7 @@ export const Checkbox = <ValueType extends string>({
|
|
|
30
31
|
inlineLayout = false,
|
|
31
32
|
bordered = true,
|
|
32
33
|
classNames: classNamesObj,
|
|
34
|
+
fieldLegend,
|
|
33
35
|
}: CheckboxProps<ValueType> & {}) => {
|
|
34
36
|
const hasNoneValue = Object.keys(options).includes('NONE');
|
|
35
37
|
|
|
@@ -71,8 +73,14 @@ export const Checkbox = <ValueType extends string>({
|
|
|
71
73
|
return (label as CheckboxWithDescription).title !== undefined;
|
|
72
74
|
};
|
|
73
75
|
|
|
76
|
+
const legend =
|
|
77
|
+
fieldLegend ??
|
|
78
|
+
(Object.keys(options).length > 1
|
|
79
|
+
? 'Select one or more options'
|
|
80
|
+
: 'You may select this option');
|
|
81
|
+
|
|
74
82
|
return (
|
|
75
|
-
<
|
|
83
|
+
<fieldset
|
|
76
84
|
className={classNames(
|
|
77
85
|
classNamesObj?.container,
|
|
78
86
|
styles.container,
|
|
@@ -85,6 +93,7 @@ export const Checkbox = <ValueType extends string>({
|
|
|
85
93
|
}
|
|
86
94
|
)}
|
|
87
95
|
>
|
|
96
|
+
<legend className="sr-only">{legend}</legend>
|
|
88
97
|
{entries.map(([currentValue, label]) => {
|
|
89
98
|
const checked = value?.includes(currentValue);
|
|
90
99
|
const customIcon = (label as CheckboxWithDescription)?.icon;
|
|
@@ -129,6 +138,6 @@ export const Checkbox = <ValueType extends string>({
|
|
|
129
138
|
</div>
|
|
130
139
|
);
|
|
131
140
|
})}
|
|
132
|
-
</
|
|
141
|
+
</fieldset>
|
|
133
142
|
);
|
|
134
143
|
};
|
|
@@ -13,6 +13,14 @@ const story = {
|
|
|
13
13
|
value: {
|
|
14
14
|
description: 'Current checked values.',
|
|
15
15
|
},
|
|
16
|
+
fieldLegend: {
|
|
17
|
+
description:
|
|
18
|
+
'Property that describes the purpose of a group of radio buttons, read aloud by screen readers to provide context.',
|
|
19
|
+
},
|
|
20
|
+
groupName: {
|
|
21
|
+
description:
|
|
22
|
+
'Property passed to each radio button. Informs the browser that the radio buttons belong to the same group, so only one can be selected',
|
|
23
|
+
},
|
|
16
24
|
onChange: {
|
|
17
25
|
description: 'Function called everytime a value changes.',
|
|
18
26
|
action: true,
|
|
@@ -29,7 +37,8 @@ const story = {
|
|
|
29
37
|
'Property that defines if options should show inline instead of block. Check inline radio options story for examples.',
|
|
30
38
|
},
|
|
31
39
|
inlineIcon: {
|
|
32
|
-
description:
|
|
40
|
+
description:
|
|
41
|
+
'Property that defines if options should show inline with icon',
|
|
33
42
|
},
|
|
34
43
|
classNames: {
|
|
35
44
|
description: 'ClassNames for custom styling',
|
|
@@ -57,6 +66,8 @@ const story = {
|
|
|
57
66
|
description: 'No pets',
|
|
58
67
|
},
|
|
59
68
|
},
|
|
69
|
+
fieldLegend: 'Owned pets',
|
|
70
|
+
groupName: 'Pets',
|
|
60
71
|
value: '',
|
|
61
72
|
wide: false,
|
|
62
73
|
classNames: {
|
|
@@ -68,7 +79,7 @@ const story = {
|
|
|
68
79
|
inlineLayout: false,
|
|
69
80
|
inlineIcon: false,
|
|
70
81
|
disabled: false,
|
|
71
|
-
}
|
|
82
|
+
},
|
|
72
83
|
};
|
|
73
84
|
|
|
74
85
|
export const RadioStory = ({
|
|
@@ -79,6 +90,8 @@ export const RadioStory = ({
|
|
|
79
90
|
inlineLayout,
|
|
80
91
|
bordered,
|
|
81
92
|
disabled,
|
|
93
|
+
fieldLegend,
|
|
94
|
+
groupName,
|
|
82
95
|
}: RadioProps<string>) => {
|
|
83
96
|
const [checkedValues, setCheckedValues] = useState<string>();
|
|
84
97
|
|
|
@@ -97,6 +110,8 @@ export const RadioStory = ({
|
|
|
97
110
|
inlineLayout={inlineLayout}
|
|
98
111
|
bordered={bordered}
|
|
99
112
|
disabled={disabled}
|
|
113
|
+
fieldLegend={fieldLegend}
|
|
114
|
+
groupName={groupName}
|
|
100
115
|
/>
|
|
101
116
|
);
|
|
102
117
|
};
|
|
@@ -2,6 +2,7 @@ import classNames from 'classnames';
|
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
|
|
4
4
|
import styles from './styles.module.scss';
|
|
5
|
+
import generateId from '../../../util/generateId';
|
|
5
6
|
export interface RadioWithDescription {
|
|
6
7
|
title: ReactNode;
|
|
7
8
|
description?: string;
|
|
@@ -23,6 +24,8 @@ export interface RadioProps<ValueType extends string> {
|
|
|
23
24
|
};
|
|
24
25
|
bordered?: boolean;
|
|
25
26
|
disabled?: boolean;
|
|
27
|
+
fieldLegend?: string;
|
|
28
|
+
groupName?: string;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
export const Radio = <ValueType extends string>({
|
|
@@ -35,14 +38,18 @@ export const Radio = <ValueType extends string>({
|
|
|
35
38
|
classNames: classNamesObj,
|
|
36
39
|
bordered = true,
|
|
37
40
|
disabled = false,
|
|
41
|
+
fieldLegend = 'Select an option',
|
|
42
|
+
groupName,
|
|
38
43
|
}: RadioProps<ValueType>) => {
|
|
39
44
|
const entries = Object.entries(options) as [
|
|
40
45
|
ValueType,
|
|
41
46
|
ReactNode | RadioWithDescription
|
|
42
47
|
][];
|
|
43
48
|
|
|
49
|
+
const name = groupName ?? generateId();
|
|
50
|
+
|
|
44
51
|
return (
|
|
45
|
-
<
|
|
52
|
+
<fieldset
|
|
46
53
|
className={classNames(
|
|
47
54
|
classNamesObj?.container,
|
|
48
55
|
styles.container,
|
|
@@ -56,6 +63,7 @@ export const Radio = <ValueType extends string>({
|
|
|
56
63
|
}
|
|
57
64
|
)}
|
|
58
65
|
>
|
|
66
|
+
<legend className="sr-only">{fieldLegend}</legend>
|
|
59
67
|
{entries.map(([currentValue, label]) => {
|
|
60
68
|
const checked = value === currentValue;
|
|
61
69
|
const customIcon = (label as RadioWithDescription)?.icon;
|
|
@@ -81,6 +89,7 @@ export const Radio = <ValueType extends string>({
|
|
|
81
89
|
checked={checked}
|
|
82
90
|
data-testid={`radio-input-${currentValue}`}
|
|
83
91
|
disabled={disabled}
|
|
92
|
+
name={name}
|
|
84
93
|
/>
|
|
85
94
|
|
|
86
95
|
<label
|
|
@@ -118,6 +127,6 @@ export const Radio = <ValueType extends string>({
|
|
|
118
127
|
</div>
|
|
119
128
|
);
|
|
120
129
|
})}
|
|
121
|
-
</
|
|
130
|
+
</fieldset>
|
|
122
131
|
);
|
|
123
132
|
};
|
|
@@ -5,6 +5,7 @@ import styles from './style.module.scss';
|
|
|
5
5
|
import { FileIcon, Trash2Icon, EyeVisionIcon } from '../../icon/icons';
|
|
6
6
|
import { Color } from '../../../models/styles';
|
|
7
7
|
import { UploadStatus, UploadedFile } from '../types';
|
|
8
|
+
import { Button } from '../../button';
|
|
8
9
|
|
|
9
10
|
interface Props {
|
|
10
11
|
uploadStatus: UploadStatus;
|
|
@@ -94,35 +95,40 @@ const UploadFileCell: React.FC<Props> = ({
|
|
|
94
95
|
) : (
|
|
95
96
|
<>
|
|
96
97
|
{isComplete && (
|
|
97
|
-
<
|
|
98
|
-
|
|
98
|
+
<Button
|
|
99
|
+
as="a"
|
|
99
100
|
href={previewUrl}
|
|
100
101
|
target="_blank"
|
|
101
102
|
rel="noopener noreferrer"
|
|
103
|
+
hideLabel
|
|
104
|
+
variant="filledWhite"
|
|
105
|
+
className={classnames('mr16', styles.button)}
|
|
106
|
+
leftIcon={
|
|
107
|
+
<EyeVisionIcon noMargin color={'grey-500'} size={24} />
|
|
108
|
+
}
|
|
102
109
|
>
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
size={24}
|
|
106
|
-
className={styles.icon}
|
|
107
|
-
/>
|
|
108
|
-
</a>
|
|
110
|
+
Preview file
|
|
111
|
+
</Button>
|
|
109
112
|
)}
|
|
110
113
|
|
|
111
114
|
{onRemoveFile && (
|
|
112
|
-
<
|
|
113
|
-
type="button"
|
|
115
|
+
<Button
|
|
114
116
|
onClick={() => onRemoveFile(id)}
|
|
115
|
-
|
|
116
|
-
[styles.disabled]: uploading,
|
|
117
|
-
})}
|
|
117
|
+
disabled={uploading}
|
|
118
118
|
data-testid="remove-button"
|
|
119
|
+
className={styles.button}
|
|
120
|
+
leftIcon={
|
|
121
|
+
<Trash2Icon
|
|
122
|
+
color={hasError ? 'red-500' : 'grey-500'}
|
|
123
|
+
size={24}
|
|
124
|
+
noMargin
|
|
125
|
+
/>
|
|
126
|
+
}
|
|
127
|
+
hideLabel
|
|
128
|
+
variant="filledWhite"
|
|
119
129
|
>
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
size={24}
|
|
123
|
-
className={styles.icon}
|
|
124
|
-
/>
|
|
125
|
-
</button>
|
|
130
|
+
Delete file
|
|
131
|
+
</Button>
|
|
126
132
|
)}
|
|
127
133
|
</>
|
|
128
134
|
)}
|
|
@@ -27,10 +27,6 @@
|
|
|
27
27
|
align-items: center;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
.icon {
|
|
31
|
-
margin: 0px;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
30
|
.main-icon {
|
|
35
31
|
margin-right: 16px;
|
|
36
32
|
}
|
|
@@ -64,39 +60,25 @@
|
|
|
64
60
|
|
|
65
61
|
.cell-right-section {
|
|
66
62
|
display: flex;
|
|
67
|
-
justify-content: flex-end;
|
|
68
|
-
min-width: 32px;
|
|
69
|
-
margin-left: 16px;
|
|
70
63
|
}
|
|
71
64
|
|
|
72
65
|
.cell-right-section-complete {
|
|
73
66
|
min-width: 64px;
|
|
74
67
|
}
|
|
75
68
|
|
|
76
|
-
.
|
|
77
|
-
|
|
78
|
-
cursor: pointer;
|
|
79
|
-
background: none;
|
|
80
|
-
border: none;
|
|
81
|
-
padding: 0;
|
|
82
|
-
margin: 0;
|
|
83
|
-
color: inherit;
|
|
84
|
-
text-align: inherit;
|
|
85
|
-
outline: none;
|
|
86
|
-
box-shadow: none;
|
|
87
|
-
appearance: none;
|
|
88
|
-
-webkit-appearance: none;
|
|
89
|
-
-moz-appearance: none;
|
|
90
|
-
}
|
|
69
|
+
.button {
|
|
70
|
+
width: 32px;
|
|
91
71
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
72
|
+
div span span {
|
|
73
|
+
min-width: 24px !important;
|
|
74
|
+
height: 24px !important;
|
|
75
|
+
}
|
|
95
76
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
77
|
+
&:focus-visible {
|
|
78
|
+
outline: 2px solid $ds-grey-900;
|
|
79
|
+
border-radius: 2px;
|
|
80
|
+
outline-offset: 2px;
|
|
81
|
+
}
|
|
100
82
|
}
|
|
101
83
|
|
|
102
84
|
@keyframes appear-down {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
formatAcceptFileList,
|
|
11
11
|
getErrorMessage,
|
|
12
12
|
getFormattedAcceptObject,
|
|
13
|
+
getStatusMessage,
|
|
13
14
|
getUploadStatus,
|
|
14
15
|
} from './utils';
|
|
15
16
|
|
|
@@ -48,6 +49,7 @@ const MultiDropzone = ({
|
|
|
48
49
|
textOverrides,
|
|
49
50
|
}: MultiDropzoneProps) => {
|
|
50
51
|
const [errors, setErrors] = useState<ErrorMessage[]>([]);
|
|
52
|
+
const [statusMessage, setStatusMessage] = useState('');
|
|
51
53
|
const formattedAccept = getFormattedAcceptObject(accept);
|
|
52
54
|
const fileList = formatAcceptFileList(formattedAccept);
|
|
53
55
|
const placeholder = getPlaceholder(textOverrides, accept, maxSize);
|
|
@@ -60,6 +62,15 @@ const MultiDropzone = ({
|
|
|
60
62
|
(acceptedFiles: File[], filesRejected: FileRejection[]) => {
|
|
61
63
|
onFileSelect(acceptedFiles);
|
|
62
64
|
|
|
65
|
+
const messageForScreenReader = getStatusMessage({
|
|
66
|
+
acceptedFiles,
|
|
67
|
+
filesRejected,
|
|
68
|
+
fileList,
|
|
69
|
+
maxSize,
|
|
70
|
+
textOverrides,
|
|
71
|
+
});
|
|
72
|
+
setStatusMessage(messageForScreenReader);
|
|
73
|
+
|
|
63
74
|
setErrors((previousErrors) => [
|
|
64
75
|
...previousErrors,
|
|
65
76
|
...filesRejected.map(({ errors }) => ({
|
|
@@ -93,10 +104,10 @@ const MultiDropzone = ({
|
|
|
93
104
|
)}
|
|
94
105
|
{...getRootProps()}
|
|
95
106
|
>
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
/>
|
|
107
|
+
<div className="sr-only" aria-live="polite" aria-atomic="true">
|
|
108
|
+
{statusMessage}
|
|
109
|
+
</div>
|
|
110
|
+
<input data-testid="ds-drop-input" {...getInputProps()} />
|
|
100
111
|
<UploadCloudIcon
|
|
101
112
|
className={isCondensed ? styles.img : ''}
|
|
102
113
|
size={isCondensed ? 24 : 64}
|
|
@@ -151,7 +162,8 @@ const MultiDropzone = ({
|
|
|
151
162
|
|
|
152
163
|
<AnimateHeight duration={300} height={isOverMaxFiles ? 'auto' : 0}>
|
|
153
164
|
<p className="tc-red-500 mt16">
|
|
154
|
-
{textOverrides?.tooManyFilesError ||
|
|
165
|
+
{textOverrides?.tooManyFilesError ||
|
|
166
|
+
`You can upload maximum ${maxFiles} files.`}
|
|
155
167
|
</p>
|
|
156
168
|
</AnimateHeight>
|
|
157
169
|
</div>
|