@startupjs-ui/multi-select 0.2.0 → 0.3.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/CHANGELOG.md +11 -0
- package/index.d.ts +16 -0
- package/index.tsx +102 -2
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [0.3.0](https://github.com/startupjs/startupjs-ui/compare/v0.2.3...v0.3.0) (2026-05-27)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Features
|
|
10
|
+
|
|
11
|
+
* [BREAKING] [0.3] improve accessibility props for E2E tests. Support testID everywhere ([#31](https://github.com/startupjs/startupjs-ui/issues/31)) ([882588c](https://github.com/startupjs/startupjs-ui/commit/882588ca37d5e1fd14b5717b5697cf9ed47042e4))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
# [0.2.0](https://github.com/startupjs/startupjs-ui/compare/v0.1.23...v0.2.0) (2026-05-04)
|
|
7
18
|
|
|
8
19
|
|
package/index.d.ts
CHANGED
|
@@ -26,6 +26,22 @@ export interface MultiSelectProps {
|
|
|
26
26
|
disabled?: boolean;
|
|
27
27
|
/** Render non-editable value @default false */
|
|
28
28
|
readonly?: boolean;
|
|
29
|
+
/** Web id for label association */
|
|
30
|
+
id?: string;
|
|
31
|
+
/** Accessible name for the combobox trigger */
|
|
32
|
+
'aria-label'?: string;
|
|
33
|
+
/** Element id that labels the combobox trigger */
|
|
34
|
+
'aria-labelledby'?: string;
|
|
35
|
+
/** Element id that describes the combobox trigger */
|
|
36
|
+
'aria-describedby'?: string;
|
|
37
|
+
/** Whether the combobox trigger value is invalid */
|
|
38
|
+
'aria-invalid'?: boolean;
|
|
39
|
+
/** Element id for the related error message */
|
|
40
|
+
'aria-errormessage'?: string;
|
|
41
|
+
/** Whether a value is required */
|
|
42
|
+
'aria-required'?: boolean;
|
|
43
|
+
/** Test identifier for the combobox trigger */
|
|
44
|
+
testID?: string;
|
|
29
45
|
/** Maximum number of visible tags (extra tags are collapsed) */
|
|
30
46
|
tagLimit?: number;
|
|
31
47
|
/** Behavior when tags are limited (legacy prop) @default 'hidden' */
|
package/index.tsx
CHANGED
|
@@ -46,6 +46,22 @@ export interface MultiSelectProps {
|
|
|
46
46
|
disabled?: boolean
|
|
47
47
|
/** Render non-editable value @default false */
|
|
48
48
|
readonly?: boolean
|
|
49
|
+
/** Web id for label association */
|
|
50
|
+
id?: string
|
|
51
|
+
/** Accessible name for the combobox trigger */
|
|
52
|
+
'aria-label'?: string
|
|
53
|
+
/** Element id that labels the combobox trigger */
|
|
54
|
+
'aria-labelledby'?: string
|
|
55
|
+
/** Element id that describes the combobox trigger */
|
|
56
|
+
'aria-describedby'?: string
|
|
57
|
+
/** Whether the combobox trigger value is invalid */
|
|
58
|
+
'aria-invalid'?: boolean
|
|
59
|
+
/** Element id for the related error message */
|
|
60
|
+
'aria-errormessage'?: string
|
|
61
|
+
/** Whether a value is required */
|
|
62
|
+
'aria-required'?: boolean
|
|
63
|
+
/** Test identifier for the combobox trigger */
|
|
64
|
+
testID?: string
|
|
49
65
|
/** Maximum number of visible tags (extra tags are collapsed) */
|
|
50
66
|
tagLimit?: number
|
|
51
67
|
/** Behavior when tags are limited (legacy prop) @default 'hidden' */
|
|
@@ -84,6 +100,14 @@ function MultiSelect ({
|
|
|
84
100
|
placeholder = 'Select',
|
|
85
101
|
disabled = false,
|
|
86
102
|
readonly = false,
|
|
103
|
+
id,
|
|
104
|
+
'aria-label': ariaLabel,
|
|
105
|
+
'aria-labelledby': ariaLabelledBy,
|
|
106
|
+
'aria-describedby': ariaDescribedBy,
|
|
107
|
+
'aria-invalid': ariaInvalid,
|
|
108
|
+
'aria-errormessage': ariaErrorMessage,
|
|
109
|
+
'aria-required': ariaRequired,
|
|
110
|
+
testID,
|
|
87
111
|
tagLimitVariant = 'hidden',
|
|
88
112
|
TagComponent = DefaultTag,
|
|
89
113
|
InputComponent,
|
|
@@ -167,12 +191,16 @@ function MultiSelect ({
|
|
|
167
191
|
const { label, value: itemValue } = item
|
|
168
192
|
const selected = value.includes(itemValue)
|
|
169
193
|
const onPress = onItemPress(itemValue, selected)
|
|
194
|
+
const optionLabel = label != null ? String(label) : String(itemValue)
|
|
170
195
|
|
|
171
196
|
return pug`
|
|
172
197
|
Div(
|
|
173
198
|
key=itemValue
|
|
174
199
|
vAlign='center'
|
|
175
200
|
disabled=selected ? false : shouldDisableSelection
|
|
201
|
+
role='option'
|
|
202
|
+
aria-label=optionLabel
|
|
203
|
+
aria-selected=selected
|
|
176
204
|
onPress=() => onPress(!selected)
|
|
177
205
|
)
|
|
178
206
|
if renderListItem
|
|
@@ -188,7 +216,7 @@ function MultiSelect ({
|
|
|
188
216
|
|
|
189
217
|
function renderContent (): ReactNode {
|
|
190
218
|
return pug`
|
|
191
|
-
ScrollView.suggestions-web
|
|
219
|
+
ScrollView.suggestions-web(role='listbox')
|
|
192
220
|
each option, index in normalizedOptions
|
|
193
221
|
= _renderListItem({ item: option, index })
|
|
194
222
|
`
|
|
@@ -214,6 +242,14 @@ function MultiSelect ({
|
|
|
214
242
|
focused=focused
|
|
215
243
|
value=value
|
|
216
244
|
placeholder=placeholder
|
|
245
|
+
id=id
|
|
246
|
+
aria-label=ariaLabel
|
|
247
|
+
aria-labelledby=ariaLabelledBy
|
|
248
|
+
aria-describedby=ariaDescribedBy
|
|
249
|
+
aria-invalid=ariaInvalid
|
|
250
|
+
aria-errormessage=ariaErrorMessage
|
|
251
|
+
aria-required=ariaRequired
|
|
252
|
+
testID=testID
|
|
217
253
|
tagLimit=tagLimit
|
|
218
254
|
tagLimitVariant=tagLimitVariant
|
|
219
255
|
options=normalizedOptions
|
|
@@ -235,6 +271,14 @@ function MultiSelect ({
|
|
|
235
271
|
focused=focused
|
|
236
272
|
value=value
|
|
237
273
|
placeholder=placeholder
|
|
274
|
+
id=id
|
|
275
|
+
aria-label=ariaLabel
|
|
276
|
+
aria-labelledby=ariaLabelledBy
|
|
277
|
+
aria-describedby=ariaDescribedBy
|
|
278
|
+
aria-invalid=ariaInvalid
|
|
279
|
+
aria-errormessage=ariaErrorMessage
|
|
280
|
+
aria-required=ariaRequired
|
|
281
|
+
testID=testID
|
|
238
282
|
tagLimit=tagLimit
|
|
239
283
|
tagLimitVariant=tagLimitVariant
|
|
240
284
|
options=normalizedOptions
|
|
@@ -261,6 +305,14 @@ function MultiSelectInput ({
|
|
|
261
305
|
value,
|
|
262
306
|
placeholder,
|
|
263
307
|
options,
|
|
308
|
+
id,
|
|
309
|
+
'aria-label': ariaLabel,
|
|
310
|
+
'aria-labelledby': ariaLabelledBy,
|
|
311
|
+
'aria-describedby': ariaDescribedBy,
|
|
312
|
+
'aria-invalid': ariaInvalid,
|
|
313
|
+
'aria-errormessage': ariaErrorMessage,
|
|
314
|
+
'aria-required': ariaRequired,
|
|
315
|
+
testID,
|
|
264
316
|
disabled,
|
|
265
317
|
readonly,
|
|
266
318
|
focused,
|
|
@@ -276,6 +328,14 @@ function MultiSelectInput ({
|
|
|
276
328
|
value: any[]
|
|
277
329
|
placeholder?: string
|
|
278
330
|
options: MultiSelectOption[]
|
|
331
|
+
id?: string
|
|
332
|
+
'aria-label'?: string
|
|
333
|
+
'aria-labelledby'?: string
|
|
334
|
+
'aria-describedby'?: string
|
|
335
|
+
'aria-invalid'?: boolean
|
|
336
|
+
'aria-errormessage'?: string
|
|
337
|
+
'aria-required'?: boolean
|
|
338
|
+
testID?: string
|
|
279
339
|
disabled?: boolean
|
|
280
340
|
readonly?: boolean
|
|
281
341
|
focused?: boolean
|
|
@@ -293,6 +353,12 @@ function MultiSelectInput ({
|
|
|
293
353
|
: 0
|
|
294
354
|
|
|
295
355
|
const EffectiveInputComponent = InputComponent ?? DefaultInput
|
|
356
|
+
const inferredAccessibleName = value.length
|
|
357
|
+
? value
|
|
358
|
+
.map(value => options.find(option => option.value === value)?.label ?? value)
|
|
359
|
+
.join(', ')
|
|
360
|
+
: placeholder
|
|
361
|
+
const accessibleName = ariaLabel ?? (ariaLabelledBy ? undefined : inferredAccessibleName)
|
|
296
362
|
|
|
297
363
|
return pug`
|
|
298
364
|
EffectiveInputComponent(
|
|
@@ -300,6 +366,14 @@ function MultiSelectInput ({
|
|
|
300
366
|
style=style
|
|
301
367
|
value=values
|
|
302
368
|
placeholder=placeholder
|
|
369
|
+
id=id
|
|
370
|
+
aria-label=accessibleName != null ? String(accessibleName) : undefined
|
|
371
|
+
aria-labelledby=ariaLabelledBy
|
|
372
|
+
aria-describedby=ariaDescribedBy
|
|
373
|
+
aria-invalid=ariaInvalid
|
|
374
|
+
aria-errormessage=ariaErrorMessage
|
|
375
|
+
aria-required=ariaRequired
|
|
376
|
+
testID=testID
|
|
303
377
|
disabled=disabled
|
|
304
378
|
focused=focused
|
|
305
379
|
readonly=readonly
|
|
@@ -329,6 +403,14 @@ function DefaultInput ({
|
|
|
329
403
|
style,
|
|
330
404
|
value = [],
|
|
331
405
|
placeholder,
|
|
406
|
+
id,
|
|
407
|
+
'aria-label': ariaLabel,
|
|
408
|
+
'aria-labelledby': ariaLabelledBy,
|
|
409
|
+
'aria-describedby': ariaDescribedBy,
|
|
410
|
+
'aria-invalid': ariaInvalid,
|
|
411
|
+
'aria-errormessage': ariaErrorMessage,
|
|
412
|
+
'aria-required': ariaRequired,
|
|
413
|
+
testID,
|
|
332
414
|
disabled,
|
|
333
415
|
focused,
|
|
334
416
|
readonly,
|
|
@@ -341,6 +423,14 @@ function DefaultInput ({
|
|
|
341
423
|
style?: StyleProp<ViewStyle>
|
|
342
424
|
value?: any[]
|
|
343
425
|
placeholder?: string
|
|
426
|
+
id?: string
|
|
427
|
+
'aria-label'?: string
|
|
428
|
+
'aria-labelledby'?: string
|
|
429
|
+
'aria-describedby'?: string
|
|
430
|
+
'aria-invalid'?: boolean
|
|
431
|
+
'aria-errormessage'?: string
|
|
432
|
+
'aria-required'?: boolean
|
|
433
|
+
testID?: string
|
|
344
434
|
disabled?: boolean
|
|
345
435
|
focused?: boolean
|
|
346
436
|
readonly?: boolean
|
|
@@ -366,7 +456,17 @@ function DefaultInput ({
|
|
|
366
456
|
Div.input(
|
|
367
457
|
style=style
|
|
368
458
|
styleName={ disabled, focused, readonly, error: _hasError }
|
|
369
|
-
|
|
459
|
+
id=id
|
|
460
|
+
role='combobox'
|
|
461
|
+
aria-label=ariaLabel
|
|
462
|
+
aria-labelledby=ariaLabelledBy
|
|
463
|
+
aria-describedby=ariaDescribedBy
|
|
464
|
+
aria-invalid=ariaInvalid
|
|
465
|
+
aria-errormessage=ariaErrorMessage
|
|
466
|
+
aria-required=ariaRequired
|
|
467
|
+
testID=testID
|
|
468
|
+
aria-expanded=!!focused
|
|
469
|
+
aria-haspopup='listbox'
|
|
370
470
|
aria-disabled=disabled
|
|
371
471
|
aria-readonly=readonly
|
|
372
472
|
onPress=disabled || readonly ? undefined : onOpen
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@startupjs-ui/multi-select",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -8,19 +8,19 @@
|
|
|
8
8
|
"types": "index.d.ts",
|
|
9
9
|
"type": "module",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@startupjs-ui/core": "^0.
|
|
12
|
-
"@startupjs-ui/div": "^0.
|
|
13
|
-
"@startupjs-ui/drawer": "^0.
|
|
14
|
-
"@startupjs-ui/icon": "^0.
|
|
15
|
-
"@startupjs-ui/popover": "^0.
|
|
16
|
-
"@startupjs-ui/scroll-view": "^0.
|
|
17
|
-
"@startupjs-ui/span": "^0.
|
|
18
|
-
"@startupjs-ui/tag": "^0.
|
|
11
|
+
"@startupjs-ui/core": "^0.3.0",
|
|
12
|
+
"@startupjs-ui/div": "^0.3.0",
|
|
13
|
+
"@startupjs-ui/drawer": "^0.3.0",
|
|
14
|
+
"@startupjs-ui/icon": "^0.3.0",
|
|
15
|
+
"@startupjs-ui/popover": "^0.3.0",
|
|
16
|
+
"@startupjs-ui/scroll-view": "^0.3.0",
|
|
17
|
+
"@startupjs-ui/span": "^0.3.0",
|
|
18
|
+
"@startupjs-ui/tag": "^0.3.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"react": "*",
|
|
22
22
|
"react-native": "*",
|
|
23
23
|
"startupjs": "*"
|
|
24
24
|
},
|
|
25
|
-
"gitHead": "
|
|
25
|
+
"gitHead": "8d212b47680af1dfe582f9759b38724b46488e25"
|
|
26
26
|
}
|