@telus-uds/components-base 3.28.0 → 3.28.2
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 +20 -2
- package/lib/cjs/Autocomplete/Autocomplete.js +86 -32
- package/lib/cjs/Autocomplete/constants.js +2 -1
- package/lib/cjs/Carousel/Carousel.js +17 -17
- package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +3 -3
- package/lib/cjs/Listbox/ListboxOverlay.js +7 -1
- package/lib/cjs/Listbox/PressableItem.js +2 -2
- package/lib/cjs/MultiSelectFilter/MultiSelectFilter.js +5 -1
- package/lib/cjs/TextInput/TextInputBase.js +2 -2
- package/lib/esm/Autocomplete/Autocomplete.js +87 -33
- package/lib/esm/Autocomplete/constants.js +1 -0
- package/lib/esm/Carousel/Carousel.js +17 -17
- package/lib/esm/Carousel/CarouselItem/CarouselItem.js +3 -3
- package/lib/esm/Listbox/ListboxOverlay.js +7 -1
- package/lib/esm/Listbox/PressableItem.js +3 -3
- package/lib/esm/MultiSelectFilter/MultiSelectFilter.js +5 -1
- package/lib/esm/TextInput/TextInputBase.js +2 -2
- package/lib/package.json +1 -1
- package/package.json +1 -1
- package/src/Autocomplete/Autocomplete.jsx +142 -77
- package/src/Autocomplete/constants.js +1 -0
- package/src/Carousel/Carousel.jsx +17 -17
- package/src/Carousel/CarouselItem/CarouselItem.jsx +3 -3
- package/src/Listbox/ListboxOverlay.jsx +9 -1
- package/src/Listbox/PressableItem.jsx +1 -1
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +6 -1
- package/src/TextInput/TextInputBase.jsx +2 -2
|
@@ -24,6 +24,7 @@ import Suggestions from './Suggestions'
|
|
|
24
24
|
import {
|
|
25
25
|
DEFAULT_MAX_SUGGESTIONS,
|
|
26
26
|
DEFAULT_MIN_TO_SUGGESTION,
|
|
27
|
+
DEFAULT_MAX_DROPDOWN_HEIGHT,
|
|
27
28
|
INPUT_LEFT_PADDING,
|
|
28
29
|
MIN_LISTBOX_WIDTH
|
|
29
30
|
} from './constants'
|
|
@@ -51,20 +52,44 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
|
51
52
|
const highlightAllMatches = (str, substring = '', matchIndexes = [], resultsTextColor) => (
|
|
52
53
|
// Wrapping all in bold
|
|
53
54
|
<Typography variant={{ bold: false }} tokens={{ color: resultsTextColor }}>
|
|
54
|
-
{matchIndexes
|
|
55
|
-
(acc, matchIndex, index) =>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
55
|
+
{matchIndexes
|
|
56
|
+
.reduce((acc, matchIndex, index) => {
|
|
57
|
+
const prefix = index === 0 ? str.slice(0, matchIndex) : null
|
|
58
|
+
const match = str.slice(matchIndex, matchIndex + substring.length)
|
|
59
|
+
const suffix = str.slice(
|
|
60
|
+
matchIndex + substring.length,
|
|
61
|
+
matchIndexes[index + 1] ?? str.length
|
|
62
|
+
)
|
|
63
|
+
return [
|
|
64
|
+
...acc,
|
|
65
|
+
prefix ? (
|
|
66
|
+
<Typography
|
|
67
|
+
key={`pre-${matchIndex}`}
|
|
68
|
+
variant={{ bold: false }}
|
|
69
|
+
tokens={{ color: resultsTextColor }}
|
|
70
|
+
>
|
|
71
|
+
{prefix}
|
|
72
|
+
</Typography>
|
|
73
|
+
) : null,
|
|
74
|
+
<Typography
|
|
75
|
+
key={matchIndex}
|
|
76
|
+
variant={{ bold: true }}
|
|
77
|
+
tokens={{ color: resultsTextColor }}
|
|
78
|
+
>
|
|
79
|
+
{match}
|
|
80
|
+
</Typography>,
|
|
81
|
+
suffix ? (
|
|
82
|
+
<Typography
|
|
83
|
+
key={`post-${matchIndex}`}
|
|
84
|
+
variant={{ bold: false }}
|
|
85
|
+
tokens={{ color: resultsTextColor }}
|
|
86
|
+
>
|
|
87
|
+
{suffix}
|
|
88
|
+
</Typography>
|
|
89
|
+
) : null
|
|
90
|
+
]
|
|
91
|
+
}, [])
|
|
92
|
+
.filter(Boolean)}
|
|
68
93
|
</Typography>
|
|
69
94
|
)
|
|
70
95
|
const highlight = (items = [], text = '', color) =>
|
|
@@ -94,12 +119,14 @@ const Autocomplete = React.forwardRef(
|
|
|
94
119
|
isLoading = false,
|
|
95
120
|
items,
|
|
96
121
|
maxSuggestions = DEFAULT_MAX_SUGGESTIONS,
|
|
122
|
+
maxDropdownHeight = DEFAULT_MAX_DROPDOWN_HEIGHT,
|
|
97
123
|
minToSuggestion = DEFAULT_MIN_TO_SUGGESTION,
|
|
98
124
|
noResults,
|
|
99
125
|
onChange,
|
|
100
126
|
onClear,
|
|
101
127
|
onSelect,
|
|
102
128
|
readOnly,
|
|
129
|
+
showOptionsOnFocus = false,
|
|
103
130
|
validation,
|
|
104
131
|
value,
|
|
105
132
|
helpText = '',
|
|
@@ -144,7 +171,7 @@ const Autocomplete = React.forwardRef(
|
|
|
144
171
|
|
|
145
172
|
const { supportsProps, ...selectedProps } = selectProps(rest)
|
|
146
173
|
const { hint, label: inputLabel } = supportsProps
|
|
147
|
-
const hintExpansionEnabled = isFocused && helpText && !currentValue
|
|
174
|
+
const hintExpansionEnabled = isFocused && !!helpText && !currentValue
|
|
148
175
|
const {
|
|
149
176
|
overlaidPosition,
|
|
150
177
|
sourceRef: inputRef,
|
|
@@ -198,9 +225,12 @@ const Autocomplete = React.forwardRef(
|
|
|
198
225
|
}
|
|
199
226
|
|
|
200
227
|
const handleChange = (newValue) => {
|
|
201
|
-
onChange?.(newValue
|
|
228
|
+
onChange?.(newValue)
|
|
202
229
|
setCurrentValue(newValue)
|
|
203
|
-
|
|
230
|
+
const shouldExpand =
|
|
231
|
+
newValue?.length >= minToSuggestion ||
|
|
232
|
+
(showOptionsOnFocus && isFocused && newValue?.length === 0)
|
|
233
|
+
setIsExpanded(shouldExpand)
|
|
204
234
|
if (!isControlled && initialItems !== undefined) {
|
|
205
235
|
setCurrentItems(
|
|
206
236
|
initialItems.filter(({ label }) =>
|
|
@@ -211,21 +241,24 @@ const Autocomplete = React.forwardRef(
|
|
|
211
241
|
}
|
|
212
242
|
const handleSelect = (selectedId) => {
|
|
213
243
|
onSelect?.(selectedId)
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
244
|
+
const selectedItem = (isControlled ? items : currentItems)?.find(
|
|
245
|
+
({ id }) => id === selectedId
|
|
246
|
+
)
|
|
247
|
+
const { label, nested, title } = selectedItem
|
|
248
|
+
|
|
219
249
|
if (title) return
|
|
220
250
|
if (!nested) {
|
|
221
251
|
setNestedSelectedValue(null)
|
|
222
|
-
onChange?.(
|
|
252
|
+
onChange?.(label)
|
|
223
253
|
setIsExpanded(false)
|
|
254
|
+
setCurrentValue(label)
|
|
224
255
|
}
|
|
225
|
-
|
|
226
|
-
if (!isControlled && inputRef?.current) inputRef.current.value = newValue
|
|
256
|
+
if (!isControlled && inputRef?.current) inputRef.current.value = label
|
|
227
257
|
|
|
228
|
-
if (nested)
|
|
258
|
+
if (nested) {
|
|
259
|
+
setNestedSelectedValue(label)
|
|
260
|
+
setCurrentValue(label)
|
|
261
|
+
}
|
|
229
262
|
|
|
230
263
|
inputRef.current.focus()
|
|
231
264
|
}
|
|
@@ -278,17 +311,13 @@ const Autocomplete = React.forwardRef(
|
|
|
278
311
|
}, [inputRef])
|
|
279
312
|
|
|
280
313
|
const handleClose = (event) => {
|
|
281
|
-
if (
|
|
282
|
-
(event.type === 'keydown' && (event.key === 'Escape' || event.key === '27')) ||
|
|
283
|
-
(event.type === 'click' && !openOverlayRef?.current?.contains(event.target)) ||
|
|
284
|
-
(event.type === 'touchstart' &&
|
|
285
|
-
openOverlayRef?.current &&
|
|
286
|
-
event.touches[0].target &&
|
|
287
|
-
!openOverlayRef?.current?.contains(event.touches[0].target))
|
|
288
|
-
) {
|
|
314
|
+
if (event.type === 'keydown' && (event.key === 'Escape' || event.key === '27')) {
|
|
289
315
|
setIsExpanded(false)
|
|
290
316
|
setNestedSelectedValue(null)
|
|
291
|
-
|
|
317
|
+
return
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (
|
|
292
321
|
event.type === 'keydown' &&
|
|
293
322
|
(event.key === 'ArrowDown' || event.key === 'Tab') &&
|
|
294
323
|
isExpanded &&
|
|
@@ -297,13 +326,30 @@ const Autocomplete = React.forwardRef(
|
|
|
297
326
|
) {
|
|
298
327
|
event.preventDefault()
|
|
299
328
|
targetRef.current.focus()
|
|
329
|
+
return
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (event.type === 'click' || event.type === 'touchstart') {
|
|
333
|
+
const clickTarget = event.type === 'click' ? event.target : event.touches[0]?.target
|
|
334
|
+
const isOutsideOverlay =
|
|
335
|
+
openOverlayRef?.current && !openOverlayRef.current.contains(clickTarget)
|
|
336
|
+
const isOutsideInput = inputRef?.current && !inputRef.current.contains(clickTarget)
|
|
337
|
+
|
|
338
|
+
if (isOutsideOverlay && isOutsideInput) {
|
|
339
|
+
setIsExpanded(false)
|
|
340
|
+
setNestedSelectedValue(null)
|
|
341
|
+
}
|
|
300
342
|
}
|
|
301
343
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
344
|
+
// Calculate items to show based on current state
|
|
345
|
+
let itemsToShow = []
|
|
346
|
+
if (currentValue?.length > 0) {
|
|
347
|
+
itemsToShow = itemsToSuggest(
|
|
348
|
+
highlight(isControlled ? items : currentItems, currentValue, resultsTextColor)
|
|
349
|
+
)
|
|
350
|
+
} else if (showOptionsOnFocus && isFocused) {
|
|
351
|
+
itemsToShow = itemsToSuggest(isControlled ? items : currentItems || initialItems)
|
|
352
|
+
}
|
|
307
353
|
const helpTextToShow = isFocused && !currentValue ? helpText : noResults ?? getCopy('noResults')
|
|
308
354
|
|
|
309
355
|
return (
|
|
@@ -337,9 +383,15 @@ const Autocomplete = React.forwardRef(
|
|
|
337
383
|
onChange={handleChange}
|
|
338
384
|
onFocus={() => {
|
|
339
385
|
setisFocused(true)
|
|
386
|
+
if (showOptionsOnFocus && (!currentValue || currentValue.length === 0)) {
|
|
387
|
+
setIsExpanded(true)
|
|
388
|
+
}
|
|
340
389
|
}}
|
|
341
390
|
onBlur={() => {
|
|
342
391
|
setisFocused(false)
|
|
392
|
+
if (showOptionsOnFocus && (!currentValue || currentValue.length === 0)) {
|
|
393
|
+
setIsExpanded(false)
|
|
394
|
+
}
|
|
343
395
|
}}
|
|
344
396
|
onClear={onClear}
|
|
345
397
|
onKeyPress={handleClose}
|
|
@@ -368,45 +420,50 @@ const Autocomplete = React.forwardRef(
|
|
|
368
420
|
)
|
|
369
421
|
}}
|
|
370
422
|
</InputSupports>
|
|
371
|
-
{(isExpanded || hintExpansionEnabled) &&
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
423
|
+
{(isExpanded || hintExpansionEnabled) &&
|
|
424
|
+
isInputVisible &&
|
|
425
|
+
(itemsToShow.length > 0 || isExpanded || hintExpansionEnabled) && (
|
|
426
|
+
<>
|
|
427
|
+
<Listbox.Overlay
|
|
428
|
+
overlaidPosition={overlaidPosition}
|
|
429
|
+
isReady={isReady}
|
|
430
|
+
minWidth={fullWidth ? inputWidth : MIN_LISTBOX_WIDTH}
|
|
431
|
+
maxWidth={inputWidth}
|
|
432
|
+
maxHeight={maxDropdownHeight}
|
|
433
|
+
onLayout={handleMeasure}
|
|
434
|
+
tokens={restOfTokens}
|
|
435
|
+
ref={openOverlayRef}
|
|
436
|
+
>
|
|
437
|
+
{isLoading ? (
|
|
438
|
+
<Loading label={loadingLabel ?? getCopy('loading')} />
|
|
439
|
+
) : (
|
|
440
|
+
<Suggestions
|
|
441
|
+
hasResults={getCopy('hasResults')}
|
|
442
|
+
id="autocomplete"
|
|
443
|
+
items={
|
|
444
|
+
nestedSelectedValue
|
|
445
|
+
? itemsToSuggest(
|
|
446
|
+
highlight(otherItems, nestedSelectedValue, resultsTextColor)
|
|
447
|
+
)
|
|
448
|
+
: itemsToShow
|
|
449
|
+
}
|
|
450
|
+
noResults={helpTextToShow}
|
|
451
|
+
onClose={handleClose}
|
|
452
|
+
onSelect={handleSelect}
|
|
453
|
+
parentRef={inputRef}
|
|
454
|
+
ref={targetRef}
|
|
455
|
+
/>
|
|
456
|
+
)}
|
|
457
|
+
</Listbox.Overlay>
|
|
458
|
+
{targetRef?.current && (
|
|
459
|
+
<View
|
|
460
|
+
// This catches and shifts focus to other interactive elements.
|
|
461
|
+
onFocus={() => targetRef?.current?.focus()}
|
|
462
|
+
tabIndex={0}
|
|
398
463
|
/>
|
|
399
464
|
)}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
<View
|
|
403
|
-
// This catches and shifts focus to other interactive elements.
|
|
404
|
-
onFocus={() => targetRef?.current?.focus()}
|
|
405
|
-
tabIndex={0}
|
|
406
|
-
/>
|
|
407
|
-
)}
|
|
408
|
-
</>
|
|
409
|
-
)}
|
|
465
|
+
</>
|
|
466
|
+
)}
|
|
410
467
|
</View>
|
|
411
468
|
)
|
|
412
469
|
}
|
|
@@ -468,6 +525,10 @@ Autocomplete.propTypes = {
|
|
|
468
525
|
* Maximum number of suggestions provided at the same time
|
|
469
526
|
*/
|
|
470
527
|
maxSuggestions: PropTypes.number,
|
|
528
|
+
/**
|
|
529
|
+
* Maximum height (in pixels) of the dropdown before scrolling is enabled
|
|
530
|
+
*/
|
|
531
|
+
maxDropdownHeight: PropTypes.number,
|
|
471
532
|
/**
|
|
472
533
|
* Text or JSX to render when no results are available
|
|
473
534
|
*/
|
|
@@ -488,6 +549,10 @@ Autocomplete.propTypes = {
|
|
|
488
549
|
* Callback function to be called when an item is selected from the list
|
|
489
550
|
*/
|
|
490
551
|
onSelect: PropTypes.func,
|
|
552
|
+
/**
|
|
553
|
+
* When true, displays all available options when the input receives focus (even without typing)
|
|
554
|
+
*/
|
|
555
|
+
showOptionsOnFocus: PropTypes.bool,
|
|
491
556
|
/**
|
|
492
557
|
* Input value for controlled usage
|
|
493
558
|
*/
|
|
@@ -125,7 +125,7 @@ const selectControlButtonPositionStyles = ({
|
|
|
125
125
|
isAutoPlayEnabled,
|
|
126
126
|
viewport,
|
|
127
127
|
maxWidth,
|
|
128
|
-
|
|
128
|
+
containerWidth
|
|
129
129
|
}) => {
|
|
130
130
|
const styles = {}
|
|
131
131
|
|
|
@@ -148,13 +148,11 @@ const selectControlButtonPositionStyles = ({
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
if (enablePeeking) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
positionOffset += leftMargin
|
|
157
|
-
}
|
|
151
|
+
const { peekingMiddleSpace, peekingGap } = getPeekingProps(viewport)
|
|
152
|
+
const clampedMaxWidth = Math.min(maxWidth || containerWidth, containerWidth)
|
|
153
|
+
const slideRightEdge = (containerWidth + clampedMaxWidth) / 2 - peekingMiddleSpace
|
|
154
|
+
const buttonCenter = slideRightEdge + peekingGap / 2
|
|
155
|
+
positionOffset = containerWidth - buttonCenter - buttonWidth / 2
|
|
158
156
|
}
|
|
159
157
|
|
|
160
158
|
styles[positionProperty] = positionOffset
|
|
@@ -173,7 +171,7 @@ const selectPreviousNextNavigationButtonStyles = (
|
|
|
173
171
|
isAutoPlayEnabled,
|
|
174
172
|
viewport,
|
|
175
173
|
maxWidth,
|
|
176
|
-
|
|
174
|
+
containerWidth
|
|
177
175
|
) => {
|
|
178
176
|
const styles = {
|
|
179
177
|
zIndex: 1,
|
|
@@ -199,7 +197,7 @@ const selectPreviousNextNavigationButtonStyles = (
|
|
|
199
197
|
isAutoPlayEnabled,
|
|
200
198
|
viewport,
|
|
201
199
|
maxWidth,
|
|
202
|
-
|
|
200
|
+
containerWidth
|
|
203
201
|
})
|
|
204
202
|
}
|
|
205
203
|
}
|
|
@@ -343,7 +341,7 @@ const calculateFinalWidth = (containerWidth, enablePeeking, viewport, maxWidth)
|
|
|
343
341
|
|
|
344
342
|
if (enablePeeking) {
|
|
345
343
|
const { peekingGap, peekingMiddleSpace } = getPeekingProps(viewport)
|
|
346
|
-
const baseWidth = maxWidth || containerWidth
|
|
344
|
+
const baseWidth = Math.min(maxWidth || containerWidth, containerWidth)
|
|
347
345
|
finalWidth = baseWidth - peekingMiddleSpace * PEEKING_MULTIPLIER + peekingGap
|
|
348
346
|
}
|
|
349
347
|
|
|
@@ -572,7 +570,10 @@ const Carousel = React.forwardRef(
|
|
|
572
570
|
const { peekingGap, peekingMiddleSpace } = getPeekingProps(viewport)
|
|
573
571
|
|
|
574
572
|
let finalWidth
|
|
575
|
-
const baseWidth =
|
|
573
|
+
const baseWidth = Math.min(
|
|
574
|
+
maxWidth || containerLayoutRef.current.width,
|
|
575
|
+
containerLayoutRef.current.width
|
|
576
|
+
)
|
|
576
577
|
const slideWide = baseWidth - peekingMiddleSpace * PEEKING_MULTIPLIER
|
|
577
578
|
|
|
578
579
|
if (activeIndexRef.current === 0) {
|
|
@@ -1055,8 +1056,7 @@ const Carousel = React.forwardRef(
|
|
|
1055
1056
|
// Related discussion - https://github.com/telus/universal-design-system/issues/1549
|
|
1056
1057
|
const previousNextIconButtonVariants = {
|
|
1057
1058
|
size: previousNextIconSize,
|
|
1058
|
-
raised:
|
|
1059
|
-
inverse: variant?.inverse
|
|
1059
|
+
raised: true
|
|
1060
1060
|
}
|
|
1061
1061
|
|
|
1062
1062
|
const getCopyWithPlaceholders = React.useCallback(
|
|
@@ -1177,7 +1177,7 @@ const Carousel = React.forwardRef(
|
|
|
1177
1177
|
isAutoPlayEnabled,
|
|
1178
1178
|
viewport,
|
|
1179
1179
|
maxWidth,
|
|
1180
|
-
|
|
1180
|
+
containerWidth: containerLayout.width
|
|
1181
1181
|
})
|
|
1182
1182
|
]}
|
|
1183
1183
|
>
|
|
@@ -1205,7 +1205,7 @@ const Carousel = React.forwardRef(
|
|
|
1205
1205
|
isAutoPlayEnabled,
|
|
1206
1206
|
viewport,
|
|
1207
1207
|
maxWidth,
|
|
1208
|
-
|
|
1208
|
+
containerLayout.width
|
|
1209
1209
|
)}
|
|
1210
1210
|
testID="previous-button-container"
|
|
1211
1211
|
>
|
|
@@ -1303,7 +1303,7 @@ const Carousel = React.forwardRef(
|
|
|
1303
1303
|
isAutoPlayEnabled,
|
|
1304
1304
|
viewport,
|
|
1305
1305
|
maxWidth,
|
|
1306
|
-
|
|
1306
|
+
containerLayout.width
|
|
1307
1307
|
)}
|
|
1308
1308
|
testID="next-button-container"
|
|
1309
1309
|
>
|
|
@@ -31,10 +31,10 @@ const selectContainerStyle = ({
|
|
|
31
31
|
|
|
32
32
|
if (enablePeeking) {
|
|
33
33
|
const isFirst = elementIndex === 0
|
|
34
|
-
const
|
|
35
|
-
adjustedWidth =
|
|
34
|
+
const clampedMaxWidth = Math.min(maxWidth || width, width)
|
|
35
|
+
adjustedWidth = clampedMaxWidth - peekingMiddleSpace * 2
|
|
36
36
|
if (isFirst) {
|
|
37
|
-
marginLeft = peekingMiddleSpace + (viewportWidth -
|
|
37
|
+
marginLeft = peekingMiddleSpace + (viewportWidth - clampedMaxWidth) / 2
|
|
38
38
|
} else {
|
|
39
39
|
marginLeft = peekingGap
|
|
40
40
|
}
|
|
@@ -28,6 +28,7 @@ const DropdownOverlay = React.forwardRef(
|
|
|
28
28
|
isReady = false,
|
|
29
29
|
overlaidPosition,
|
|
30
30
|
maxWidth,
|
|
31
|
+
maxHeight,
|
|
31
32
|
minWidth,
|
|
32
33
|
onLayout,
|
|
33
34
|
tokens,
|
|
@@ -50,12 +51,18 @@ const DropdownOverlay = React.forwardRef(
|
|
|
50
51
|
staticStyles.positioner,
|
|
51
52
|
!isReady && staticStyles.hidden
|
|
52
53
|
]}
|
|
54
|
+
onMouseDown={(e) => {
|
|
55
|
+
e.preventDefault()
|
|
56
|
+
}}
|
|
53
57
|
>
|
|
54
58
|
<Card
|
|
55
59
|
tokens={{
|
|
56
60
|
shadow: systemTokens.shadow,
|
|
57
61
|
borderRadius: systemTokens.borderRadius,
|
|
58
|
-
...(Platform.OS === 'web' && {
|
|
62
|
+
...(Platform.OS === 'web' && {
|
|
63
|
+
maxHeight,
|
|
64
|
+
overflowY: 'auto'
|
|
65
|
+
}),
|
|
59
66
|
paddingBottom: paddingVertical,
|
|
60
67
|
paddingTop: paddingVertical,
|
|
61
68
|
paddingLeft: paddingHorizontal,
|
|
@@ -89,6 +96,7 @@ DropdownOverlay.propTypes = {
|
|
|
89
96
|
width: PropTypes.number
|
|
90
97
|
}),
|
|
91
98
|
maxWidth: PropTypes.number,
|
|
99
|
+
maxHeight: PropTypes.number,
|
|
92
100
|
minWidth: PropTypes.number,
|
|
93
101
|
onLayout: PropTypes.func,
|
|
94
102
|
tokens: PropTypes.object,
|
|
@@ -120,7 +120,7 @@ const PressableItem = React.forwardRef(
|
|
|
120
120
|
>
|
|
121
121
|
{(pressableState) => {
|
|
122
122
|
return (
|
|
123
|
-
<Text style={selectTextStyles(resolveButtonTokens(pressableState))}>{children}
|
|
123
|
+
<Text style={selectTextStyles(resolveButtonTokens(pressableState))}>{children}</Text>
|
|
124
124
|
)
|
|
125
125
|
}}
|
|
126
126
|
</Pressable>
|
|
@@ -185,6 +185,12 @@ const MultiSelectFilter = React.forwardRef(
|
|
|
185
185
|
|
|
186
186
|
React.useEffect(() => setCheckedIds(currentValues ?? []), [currentValues])
|
|
187
187
|
|
|
188
|
+
React.useEffect(() => {
|
|
189
|
+
if (isOpen && onOpen) {
|
|
190
|
+
onOpen()
|
|
191
|
+
}
|
|
192
|
+
}, [isOpen, onOpen])
|
|
193
|
+
|
|
188
194
|
const uniqueFields = ['id', 'label']
|
|
189
195
|
if (!containUniqueFields(items, uniqueFields)) {
|
|
190
196
|
throw new Error(`MultiSelectFilter items must have unique ${uniqueFields.join(', ')}`)
|
|
@@ -194,7 +200,6 @@ const MultiSelectFilter = React.forwardRef(
|
|
|
194
200
|
|
|
195
201
|
const handleChange = (event) => {
|
|
196
202
|
if (pressHandlers.onPress) pressHandlers?.onPress(event)
|
|
197
|
-
if (isOpen) onOpen()
|
|
198
203
|
setIsOpen(!isOpen)
|
|
199
204
|
}
|
|
200
205
|
|
|
@@ -255,8 +255,8 @@ const TextInputBase = React.forwardRef(
|
|
|
255
255
|
}, [element, pattern])
|
|
256
256
|
|
|
257
257
|
const handleChangeText = (event) => {
|
|
258
|
-
const text = event.nativeEvent?.text
|
|
259
|
-
let filteredText = isNumeric ? text?.replace(/[^\d]/g, '') : text
|
|
258
|
+
const text = event.nativeEvent?.text ?? event.target?.value
|
|
259
|
+
let filteredText = isNumeric ? text?.replace(/[^\d]/g, '') || undefined : text
|
|
260
260
|
if (type === 'card' && filteredText) {
|
|
261
261
|
const formattedValue = filteredText.replace(/[^a-zA-Z0-9]/g, '')
|
|
262
262
|
const regex = new RegExp(`([a-zA-Z0-9]{4})(?=[a-zA-Z0-9])`, 'g')
|