@telus-uds/components-base 1.62.1 → 1.63.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 -2
- package/lib/Autocomplete/Autocomplete.js +36 -4
- package/lib/Button/ButtonDropdown.js +1 -0
- package/lib/Listbox/Listbox.js +2 -2
- package/lib/Listbox/ListboxItem.js +7 -2
- package/lib/MultiSelectFilter/MultiSelectFilter.js +2 -2
- package/lib-module/Autocomplete/Autocomplete.js +37 -5
- package/lib-module/Button/ButtonDropdown.js +2 -1
- package/lib-module/Listbox/Listbox.js +2 -2
- package/lib-module/Listbox/ListboxItem.js +7 -2
- package/lib-module/MultiSelectFilter/MultiSelectFilter.js +2 -2
- package/package.json +3 -4
- package/src/Autocomplete/Autocomplete.jsx +43 -5
- package/src/Button/ButtonDropdown.jsx +3 -0
- package/src/Listbox/Listbox.jsx +2 -2
- package/src/Listbox/ListboxItem.jsx +14 -2
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +2 -2
- package/component-docs.json +0 -15896
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
# Change Log - @telus-uds/components-base
|
|
2
2
|
|
|
3
|
-
This log was last generated on Wed,
|
|
3
|
+
This log was last generated on Wed, 04 Oct 2023 18:37:04 GMT and should not be manually modified.
|
|
4
4
|
|
|
5
5
|
<!-- Start content -->
|
|
6
6
|
|
|
7
|
+
## 1.63.0
|
|
8
|
+
|
|
9
|
+
Wed, 04 Oct 2023 18:37:04 GMT
|
|
10
|
+
|
|
11
|
+
### Minor changes
|
|
12
|
+
|
|
13
|
+
- new logic for autocomplete when has nested items (mauricio.batresmontejo@telus.com)
|
|
14
|
+
- update components base imports (evander.owusu@telus.com)
|
|
15
|
+
|
|
7
16
|
## 1.62.1
|
|
8
17
|
|
|
9
|
-
Wed, 27 Sep 2023 20:
|
|
18
|
+
Wed, 27 Sep 2023 20:47:22 GMT
|
|
10
19
|
|
|
11
20
|
### Patches
|
|
12
21
|
|
|
@@ -154,7 +154,8 @@ const Autocomplete = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
154
154
|
|
|
155
155
|
const isControlled = value !== undefined; // We need to store current items for uncontrolled usage
|
|
156
156
|
|
|
157
|
-
const [currentItems, setCurrentItems] = (0, _react.useState)(initialItems);
|
|
157
|
+
const [currentItems, setCurrentItems] = (0, _react.useState)(initialItems);
|
|
158
|
+
const [otherItems, setOtherItems] = (0, _react.useState)(items); // We need to store the current value as well to be able to highlight it
|
|
158
159
|
|
|
159
160
|
const [currentValue, setCurrentValue] = (0, _react.useState)(value ?? initialValue);
|
|
160
161
|
const inputTokens = {
|
|
@@ -164,7 +165,9 @@ const Autocomplete = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
164
165
|
const openOverlayRef = (0, _react.useRef)();
|
|
165
166
|
const [isExpanded, setIsExpanded] = (0, _react.useState)(((_ref3 = value ?? initialValue) === null || _ref3 === void 0 ? void 0 : _ref3.length) >= minToSuggestion);
|
|
166
167
|
const [isFocused, setisFocused] = (0, _react.useState)(false);
|
|
167
|
-
const [sourceLayout, setSourceLayout] = (0, _react.useState)(null);
|
|
168
|
+
const [sourceLayout, setSourceLayout] = (0, _react.useState)(null); // When it's nested, selected value
|
|
169
|
+
|
|
170
|
+
const [nestedSelectedValue, setNestedSelectedValue] = (0, _react.useState)(null);
|
|
168
171
|
const {
|
|
169
172
|
supportsProps,
|
|
170
173
|
...selectedProps
|
|
@@ -262,22 +265,49 @@ const Autocomplete = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
262
265
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedId);
|
|
263
266
|
const {
|
|
264
267
|
label: newValue,
|
|
265
|
-
nested
|
|
268
|
+
nested,
|
|
269
|
+
title
|
|
266
270
|
} = (_ref5 = isControlled ? items : currentItems) === null || _ref5 === void 0 ? void 0 : _ref5.find(_ref6 => {
|
|
267
271
|
let {
|
|
268
272
|
id
|
|
269
273
|
} = _ref6;
|
|
270
274
|
return id === selectedId;
|
|
271
275
|
});
|
|
276
|
+
if (title) return;
|
|
272
277
|
|
|
273
278
|
if (!nested) {
|
|
279
|
+
setNestedSelectedValue(null);
|
|
274
280
|
onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
|
|
275
281
|
setIsExpanded(false);
|
|
276
282
|
}
|
|
277
283
|
|
|
278
284
|
setCurrentValue(newValue);
|
|
279
285
|
if (!isControlled && inputRef !== null && inputRef !== void 0 && inputRef.current) inputRef.current.value = newValue;
|
|
286
|
+
if (nested) setNestedSelectedValue(newValue);
|
|
280
287
|
};
|
|
288
|
+
/**
|
|
289
|
+
* When an item that is nested equal "true" is selected this useEffect is executed.
|
|
290
|
+
* The nested item is added to the item list at the top, the if validates it doesn't exist
|
|
291
|
+
* within the list, if doesn't exist the nested item is added to the top of the list,
|
|
292
|
+
* the nested item is added with an id equal "0"
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
(0, _react.useEffect)(() => {
|
|
297
|
+
if (nestedSelectedValue && !items.find(item => item.id === 0)) {
|
|
298
|
+
const tmpItems = [...items];
|
|
299
|
+
tmpItems.unshift({
|
|
300
|
+
label: nestedSelectedValue,
|
|
301
|
+
title: true,
|
|
302
|
+
id: 0
|
|
303
|
+
});
|
|
304
|
+
setOtherItems(tmpItems.map(item => {
|
|
305
|
+
return { ...item,
|
|
306
|
+
nestedChild: item.id !== 0
|
|
307
|
+
};
|
|
308
|
+
}));
|
|
309
|
+
}
|
|
310
|
+
}, [nestedSelectedValue, items]);
|
|
281
311
|
|
|
282
312
|
const handleClose = event => {
|
|
283
313
|
var _openOverlayRef$curre, _openOverlayRef$curre2;
|
|
@@ -285,6 +315,7 @@ const Autocomplete = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
285
315
|
if (event.type === 'keydown') {
|
|
286
316
|
if (event.key === 'Escape' || event.key === 27) {
|
|
287
317
|
setIsExpanded(false);
|
|
318
|
+
setNestedSelectedValue(null);
|
|
288
319
|
} else if (event.key === 'ArrowDown' && isExpanded && !isLoading && targetRef !== null && targetRef !== void 0 && targetRef.current) {
|
|
289
320
|
targetRef.current.focus();
|
|
290
321
|
}
|
|
@@ -295,6 +326,7 @@ const Autocomplete = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
295
326
|
} else if (_Platform.default.OS === 'web') {
|
|
296
327
|
// needed for dropdown to be collapsed when clicking outside on web
|
|
297
328
|
setIsExpanded(false);
|
|
329
|
+
setNestedSelectedValue(null);
|
|
298
330
|
}
|
|
299
331
|
};
|
|
300
332
|
|
|
@@ -369,7 +401,7 @@ const Autocomplete = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
369
401
|
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Suggestions.default, {
|
|
370
402
|
hasResults: getCopy('hasResults'),
|
|
371
403
|
id: "autocomplete",
|
|
372
|
-
items: itemsToShow,
|
|
404
|
+
items: nestedSelectedValue ? itemsToSuggest(highlight(otherItems, nestedSelectedValue, resultsTextColor)) : itemsToShow,
|
|
373
405
|
noResults: helpTextToShow,
|
|
374
406
|
onClose: handleClose,
|
|
375
407
|
onSelect: handleSelect,
|
|
@@ -176,6 +176,7 @@ ButtonDropdown.propTypes = { ..._utils.a11yProps.types,
|
|
|
176
176
|
..._utils.focusHandlerProps.types,
|
|
177
177
|
..._propTypes2.default,
|
|
178
178
|
children: _propTypes2.textAndA11yText,
|
|
179
|
+
tokens: (0, _utils.getTokensPropType)('ButtonDropdown'),
|
|
179
180
|
|
|
180
181
|
/**
|
|
181
182
|
* Callback called when a controlled ButtonDropdown gets interacted with.
|
package/lib/Listbox/Listbox.js
CHANGED
|
@@ -165,6 +165,7 @@ const Listbox = _ref => {
|
|
|
165
165
|
};
|
|
166
166
|
|
|
167
167
|
Listbox.propTypes = { ..._utils.withLinkRouter.propTypes,
|
|
168
|
+
tokens: (0, _utils.getTokensPropType)('Listbox'),
|
|
168
169
|
|
|
169
170
|
/**
|
|
170
171
|
* Focus will be moved to the item with this ref once within the menu.
|
|
@@ -190,8 +191,7 @@ Listbox.propTypes = { ..._utils.withLinkRouter.propTypes,
|
|
|
190
191
|
/**
|
|
191
192
|
* onClose event
|
|
192
193
|
*/
|
|
193
|
-
onClose: _propTypes.default.func
|
|
194
|
-
tokens: (0, _utils.getTokensPropType)('Listbox')
|
|
194
|
+
onClose: _propTypes.default.func
|
|
195
195
|
};
|
|
196
196
|
Listbox.Overlay = _ListboxOverlay.default;
|
|
197
197
|
var _default = Listbox;
|
|
@@ -37,6 +37,9 @@ const styles = _StyleSheet.default.create({
|
|
|
37
37
|
},
|
|
38
38
|
childContainer: {
|
|
39
39
|
paddingLeft: 16
|
|
40
|
+
},
|
|
41
|
+
nestedChildContainer: {
|
|
42
|
+
paddingLeft: 24
|
|
40
43
|
}
|
|
41
44
|
});
|
|
42
45
|
|
|
@@ -45,6 +48,7 @@ const ListboxItem = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
|
45
48
|
href,
|
|
46
49
|
label,
|
|
47
50
|
isChild = false,
|
|
51
|
+
nestedChild,
|
|
48
52
|
onBlur,
|
|
49
53
|
nextItemRef,
|
|
50
54
|
prevItemRef,
|
|
@@ -64,7 +68,7 @@ const ListboxItem = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
|
64
68
|
isChild
|
|
65
69
|
});
|
|
66
70
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
67
|
-
style: [styles.itemContainer, isChild && styles.childContainer],
|
|
71
|
+
style: [styles.itemContainer, isChild && styles.childContainer, nestedChild && styles.nestedChildContainer],
|
|
68
72
|
role: "option",
|
|
69
73
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_PressableItem.default, {
|
|
70
74
|
href: href,
|
|
@@ -89,7 +93,8 @@ ListboxItem.propTypes = { ...selectedSystemPropTypes,
|
|
|
89
93
|
label: _propTypes.default.node.isRequired,
|
|
90
94
|
nextItemRef: _propTypes.default.object,
|
|
91
95
|
prevItemRef: _propTypes.default.object,
|
|
92
|
-
onPress: _propTypes.default.func
|
|
96
|
+
onPress: _propTypes.default.func,
|
|
97
|
+
nestedChild: _propTypes.default.bool
|
|
93
98
|
};
|
|
94
99
|
|
|
95
100
|
var _default = (0, _utils.withLinkRouter)(ListboxItem);
|
|
@@ -439,9 +439,9 @@ MultiSelectFilter.propTypes = {
|
|
|
439
439
|
variant: _utils.variantProp.propType,
|
|
440
440
|
|
|
441
441
|
/**
|
|
442
|
-
* Sets the tokens for
|
|
442
|
+
* Sets the tokens for MultiSelectFilter element.
|
|
443
443
|
*/
|
|
444
|
-
tokens: (0, _utils.getTokensPropType)('
|
|
444
|
+
tokens: (0, _utils.getTokensPropType)('MultiSelectFilter'),
|
|
445
445
|
|
|
446
446
|
/**
|
|
447
447
|
* The options a user may select.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable react/require-default-props */
|
|
2
|
-
import React, { forwardRef, useRef, useState } from 'react';
|
|
2
|
+
import React, { forwardRef, useEffect, useRef, useState } from 'react';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import Dimensions from "react-native-web/dist/exports/Dimensions";
|
|
5
5
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
@@ -123,7 +123,8 @@ const Autocomplete = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
123
123
|
|
|
124
124
|
const isControlled = value !== undefined; // We need to store current items for uncontrolled usage
|
|
125
125
|
|
|
126
|
-
const [currentItems, setCurrentItems] = useState(initialItems);
|
|
126
|
+
const [currentItems, setCurrentItems] = useState(initialItems);
|
|
127
|
+
const [otherItems, setOtherItems] = useState(items); // We need to store the current value as well to be able to highlight it
|
|
127
128
|
|
|
128
129
|
const [currentValue, setCurrentValue] = useState(value ?? initialValue);
|
|
129
130
|
const inputTokens = {
|
|
@@ -133,7 +134,9 @@ const Autocomplete = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
133
134
|
const openOverlayRef = useRef();
|
|
134
135
|
const [isExpanded, setIsExpanded] = useState(((_ref3 = value ?? initialValue) === null || _ref3 === void 0 ? void 0 : _ref3.length) >= minToSuggestion);
|
|
135
136
|
const [isFocused, setisFocused] = useState(false);
|
|
136
|
-
const [sourceLayout, setSourceLayout] = useState(null);
|
|
137
|
+
const [sourceLayout, setSourceLayout] = useState(null); // When it's nested, selected value
|
|
138
|
+
|
|
139
|
+
const [nestedSelectedValue, setNestedSelectedValue] = useState(null);
|
|
137
140
|
const {
|
|
138
141
|
supportsProps,
|
|
139
142
|
...selectedProps
|
|
@@ -229,22 +232,49 @@ const Autocomplete = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
229
232
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedId);
|
|
230
233
|
const {
|
|
231
234
|
label: newValue,
|
|
232
|
-
nested
|
|
235
|
+
nested,
|
|
236
|
+
title
|
|
233
237
|
} = (_ref5 = isControlled ? items : currentItems) === null || _ref5 === void 0 ? void 0 : _ref5.find(_ref6 => {
|
|
234
238
|
let {
|
|
235
239
|
id
|
|
236
240
|
} = _ref6;
|
|
237
241
|
return id === selectedId;
|
|
238
242
|
});
|
|
243
|
+
if (title) return;
|
|
239
244
|
|
|
240
245
|
if (!nested) {
|
|
246
|
+
setNestedSelectedValue(null);
|
|
241
247
|
onChange === null || onChange === void 0 ? void 0 : onChange(newValue);
|
|
242
248
|
setIsExpanded(false);
|
|
243
249
|
}
|
|
244
250
|
|
|
245
251
|
setCurrentValue(newValue);
|
|
246
252
|
if (!isControlled && inputRef !== null && inputRef !== void 0 && inputRef.current) inputRef.current.value = newValue;
|
|
253
|
+
if (nested) setNestedSelectedValue(newValue);
|
|
247
254
|
};
|
|
255
|
+
/**
|
|
256
|
+
* When an item that is nested equal "true" is selected this useEffect is executed.
|
|
257
|
+
* The nested item is added to the item list at the top, the if validates it doesn't exist
|
|
258
|
+
* within the list, if doesn't exist the nested item is added to the top of the list,
|
|
259
|
+
* the nested item is added with an id equal "0"
|
|
260
|
+
*/
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
useEffect(() => {
|
|
264
|
+
if (nestedSelectedValue && !items.find(item => item.id === 0)) {
|
|
265
|
+
const tmpItems = [...items];
|
|
266
|
+
tmpItems.unshift({
|
|
267
|
+
label: nestedSelectedValue,
|
|
268
|
+
title: true,
|
|
269
|
+
id: 0
|
|
270
|
+
});
|
|
271
|
+
setOtherItems(tmpItems.map(item => {
|
|
272
|
+
return { ...item,
|
|
273
|
+
nestedChild: item.id !== 0
|
|
274
|
+
};
|
|
275
|
+
}));
|
|
276
|
+
}
|
|
277
|
+
}, [nestedSelectedValue, items]);
|
|
248
278
|
|
|
249
279
|
const handleClose = event => {
|
|
250
280
|
var _openOverlayRef$curre, _openOverlayRef$curre2;
|
|
@@ -252,6 +282,7 @@ const Autocomplete = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
252
282
|
if (event.type === 'keydown') {
|
|
253
283
|
if (event.key === 'Escape' || event.key === 27) {
|
|
254
284
|
setIsExpanded(false);
|
|
285
|
+
setNestedSelectedValue(null);
|
|
255
286
|
} else if (event.key === 'ArrowDown' && isExpanded && !isLoading && targetRef !== null && targetRef !== void 0 && targetRef.current) {
|
|
256
287
|
targetRef.current.focus();
|
|
257
288
|
}
|
|
@@ -262,6 +293,7 @@ const Autocomplete = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
262
293
|
} else if (Platform.OS === 'web') {
|
|
263
294
|
// needed for dropdown to be collapsed when clicking outside on web
|
|
264
295
|
setIsExpanded(false);
|
|
296
|
+
setNestedSelectedValue(null);
|
|
265
297
|
}
|
|
266
298
|
};
|
|
267
299
|
|
|
@@ -336,7 +368,7 @@ const Autocomplete = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
336
368
|
}) : /*#__PURE__*/_jsx(Suggestions, {
|
|
337
369
|
hasResults: getCopy('hasResults'),
|
|
338
370
|
id: "autocomplete",
|
|
339
|
-
items: itemsToShow,
|
|
371
|
+
items: nestedSelectedValue ? itemsToSuggest(highlight(otherItems, nestedSelectedValue, resultsTextColor)) : itemsToShow,
|
|
340
372
|
noResults: helpTextToShow,
|
|
341
373
|
onClose: handleClose,
|
|
342
374
|
onSelect: handleSelect,
|
|
@@ -6,7 +6,7 @@ import View from "react-native-web/dist/exports/View";
|
|
|
6
6
|
import buttonPropTypes, { textAndA11yText } from './propTypes';
|
|
7
7
|
import ButtonBase from './ButtonBase';
|
|
8
8
|
import { useThemeTokensCallback } from '../ThemeProvider';
|
|
9
|
-
import { a11yProps, focusHandlerProps, resolvePressableState, selectTokens, useInputValue } from '../utils';
|
|
9
|
+
import { a11yProps, getTokensPropType, focusHandlerProps, resolvePressableState, selectTokens, useInputValue } from '../utils';
|
|
10
10
|
import Icon from '../Icon';
|
|
11
11
|
import { getStackedContent } from '../StackView';
|
|
12
12
|
import { getPressHandlersWithArgs } from '../utils/pressability';
|
|
@@ -151,6 +151,7 @@ ButtonDropdown.propTypes = { ...a11yProps.types,
|
|
|
151
151
|
...focusHandlerProps.types,
|
|
152
152
|
...buttonPropTypes,
|
|
153
153
|
children: textAndA11yText,
|
|
154
|
+
tokens: getTokensPropType('ButtonDropdown'),
|
|
154
155
|
|
|
155
156
|
/**
|
|
156
157
|
* Callback called when a controlled ButtonDropdown gets interacted with.
|
|
@@ -140,6 +140,7 @@ const Listbox = _ref => {
|
|
|
140
140
|
};
|
|
141
141
|
|
|
142
142
|
Listbox.propTypes = { ...withLinkRouter.propTypes,
|
|
143
|
+
tokens: getTokensPropType('Listbox'),
|
|
143
144
|
|
|
144
145
|
/**
|
|
145
146
|
* Focus will be moved to the item with this ref once within the menu.
|
|
@@ -165,8 +166,7 @@ Listbox.propTypes = { ...withLinkRouter.propTypes,
|
|
|
165
166
|
/**
|
|
166
167
|
* onClose event
|
|
167
168
|
*/
|
|
168
|
-
onClose: PropTypes.func
|
|
169
|
-
tokens: getTokensPropType('Listbox')
|
|
169
|
+
onClose: PropTypes.func
|
|
170
170
|
};
|
|
171
171
|
Listbox.Overlay = DropdownOverlay;
|
|
172
172
|
export default Listbox;
|
|
@@ -15,6 +15,9 @@ const styles = StyleSheet.create({
|
|
|
15
15
|
},
|
|
16
16
|
childContainer: {
|
|
17
17
|
paddingLeft: 16
|
|
18
|
+
},
|
|
19
|
+
nestedChildContainer: {
|
|
20
|
+
paddingLeft: 24
|
|
18
21
|
}
|
|
19
22
|
});
|
|
20
23
|
const ListboxItem = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
@@ -22,6 +25,7 @@ const ListboxItem = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
22
25
|
href,
|
|
23
26
|
label,
|
|
24
27
|
isChild = false,
|
|
28
|
+
nestedChild,
|
|
25
29
|
onBlur,
|
|
26
30
|
nextItemRef,
|
|
27
31
|
prevItemRef,
|
|
@@ -41,7 +45,7 @@ const ListboxItem = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
41
45
|
isChild
|
|
42
46
|
});
|
|
43
47
|
return /*#__PURE__*/_jsx(View, {
|
|
44
|
-
style: [styles.itemContainer, isChild && styles.childContainer],
|
|
48
|
+
style: [styles.itemContainer, isChild && styles.childContainer, nestedChild && styles.nestedChildContainer],
|
|
45
49
|
role: "option",
|
|
46
50
|
children: /*#__PURE__*/_jsx(PressableItem, {
|
|
47
51
|
href: href,
|
|
@@ -66,6 +70,7 @@ ListboxItem.propTypes = { ...selectedSystemPropTypes,
|
|
|
66
70
|
label: PropTypes.node.isRequired,
|
|
67
71
|
nextItemRef: PropTypes.object,
|
|
68
72
|
prevItemRef: PropTypes.object,
|
|
69
|
-
onPress: PropTypes.func
|
|
73
|
+
onPress: PropTypes.func,
|
|
74
|
+
nestedChild: PropTypes.bool
|
|
70
75
|
};
|
|
71
76
|
export default withLinkRouter(ListboxItem);
|
|
@@ -405,9 +405,9 @@ MultiSelectFilter.propTypes = {
|
|
|
405
405
|
variant: variantProp.propType,
|
|
406
406
|
|
|
407
407
|
/**
|
|
408
|
-
* Sets the tokens for
|
|
408
|
+
* Sets the tokens for MultiSelectFilter element.
|
|
409
409
|
*/
|
|
410
|
-
tokens: getTokensPropType('
|
|
410
|
+
tokens: getTokensPropType('MultiSelectFilter'),
|
|
411
411
|
|
|
412
412
|
/**
|
|
413
413
|
* The options a user may select.
|
package/package.json
CHANGED
|
@@ -64,15 +64,14 @@
|
|
|
64
64
|
"lint": "npm run --prefix ../.. lint:path -- --color packages/components-base",
|
|
65
65
|
"lint:fix": "npm run --prefix ../.. lint:path -- --fix packages/components-base",
|
|
66
66
|
"format": "prettier --write .",
|
|
67
|
-
"build": "npm run build:code
|
|
67
|
+
"build": "npm run build:code",
|
|
68
68
|
"build:main": "babel src -d lib",
|
|
69
69
|
"build:module": "babel src -d lib-module --env-name module",
|
|
70
|
-
"build:code": "npm run build:main && npm run build:module"
|
|
71
|
-
"build:docs": "babel-node --plugins=@telus-uds/babel-plugin-react-docgen generate-component-docs.js"
|
|
70
|
+
"build:code": "npm run build:main && npm run build:module"
|
|
72
71
|
},
|
|
73
72
|
"sideEffects": false,
|
|
74
73
|
"standard-engine": {
|
|
75
74
|
"skip": true
|
|
76
75
|
},
|
|
77
|
-
"version": "1.
|
|
76
|
+
"version": "1.63.0"
|
|
78
77
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable react/require-default-props */
|
|
2
|
-
import React, { forwardRef, useRef, useState } from 'react'
|
|
2
|
+
import React, { forwardRef, useEffect, useRef, useState } from 'react'
|
|
3
3
|
import PropTypes from 'prop-types'
|
|
4
4
|
import { Dimensions, Platform, View, StyleSheet } from 'react-native'
|
|
5
5
|
import throttle from 'lodash.throttle'
|
|
@@ -118,6 +118,8 @@ const Autocomplete = forwardRef(
|
|
|
118
118
|
// We need to store current items for uncontrolled usage
|
|
119
119
|
const [currentItems, setCurrentItems] = useState(initialItems)
|
|
120
120
|
|
|
121
|
+
const [otherItems, setOtherItems] = useState(items)
|
|
122
|
+
|
|
121
123
|
// We need to store the current value as well to be able to highlight it
|
|
122
124
|
const [currentValue, setCurrentValue] = useState(value ?? initialValue)
|
|
123
125
|
const inputTokens = { paddingLeft: INPUT_LEFT_PADDING }
|
|
@@ -128,6 +130,9 @@ const Autocomplete = forwardRef(
|
|
|
128
130
|
const [isFocused, setisFocused] = useState(false)
|
|
129
131
|
const [sourceLayout, setSourceLayout] = useState(null)
|
|
130
132
|
|
|
133
|
+
// When it's nested, selected value
|
|
134
|
+
const [nestedSelectedValue, setNestedSelectedValue] = useState(null)
|
|
135
|
+
|
|
131
136
|
const { supportsProps, ...selectedProps } = selectProps(rest)
|
|
132
137
|
const { hint, label: inputLabel } = supportsProps
|
|
133
138
|
const hintExpansionEnabled = isFocused && helpText && !currentValue
|
|
@@ -197,21 +202,49 @@ const Autocomplete = forwardRef(
|
|
|
197
202
|
}
|
|
198
203
|
const handleSelect = (selectedId) => {
|
|
199
204
|
onSelect?.(selectedId)
|
|
200
|
-
const {
|
|
201
|
-
|
|
202
|
-
|
|
205
|
+
const {
|
|
206
|
+
label: newValue,
|
|
207
|
+
nested,
|
|
208
|
+
title
|
|
209
|
+
} = (isControlled ? items : currentItems)?.find(({ id }) => id === selectedId)
|
|
210
|
+
if (title) return
|
|
203
211
|
if (!nested) {
|
|
212
|
+
setNestedSelectedValue(null)
|
|
204
213
|
onChange?.(newValue)
|
|
205
214
|
setIsExpanded(false)
|
|
206
215
|
}
|
|
207
216
|
setCurrentValue(newValue)
|
|
208
217
|
if (!isControlled && inputRef?.current) inputRef.current.value = newValue
|
|
218
|
+
|
|
219
|
+
if (nested) setNestedSelectedValue(newValue)
|
|
209
220
|
}
|
|
210
221
|
|
|
222
|
+
/**
|
|
223
|
+
* When an item that is nested equal "true" is selected this useEffect is executed.
|
|
224
|
+
* The nested item is added to the item list at the top, the if validates it doesn't exist
|
|
225
|
+
* within the list, if doesn't exist the nested item is added to the top of the list,
|
|
226
|
+
* the nested item is added with an id equal "0"
|
|
227
|
+
*/
|
|
228
|
+
useEffect(() => {
|
|
229
|
+
if (nestedSelectedValue && !items.find((item) => item.id === 0)) {
|
|
230
|
+
const tmpItems = [...items]
|
|
231
|
+
tmpItems.unshift({ label: nestedSelectedValue, title: true, id: 0 })
|
|
232
|
+
setOtherItems(
|
|
233
|
+
tmpItems.map((item) => {
|
|
234
|
+
return {
|
|
235
|
+
...item,
|
|
236
|
+
nestedChild: item.id !== 0
|
|
237
|
+
}
|
|
238
|
+
})
|
|
239
|
+
)
|
|
240
|
+
}
|
|
241
|
+
}, [nestedSelectedValue, items])
|
|
242
|
+
|
|
211
243
|
const handleClose = (event) => {
|
|
212
244
|
if (event.type === 'keydown') {
|
|
213
245
|
if (event.key === 'Escape' || event.key === 27) {
|
|
214
246
|
setIsExpanded(false)
|
|
247
|
+
setNestedSelectedValue(null)
|
|
215
248
|
} else if (event.key === 'ArrowDown' && isExpanded && !isLoading && targetRef?.current) {
|
|
216
249
|
targetRef.current.focus()
|
|
217
250
|
}
|
|
@@ -232,6 +265,7 @@ const Autocomplete = forwardRef(
|
|
|
232
265
|
} else if (Platform.OS === 'web') {
|
|
233
266
|
// needed for dropdown to be collapsed when clicking outside on web
|
|
234
267
|
setIsExpanded(false)
|
|
268
|
+
setNestedSelectedValue(null)
|
|
235
269
|
}
|
|
236
270
|
}
|
|
237
271
|
const itemsToShow = currentValue
|
|
@@ -308,7 +342,11 @@ const Autocomplete = forwardRef(
|
|
|
308
342
|
<Suggestions
|
|
309
343
|
hasResults={getCopy('hasResults')}
|
|
310
344
|
id="autocomplete"
|
|
311
|
-
items={
|
|
345
|
+
items={
|
|
346
|
+
nestedSelectedValue
|
|
347
|
+
? itemsToSuggest(highlight(otherItems, nestedSelectedValue, resultsTextColor))
|
|
348
|
+
: itemsToShow
|
|
349
|
+
}
|
|
312
350
|
noResults={helpTextToShow}
|
|
313
351
|
onClose={handleClose}
|
|
314
352
|
onSelect={handleSelect}
|
|
@@ -6,6 +6,7 @@ import ButtonBase from './ButtonBase'
|
|
|
6
6
|
import { useThemeTokensCallback } from '../ThemeProvider'
|
|
7
7
|
import {
|
|
8
8
|
a11yProps,
|
|
9
|
+
getTokensPropType,
|
|
9
10
|
focusHandlerProps,
|
|
10
11
|
resolvePressableState,
|
|
11
12
|
selectTokens,
|
|
@@ -153,6 +154,8 @@ ButtonDropdown.propTypes = {
|
|
|
153
154
|
...focusHandlerProps.types,
|
|
154
155
|
...buttonPropTypes,
|
|
155
156
|
children: textAndA11yText,
|
|
157
|
+
tokens: getTokensPropType('ButtonDropdown'),
|
|
158
|
+
|
|
156
159
|
/**
|
|
157
160
|
* Callback called when a controlled ButtonDropdown gets interacted with.
|
|
158
161
|
*/
|
package/src/Listbox/Listbox.jsx
CHANGED
|
@@ -136,6 +136,7 @@ const Listbox = ({
|
|
|
136
136
|
|
|
137
137
|
Listbox.propTypes = {
|
|
138
138
|
...withLinkRouter.propTypes,
|
|
139
|
+
tokens: getTokensPropType('Listbox'),
|
|
139
140
|
/**
|
|
140
141
|
* Focus will be moved to the item with this ref once within the menu.
|
|
141
142
|
*/
|
|
@@ -156,8 +157,7 @@ Listbox.propTypes = {
|
|
|
156
157
|
/**
|
|
157
158
|
* onClose event
|
|
158
159
|
*/
|
|
159
|
-
onClose: PropTypes.func
|
|
160
|
-
tokens: getTokensPropType('Listbox')
|
|
160
|
+
onClose: PropTypes.func
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
Listbox.Overlay = DropdownOverlay
|
|
@@ -15,6 +15,9 @@ const styles = StyleSheet.create({
|
|
|
15
15
|
},
|
|
16
16
|
childContainer: {
|
|
17
17
|
paddingLeft: 16
|
|
18
|
+
},
|
|
19
|
+
nestedChildContainer: {
|
|
20
|
+
paddingLeft: 24
|
|
18
21
|
}
|
|
19
22
|
})
|
|
20
23
|
|
|
@@ -24,6 +27,7 @@ const ListboxItem = forwardRef(
|
|
|
24
27
|
href,
|
|
25
28
|
label,
|
|
26
29
|
isChild = false,
|
|
30
|
+
nestedChild,
|
|
27
31
|
onBlur,
|
|
28
32
|
nextItemRef,
|
|
29
33
|
prevItemRef,
|
|
@@ -41,7 +45,14 @@ const ListboxItem = forwardRef(
|
|
|
41
45
|
|
|
42
46
|
const getTokens = useThemeTokensCallback('Listbox', tokens, variant, { isChild })
|
|
43
47
|
return (
|
|
44
|
-
<View
|
|
48
|
+
<View
|
|
49
|
+
style={[
|
|
50
|
+
styles.itemContainer,
|
|
51
|
+
isChild && styles.childContainer,
|
|
52
|
+
nestedChild && styles.nestedChildContainer
|
|
53
|
+
]}
|
|
54
|
+
role="option"
|
|
55
|
+
>
|
|
45
56
|
<PressableItem
|
|
46
57
|
href={href}
|
|
47
58
|
isChild={isChild}
|
|
@@ -70,7 +81,8 @@ ListboxItem.propTypes = {
|
|
|
70
81
|
label: PropTypes.node.isRequired,
|
|
71
82
|
nextItemRef: PropTypes.object,
|
|
72
83
|
prevItemRef: PropTypes.object,
|
|
73
|
-
onPress: PropTypes.func
|
|
84
|
+
onPress: PropTypes.func,
|
|
85
|
+
nestedChild: PropTypes.bool
|
|
74
86
|
}
|
|
75
87
|
|
|
76
88
|
export default withLinkRouter(ListboxItem)
|
|
@@ -344,9 +344,9 @@ MultiSelectFilter.propTypes = {
|
|
|
344
344
|
*/
|
|
345
345
|
variant: variantProp.propType,
|
|
346
346
|
/**
|
|
347
|
-
* Sets the tokens for
|
|
347
|
+
* Sets the tokens for MultiSelectFilter element.
|
|
348
348
|
*/
|
|
349
|
-
tokens: getTokensPropType('
|
|
349
|
+
tokens: getTokensPropType('MultiSelectFilter'),
|
|
350
350
|
/**
|
|
351
351
|
* The options a user may select.
|
|
352
352
|
*/
|