@telus-uds/components-base 2.3.0 → 2.5.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 +34 -2
- package/lib/A11yInfoProvider/index.js +2 -2
- package/lib/Autocomplete/Autocomplete.js +22 -32
- package/lib/Autocomplete/Suggestions.js +1 -1
- package/lib/BaseProvider/HydrationContext.js +1 -2
- package/lib/BaseProvider/index.js +1 -2
- package/lib/Button/ButtonDropdown.js +1 -1
- package/lib/Card/Card.js +12 -13
- package/lib/Card/CardBase.js +1 -1
- package/lib/Card/PressableCardBase.js +1 -1
- package/lib/CardGroup/CardGroup.js +3 -3
- package/lib/Carousel/Carousel.js +5 -6
- package/lib/Carousel/CarouselStepTracker/CarouselStepTracker.js +3 -0
- package/lib/Carousel/CarouselTabs/CarouselTabs.js +1 -2
- package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +1 -1
- package/lib/Carousel/CarouselTabs/CarouselTabsPanelItem.js +1 -1
- package/lib/Carousel/CarouselThumbnail.js +1 -1
- package/lib/Checkbox/Checkbox.js +1 -1
- package/lib/ColourToggle/ColourToggle.js +1 -1
- package/lib/ExpandCollapseMini/ExpandCollapseMini.js +77 -0
- package/lib/ExpandCollapseMini/ExpandCollapseMiniControl.js +126 -0
- package/lib/ExpandCollapseMini/index.js +2 -0
- package/lib/Footnote/Footnote.js +4 -4
- package/lib/HorizontalScroll/HorizontalScroll.js +1 -2
- package/lib/Icon/Icon.js +1 -1
- package/lib/Icon/IconText.js +2 -3
- package/lib/IconButton/IconButton.js +1 -2
- package/lib/InputLabel/InputLabel.js +36 -2
- package/lib/InputSupports/InputSupports.js +31 -8
- package/lib/InputSupports/dictionary.js +12 -0
- package/lib/InputSupports/useInputSupports.js +12 -3
- package/lib/Link/LinkBase.js +25 -18
- package/lib/List/List.js +1 -2
- package/lib/List/ListItemContent.js +1 -1
- package/lib/Listbox/Listbox.js +5 -8
- package/lib/Listbox/PressableItem.js +4 -4
- package/lib/Modal/Modal.js +4 -7
- package/lib/MultiSelectFilter/MultiSelectFilter.js +55 -42
- package/lib/Notification/Notification.js +15 -13
- package/lib/OrderedList/OrderedList.js +2 -3
- package/lib/Pagination/usePagination.js +1 -2
- package/lib/PriceLockup/utils/renderFootnoteContent.js +2 -2
- package/lib/PriceLockup/utils/renderFootnoteLinks.js +2 -2
- package/lib/PriceLockup/utils/renderPrice.js +2 -2
- package/lib/ProductCard/ProductCard.js +2 -3
- package/lib/Progress/ProgressBarBackground.js +2 -2
- package/lib/QuickLinksFeature/QuickLinksFeature.js +1 -2
- package/lib/Radio/Radio.js +1 -1
- package/lib/Search/Search.js +41 -11
- package/lib/Select/Picker.js +2 -2
- package/lib/Select/Picker.native.js +8 -4
- package/lib/Select/constants.js +4 -2
- package/lib/StackView/StackWrap.js +1 -4
- package/lib/StackView/getStackedContent.js +1 -2
- package/lib/StepTracker/StepTracker.js +1 -2
- package/lib/TabBar/TabBar.js +1 -1
- package/lib/Tabs/Tabs.js +1 -1
- package/lib/Tabs/TabsItem.js +2 -2
- package/lib/TextInput/TextArea.js +7 -6
- package/lib/TextInput/TextInput.js +7 -6
- package/lib/TextInput/TextInputBase.js +57 -25
- package/lib/ThemeProvider/utils/theme-tokens.js +2 -4
- package/lib/Timeline/Timeline.js +1 -2
- package/lib/Tooltip/Tooltip.native.js +4 -4
- package/lib/Typography/Typography.js +4 -5
- package/lib/Validator/Validator.js +9 -14
- package/lib/ViewportProvider/useViewportListener.js +1 -1
- package/lib/index.js +1 -0
- package/lib/utils/children.js +2 -6
- package/lib/utils/input.js +1 -1
- package/lib/utils/props/componentPropType.js +1 -2
- package/lib/utils/props/inputSupportsProps.js +15 -3
- package/lib/utils/props/selectSystemProps.js +2 -2
- package/lib/utils/ssr-media-query/create-stylesheet/create-stylesheet-mobile.js +1 -1
- package/lib/utils/ssr-media-query/create-stylesheet/index.js +2 -3
- package/lib/utils/ssr-media-query/utils/inject.js +3 -5
- package/lib/utils/useHash.js +1 -4
- package/lib/utils/useOverlaidPosition.js +25 -4
- package/lib/utils/useScrollBlocking.js +2 -4
- package/lib/utils/useSpacingScale.js +2 -2
- package/package.json +2 -2
- package/src/Carousel/CarouselStepTracker/CarouselStepTracker.jsx +3 -0
- package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +76 -0
- package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +119 -0
- package/src/ExpandCollapseMini/index.js +3 -0
- package/src/InputLabel/InputLabel.jsx +39 -2
- package/src/InputSupports/InputSupports.jsx +33 -7
- package/src/InputSupports/dictionary.js +12 -0
- package/src/InputSupports/useInputSupports.js +24 -3
- package/src/Link/LinkBase.jsx +25 -18
- package/src/Modal/Modal.jsx +1 -1
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +55 -27
- package/src/Notification/Notification.jsx +9 -3
- package/src/Search/Search.jsx +52 -24
- package/src/Select/Picker.native.jsx +10 -4
- package/src/Select/constants.js +4 -1
- package/src/TextInput/TextArea.jsx +12 -5
- package/src/TextInput/TextInput.jsx +13 -6
- package/src/TextInput/TextInputBase.jsx +57 -10
- package/src/index.js +1 -0
- package/src/utils/props/inputSupportsProps.js +15 -3
- package/src/utils/useOverlaidPosition.js +23 -0
package/lib/Tabs/TabsItem.js
CHANGED
|
@@ -142,9 +142,9 @@ const TabsItem = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
142
142
|
const scrollEnd = itemPositions.scrollOffset + itemPositions.containerWidth;
|
|
143
143
|
if (
|
|
144
144
|
// is off the right edge, or
|
|
145
|
-
scrollEnd &&
|
|
145
|
+
scrollEnd && position?.end > scrollEnd ||
|
|
146
146
|
// is off the left edge
|
|
147
|
-
typeof
|
|
147
|
+
typeof position?.start === 'number' && position.start < itemPositions.scrollOffset) {
|
|
148
148
|
itemPositions.scrollTo(position.start);
|
|
149
149
|
}
|
|
150
150
|
}
|
|
@@ -61,10 +61,6 @@ const TextArea = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
61
61
|
} = selectProps(rest);
|
|
62
62
|
const inputProps = {
|
|
63
63
|
...selectedProps,
|
|
64
|
-
variant: {
|
|
65
|
-
...variant,
|
|
66
|
-
validation: supportsProps.validation
|
|
67
|
-
},
|
|
68
64
|
multiline: true,
|
|
69
65
|
onContentSizeChange: onHeightChange,
|
|
70
66
|
height: inputHeight,
|
|
@@ -72,6 +68,7 @@ const TextArea = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
72
68
|
};
|
|
73
69
|
return /*#__PURE__*/_jsx(InputSupports, {
|
|
74
70
|
...supportsProps,
|
|
71
|
+
inputValue: selectedProps?.value,
|
|
75
72
|
children: _ref3 => {
|
|
76
73
|
let {
|
|
77
74
|
inputId,
|
|
@@ -79,9 +76,13 @@ const TextArea = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
79
76
|
} = _ref3;
|
|
80
77
|
return /*#__PURE__*/_jsx(TextInputBase, {
|
|
81
78
|
ref: ref,
|
|
82
|
-
...inputProps,
|
|
83
79
|
nativeID: inputId,
|
|
84
|
-
...props
|
|
80
|
+
...props,
|
|
81
|
+
...inputProps,
|
|
82
|
+
variant: {
|
|
83
|
+
...variant,
|
|
84
|
+
validation: props.validation
|
|
85
|
+
}
|
|
85
86
|
});
|
|
86
87
|
}
|
|
87
88
|
});
|
|
@@ -38,16 +38,13 @@ const TextInput = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
38
38
|
} = selectProps(rest);
|
|
39
39
|
const inputProps = {
|
|
40
40
|
...selectedProps,
|
|
41
|
-
tokens
|
|
42
|
-
variant: {
|
|
43
|
-
...variant,
|
|
44
|
-
validation: supportsProps.validation
|
|
45
|
-
}
|
|
41
|
+
tokens
|
|
46
42
|
};
|
|
47
43
|
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
48
44
|
children: [/*#__PURE__*/_jsx(InputSupports, {
|
|
49
45
|
nativeID: nativeID,
|
|
50
46
|
...supportsProps,
|
|
47
|
+
inputValue: selectedProps?.value,
|
|
51
48
|
children: _ref2 => {
|
|
52
49
|
let {
|
|
53
50
|
inputId,
|
|
@@ -57,7 +54,11 @@ const TextInput = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
57
54
|
ref: ref,
|
|
58
55
|
nativeID: inputId,
|
|
59
56
|
...propsFromInputSupports,
|
|
60
|
-
...inputProps
|
|
57
|
+
...inputProps,
|
|
58
|
+
variant: {
|
|
59
|
+
...variant,
|
|
60
|
+
validation: propsFromInputSupports.validation
|
|
61
|
+
}
|
|
61
62
|
});
|
|
62
63
|
}
|
|
63
64
|
}), rest.children]
|
|
@@ -37,6 +37,9 @@ const selectInputStyles = function (_ref, themeOptions, inactive, type) {
|
|
|
37
37
|
let buttonSize = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
|
|
38
38
|
let buttonsGapSize = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;
|
|
39
39
|
let isPassword = arguments.length > 7 ? arguments[7] : undefined;
|
|
40
|
+
let iconLeftWidth = arguments.length > 8 ? arguments[8] : undefined;
|
|
41
|
+
let iconLeftGap = arguments.length > 9 ? arguments[9] : undefined;
|
|
42
|
+
let direction = arguments.length > 10 ? arguments[10] : undefined;
|
|
40
43
|
// Subtract border width from padding so overall input width/height doesn't
|
|
41
44
|
// jump around if the border width changes (avoiding NaN and negative padding)
|
|
42
45
|
const offsetBorder = value => typeof value === 'number' ? Math.max(0, value - borderWidth) : value;
|
|
@@ -63,6 +66,15 @@ const selectInputStyles = function (_ref, themeOptions, inactive, type) {
|
|
|
63
66
|
resize: minHeight !== maxHeight ? 'vertical' : 'none' // does nothing for an input, only needed for textarea
|
|
64
67
|
}
|
|
65
68
|
});
|
|
69
|
+
const getPaddingLeft = () => {
|
|
70
|
+
if (type === 'card') {
|
|
71
|
+
return offsetBorder(paddingLeft + 34);
|
|
72
|
+
}
|
|
73
|
+
if (direction === 'left') {
|
|
74
|
+
return offsetBorder(iconLeftWidth + iconLeftGap + staticStyles.iconLeftContainer.paddingLeft);
|
|
75
|
+
}
|
|
76
|
+
return offsetBorder(paddingLeft);
|
|
77
|
+
};
|
|
66
78
|
const buttonSpacing = isPassword ? buttonsGapSize : -buttonsGapSize;
|
|
67
79
|
const adjustedPaddingRight = paddingRight + (buttonCount ? 1 : 0) * (buttonSize + buttonSpacing);
|
|
68
80
|
const adjustedPaddingWithButtons = buttonCount > 1 ? paddingRight : adjustedPaddingRight;
|
|
@@ -73,7 +85,7 @@ const selectInputStyles = function (_ref, themeOptions, inactive, type) {
|
|
|
73
85
|
borderWidth,
|
|
74
86
|
borderColor,
|
|
75
87
|
borderRadius,
|
|
76
|
-
paddingLeft:
|
|
88
|
+
paddingLeft: getPaddingLeft(),
|
|
77
89
|
paddingRight: icon ? offsetBorder(paddingWithIcon) : offsetBorder(adjustedPaddingWithButtons),
|
|
78
90
|
paddingTop: offsetBorder(paddingTop),
|
|
79
91
|
paddingBottom: offsetBorder(paddingBottom),
|
|
@@ -123,20 +135,26 @@ const selectIconContainerStyles = (_ref4, buttonCount) => {
|
|
|
123
135
|
paddingBottom
|
|
124
136
|
};
|
|
125
137
|
};
|
|
126
|
-
const
|
|
138
|
+
const selectIconCardLeftContainerStyles = _ref5 => {
|
|
127
139
|
let {
|
|
128
140
|
leftIconPaddingBottom
|
|
129
141
|
} = _ref5;
|
|
130
142
|
return {
|
|
131
|
-
// not tokenizing paddingLeft as it remains same across brands for now
|
|
132
|
-
paddingLeft: 10,
|
|
133
143
|
paddingBottom: leftIconPaddingBottom
|
|
134
144
|
};
|
|
135
145
|
};
|
|
136
|
-
const
|
|
146
|
+
const selectIconLeftContainerStyles = _ref6 => {
|
|
137
147
|
let {
|
|
138
|
-
|
|
148
|
+
iconLeftPaddingBottom
|
|
139
149
|
} = _ref6;
|
|
150
|
+
return {
|
|
151
|
+
paddingBottom: iconLeftPaddingBottom
|
|
152
|
+
};
|
|
153
|
+
};
|
|
154
|
+
const selectButtonsContainerStyle = _ref7 => {
|
|
155
|
+
let {
|
|
156
|
+
buttonsPaddingRight
|
|
157
|
+
} = _ref7;
|
|
140
158
|
return {
|
|
141
159
|
paddingRight: buttonsPaddingRight
|
|
142
160
|
};
|
|
@@ -180,7 +198,7 @@ const getIcon = function () {
|
|
|
180
198
|
testID: selectedIcon.testID
|
|
181
199
|
});
|
|
182
200
|
};
|
|
183
|
-
const TextInputBase = /*#__PURE__*/React.forwardRef((
|
|
201
|
+
const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
184
202
|
let {
|
|
185
203
|
buttons = [],
|
|
186
204
|
copy = 'en',
|
|
@@ -201,8 +219,9 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
201
219
|
variant = {},
|
|
202
220
|
type,
|
|
203
221
|
onKeyPress,
|
|
222
|
+
direction,
|
|
204
223
|
...rest
|
|
205
|
-
} =
|
|
224
|
+
} = _ref8;
|
|
206
225
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
207
226
|
const [showPassword, setShowPassword] = React.useState(false);
|
|
208
227
|
const handleFocus = event => {
|
|
@@ -243,7 +262,7 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
243
262
|
} = variant;
|
|
244
263
|
const isNumeric = numeric || type === 'card' || type === 'number';
|
|
245
264
|
const isPassword = password || type === 'password';
|
|
246
|
-
const element = inputRef
|
|
265
|
+
const element = inputRef?.current;
|
|
247
266
|
React.useEffect(() => {
|
|
248
267
|
if (Platform.OS === 'web' && pattern && element) {
|
|
249
268
|
// React Native Web doesn't support `pattern`, so we have to attach it via a ref,
|
|
@@ -252,9 +271,8 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
252
271
|
}
|
|
253
272
|
}, [element, pattern]);
|
|
254
273
|
const handleChangeText = event => {
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
let filteredText = isNumeric ? text === null || text === void 0 ? void 0 : text.replace(/[^\d]/g, '') : text;
|
|
274
|
+
const text = event.nativeEvent?.text || event.target?.value;
|
|
275
|
+
let filteredText = isNumeric ? text?.replace(/[^\d]/g, '') : text;
|
|
258
276
|
if (type === 'card' && filteredText) {
|
|
259
277
|
const formattedValue = filteredText.replace(/[^a-zA-Z0-9]/g, '');
|
|
260
278
|
const regex = new RegExp(`([a-zA-Z0-9]{4})(?=[a-zA-Z0-9])`, 'g');
|
|
@@ -271,10 +289,9 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
271
289
|
};
|
|
272
290
|
const themeTokens = useThemeTokens('TextInput', tokens, variant, states);
|
|
273
291
|
const handleClear = event => {
|
|
274
|
-
|
|
275
|
-
onClear === null || onClear === void 0 || onClear(event);
|
|
292
|
+
onClear?.(event);
|
|
276
293
|
resetValue(event);
|
|
277
|
-
inputRef
|
|
294
|
+
inputRef?.current?.focus();
|
|
278
295
|
};
|
|
279
296
|
const handleShowOrHide = () => {
|
|
280
297
|
if (!variant.inactive) setShowPassword(!showPassword);
|
|
@@ -288,16 +305,18 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
288
305
|
defaultCreditIcon,
|
|
289
306
|
amexIcon,
|
|
290
307
|
visaIcon,
|
|
291
|
-
masterCardIcon
|
|
308
|
+
masterCardIcon,
|
|
309
|
+
iconLeftGap
|
|
292
310
|
} = themeTokens;
|
|
293
311
|
const buttonsGapSize = useSpacingScale(buttonsGap);
|
|
294
312
|
const getCopy = useCopy({
|
|
295
313
|
dictionary,
|
|
296
314
|
copy
|
|
297
315
|
});
|
|
298
|
-
const textInputButtons = buttons;
|
|
316
|
+
const textInputButtons = direction === 'left' ? buttons.filter(button => button && button.key !== 'submitIcon') : buttons;
|
|
317
|
+
const submitIcon = direction === 'left' ? buttons.find(button => button && button.key === 'submitIcon') : null;
|
|
299
318
|
if (onClear && isDirty) {
|
|
300
|
-
textInputButtons
|
|
319
|
+
textInputButtons?.unshift(/*#__PURE__*/_jsx(IconButton, {
|
|
301
320
|
accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
|
|
302
321
|
icon: ClearButtonIcon,
|
|
303
322
|
onPress: handleClear,
|
|
@@ -307,7 +326,7 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
307
326
|
}, "clear"));
|
|
308
327
|
}
|
|
309
328
|
if (isPassword) {
|
|
310
|
-
textInputButtons
|
|
329
|
+
textInputButtons?.unshift(/*#__PURE__*/_jsx(IconButton, {
|
|
311
330
|
accessibilityLabel: showPassword ? getCopy('hidePasswordAccessibilityLabel') : getCopy('showPasswordAccessibilityLabel'),
|
|
312
331
|
icon: !showPassword ? passwordShowButtonIcon : passwordHideButtonIcon,
|
|
313
332
|
onPress: handleShowOrHide,
|
|
@@ -339,15 +358,20 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
339
358
|
const {
|
|
340
359
|
themeOptions
|
|
341
360
|
} = useTheme();
|
|
361
|
+
const iconLeftWidth = submitIcon ? submitIcon.props.tokens.size ?? 0 : 0;
|
|
342
362
|
const nativeInputStyle = selectInputStyles({
|
|
343
363
|
...themeTokens,
|
|
344
364
|
height
|
|
345
|
-
}, themeOptions, inactive, type, buttons
|
|
365
|
+
}, themeOptions, inactive, type, buttons?.length, themeTokens.buttonSize, buttonsGapSize, isPassword, iconLeftWidth, iconLeftGap, direction);
|
|
366
|
+
const shouldShowSubmitIcon = submitIcon && direction === 'left' && !inactive;
|
|
346
367
|
return /*#__PURE__*/_jsxs(View, {
|
|
347
368
|
style: selectOuterBorderStyles(themeTokens),
|
|
348
|
-
children: [
|
|
369
|
+
children: [shouldShowSubmitIcon && /*#__PURE__*/_jsx(View, {
|
|
370
|
+
style: [staticStyles.iconLeftContainer, selectIconLeftContainerStyles(themeTokens)],
|
|
371
|
+
children: submitIcon
|
|
372
|
+
}), type === 'card' && /*#__PURE__*/_jsx(View, {
|
|
349
373
|
pointerEvents: "none",
|
|
350
|
-
style: [staticStyles.
|
|
374
|
+
style: [staticStyles.iconCardLeftContainer, selectIconCardLeftContainerStyles(themeTokens)],
|
|
351
375
|
children: getIcon(currentValue, {
|
|
352
376
|
defaultCreditIcon,
|
|
353
377
|
amexIcon,
|
|
@@ -367,11 +391,11 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
367
391
|
style: [staticStyles.rightIconContainer, selectIconContainerStyles({
|
|
368
392
|
...themeTokens,
|
|
369
393
|
buttonsGapSize
|
|
370
|
-
}, buttons
|
|
394
|
+
}, buttons?.length)],
|
|
371
395
|
children: /*#__PURE__*/_jsx(IconComponent, {
|
|
372
396
|
...selectIconTokens(themeTokens)
|
|
373
397
|
})
|
|
374
|
-
}),
|
|
398
|
+
}), buttons?.length > 0 && !inactive && /*#__PURE__*/_jsx(View, {
|
|
375
399
|
style: [staticStyles.buttonsContainer, selectButtonsContainerStyle(themeTokens)],
|
|
376
400
|
children: /*#__PURE__*/_jsx(StackView, {
|
|
377
401
|
direction: "row",
|
|
@@ -425,7 +449,15 @@ const staticStyles = StyleSheet.create({
|
|
|
425
449
|
right: 0,
|
|
426
450
|
bottom: 0
|
|
427
451
|
},
|
|
428
|
-
|
|
452
|
+
iconCardLeftContainer: {
|
|
453
|
+
paddingLeft: 10,
|
|
454
|
+
position: 'absolute',
|
|
455
|
+
left: 0,
|
|
456
|
+
bottom: 0,
|
|
457
|
+
zIndex: 1
|
|
458
|
+
},
|
|
459
|
+
iconLeftContainer: {
|
|
460
|
+
paddingLeft: 10,
|
|
429
461
|
position: 'absolute',
|
|
430
462
|
left: 0,
|
|
431
463
|
bottom: 0,
|
|
@@ -13,13 +13,12 @@ import pkg from '../../../package.json';
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
export const getComponentTheme = (theme, componentName) => {
|
|
16
|
-
var _theme$metadata;
|
|
17
16
|
// Give clear and understandable error messages for common dev errors, for example,
|
|
18
17
|
// typo in component name, missing export or accessing old version of theme
|
|
19
18
|
if (!theme) {
|
|
20
19
|
throw new Error(`Called useTheme's getStyle on "${componentName}" with no theme provided`);
|
|
21
20
|
}
|
|
22
|
-
const themeName =
|
|
21
|
+
const themeName = theme.metadata?.name || '';
|
|
23
22
|
if (!theme.components) {
|
|
24
23
|
throw new Error(`Theme "${themeName}" has no components defined (looking for "${componentName}")`);
|
|
25
24
|
}
|
|
@@ -147,9 +146,8 @@ export const toArray = strOrArr => Array.isArray(strOrArr) ? strOrArr : [strOrAr
|
|
|
147
146
|
* @param {object} theme - UDS theme built for react-native
|
|
148
147
|
*/
|
|
149
148
|
export const validateThemeTokensVersion = theme => {
|
|
150
|
-
var _theme$metadata2;
|
|
151
149
|
const expectedThemeTokensVersion = pkg.dependencies['@telus-uds/system-theme-tokens'];
|
|
152
|
-
const actualThemeTokensVersion = theme
|
|
150
|
+
const actualThemeTokensVersion = theme?.metadata?.themeTokensVersion;
|
|
153
151
|
if (!semVerSatisfies(actualThemeTokensVersion, expectedThemeTokensVersion)) {
|
|
154
152
|
throw new Error(`Invalid UDS token schema version detected.
|
|
155
153
|
|
package/lib/Timeline/Timeline.js
CHANGED
|
@@ -117,10 +117,9 @@ const Timeline = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
117
117
|
ref: ref,
|
|
118
118
|
style: selectTimelineContainerStyle(themeTokens),
|
|
119
119
|
children: children.map((child, index) => {
|
|
120
|
-
var _child$props;
|
|
121
120
|
const accessibilityRole = Platform.OS !== 'android' ? 'listitem' : undefined;
|
|
122
121
|
const childrenProps = {
|
|
123
|
-
...getA11yPropsFromHtmlTag(childrenTag,
|
|
122
|
+
...getA11yPropsFromHtmlTag(childrenTag, child?.props?.accessibilityRole || accessibilityRole)
|
|
124
123
|
};
|
|
125
124
|
return /*#__PURE__*/_jsxs(View, {
|
|
126
125
|
style: selectLineItemContainer(themeTokens)
|
|
@@ -186,7 +186,7 @@ const Tooltip = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
186
186
|
} = _ref8;
|
|
187
187
|
setWindowDimensions(window);
|
|
188
188
|
});
|
|
189
|
-
return () => subscription
|
|
189
|
+
return () => subscription?.remove();
|
|
190
190
|
});
|
|
191
191
|
const toggleIsOpen = () => {
|
|
192
192
|
onPress();
|
|
@@ -245,7 +245,7 @@ const Tooltip = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
245
245
|
setIsOpen(false);
|
|
246
246
|
}, [windowDimensions]);
|
|
247
247
|
React.useEffect(() => {
|
|
248
|
-
if (tooltipPosition !== null && !
|
|
248
|
+
if (tooltipPosition !== null && !tooltipPosition?.isNormalized || !isOpen || controlLayout === null || tooltipDimensions == null) {
|
|
249
249
|
return;
|
|
250
250
|
}
|
|
251
251
|
const updatedPosition = getTooltipPosition(position, {
|
|
@@ -257,7 +257,7 @@ const Tooltip = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
257
257
|
});
|
|
258
258
|
|
|
259
259
|
// avoid ending up in an infinite normalization loop
|
|
260
|
-
if (tooltipPosition
|
|
260
|
+
if (tooltipPosition?.isNormalized && updatedPosition.isNormalized) {
|
|
261
261
|
return;
|
|
262
262
|
}
|
|
263
263
|
setTooltipPosition(updatedPosition);
|
|
@@ -322,7 +322,7 @@ const Tooltip = /*#__PURE__*/React.forwardRef((_ref7, ref) => {
|
|
|
322
322
|
ref: ref,
|
|
323
323
|
style: [staticStyles.tooltip, selectTooltipShadowStyles(themeTokens),
|
|
324
324
|
// applied separately so that it doesn't cover the arrow
|
|
325
|
-
selectToolTipSizeStyles(themeTokens), tooltipPosition && selectTooltipPositionStyles(tooltipPosition), (tooltipPosition === null ||
|
|
325
|
+
selectToolTipSizeStyles(themeTokens), tooltipPosition && selectTooltipPositionStyles(tooltipPosition), (tooltipPosition === null || tooltipPosition?.isNormalized) && staticStyles.tooltipHidden // visually hide the tooltip until we have a final measurement
|
|
326
326
|
],
|
|
327
327
|
onLayout: onTooltipLayout,
|
|
328
328
|
accessibilityRole: "alert",
|
|
@@ -162,15 +162,14 @@ const Typography = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
162
162
|
...selectContainerProps(rest)
|
|
163
163
|
};
|
|
164
164
|
const resetTagStyling = child => {
|
|
165
|
-
|
|
166
|
-
if (typeof child !== 'object' || !((child === null || child === void 0 ? void 0 : child.type) === 'sub' || (child === null || child === void 0 ? void 0 : child.type) === 'sup')) {
|
|
165
|
+
if (typeof child !== 'object' || !(child?.type === 'sub' || child?.type === 'sup')) {
|
|
167
166
|
return child;
|
|
168
167
|
}
|
|
169
|
-
const childStyles =
|
|
168
|
+
const childStyles = child?.props?.style || {};
|
|
170
169
|
const supFontSize = childStyles.fontSize ?? themeTokens.superScriptFontSize;
|
|
171
170
|
const isMobile = Platform.OS === 'ios' || Platform.OS === 'android';
|
|
172
|
-
const isSubSup =
|
|
173
|
-
const mobileStyles = isMobile && isSubSup ? selectMobileSubSupStyles(themeTokens, child
|
|
171
|
+
const isSubSup = child?.type === 'sub' || child?.type === 'sup';
|
|
172
|
+
const mobileStyles = isMobile && isSubSup ? selectMobileSubSupStyles(themeTokens, child?.type) : {};
|
|
174
173
|
const defaultStyles = !isMobile && isSubSup ? {
|
|
175
174
|
fontSize: supFontSize,
|
|
176
175
|
lineHeight: 0
|
|
@@ -83,21 +83,20 @@ const Validator = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
83
83
|
if (typeof onChange === 'function') onChange(code, singleCodes);
|
|
84
84
|
};
|
|
85
85
|
const handleChangeCodeValues = (event, codeId, nextIndex) => {
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
const val = ((_event$nativeEvent = event.nativeEvent) === null || _event$nativeEvent === void 0 ? void 0 : _event$nativeEvent.value) || ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.value);
|
|
86
|
+
const codeElement = codeReferences[codeId]?.current;
|
|
87
|
+
const val = event.nativeEvent?.value || event.target?.value;
|
|
89
88
|
if (Number(val).toString() === 'NaN') {
|
|
90
89
|
codeElement.value = singleCodes[codeId] ?? '';
|
|
91
90
|
return;
|
|
92
91
|
}
|
|
93
|
-
handleSingleCodes(codeId,
|
|
92
|
+
handleSingleCodes(codeId, codeElement?.value ?? singleCodes[codeId], 'success');
|
|
94
93
|
handleChangeCode();
|
|
95
94
|
if (nextIndex === validatorsLength) {
|
|
96
95
|
codeElement.blur();
|
|
97
96
|
changeDataMasking(codeElement);
|
|
98
97
|
return;
|
|
99
98
|
}
|
|
100
|
-
if (
|
|
99
|
+
if (codeElement?.value?.length > 0) {
|
|
101
100
|
codeReferences[prefix + nextIndex].current.focus();
|
|
102
101
|
changeDataMasking(codeElement);
|
|
103
102
|
}
|
|
@@ -121,10 +120,7 @@ const Validator = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
121
120
|
ref: codeReferences[codeId] ?? null,
|
|
122
121
|
validation: strValidation || singleCodes[codeId + sufixValidation],
|
|
123
122
|
tokens: selectCodeTextInputTokens(themeTokens),
|
|
124
|
-
onFocus: () =>
|
|
125
|
-
var _codeReferences$codeI2;
|
|
126
|
-
return ((_codeReferences$codeI2 = codeReferences[codeId]) === null || _codeReferences$codeI2 === void 0 || (_codeReferences$codeI2 = _codeReferences$codeI2.current) === null || _codeReferences$codeI2 === void 0 ? void 0 : _codeReferences$codeI2.select()) ?? null;
|
|
127
|
-
},
|
|
123
|
+
onFocus: () => codeReferences[codeId]?.current?.select() ?? null,
|
|
128
124
|
onKeyPress: event => handleKeyPress(event, i, i - 1),
|
|
129
125
|
onMouseOver: handleMouseOver,
|
|
130
126
|
onMouseOut: handleMouseOut,
|
|
@@ -176,10 +172,9 @@ const Validator = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
176
172
|
return () => {
|
|
177
173
|
if (Platform.oldValue === 'web') {
|
|
178
174
|
for (let i = 0; i < validatorsLength; i += 1) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
(_codeReferences3 = codeReferences[prefix + i]) === null || _codeReferences3 === void 0 || (_codeReferences3 = _codeReferences3.current) === null || _codeReferences3 === void 0 || _codeReferences3.removeEventListener('input', event => handleChangeCodeValues(event, prefix + i, i + 1));
|
|
175
|
+
codeReferences[prefix + i]?.current?.removeEventListener('paste', handlePasteCode);
|
|
176
|
+
codeReferences[prefix + i]?.current?.removeEventListener('copy', handleCopy);
|
|
177
|
+
codeReferences[prefix + i]?.current?.removeEventListener('input', event => handleChangeCodeValues(event, prefix + i, i + 1));
|
|
183
178
|
}
|
|
184
179
|
}
|
|
185
180
|
};
|
|
@@ -187,7 +182,7 @@ const Validator = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
187
182
|
return /*#__PURE__*/_jsx(InputSupports, {
|
|
188
183
|
...supportsProps,
|
|
189
184
|
feedbackProps: {
|
|
190
|
-
...
|
|
185
|
+
...rest?.feedbackProps,
|
|
191
186
|
showFeedbackIcon: true
|
|
192
187
|
},
|
|
193
188
|
children: /*#__PURE__*/_jsx(StackView, {
|
|
@@ -23,7 +23,7 @@ const useViewportListener = setViewport => {
|
|
|
23
23
|
};
|
|
24
24
|
const listener = Dimensions.addEventListener('change', onChange);
|
|
25
25
|
return () => {
|
|
26
|
-
if (typeof
|
|
26
|
+
if (typeof listener?.remove === 'function') {
|
|
27
27
|
// Can't just return listener.remove because listener.emitter disappears, causing an internal error.
|
|
28
28
|
// See https://github.com/facebook/react-native/issues/34508
|
|
29
29
|
listener.remove();
|
package/lib/index.js
CHANGED
|
@@ -18,6 +18,7 @@ export { default as ColourToggle } from './ColourToggle';
|
|
|
18
18
|
export { default as DownloadApp } from './DownloadApp';
|
|
19
19
|
export { default as Divider } from './Divider';
|
|
20
20
|
export { default as ExpandCollapse, Accordion } from './ExpandCollapse';
|
|
21
|
+
export { default as ExpandCollapseMini } from './ExpandCollapseMini';
|
|
21
22
|
export { default as Feedback } from './Feedback';
|
|
22
23
|
export { default as Fieldset } from './Fieldset';
|
|
23
24
|
export { default as FlexGrid } from './FlexGrid';
|
package/lib/utils/children.js
CHANGED
|
@@ -36,22 +36,18 @@ import A11yText from '../A11yText';
|
|
|
36
36
|
*/
|
|
37
37
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
38
38
|
export const unpackFragment = child => {
|
|
39
|
-
var _child$props;
|
|
40
39
|
// If this level is a set of top-level siblings rather than one child, check each in turn
|
|
41
40
|
if (React.Children.count(child) > 1) return React.Children.map(child, unpackFragment);
|
|
42
41
|
|
|
43
42
|
// When a fragment is found, unpack its children to the top level and check them
|
|
44
|
-
if (
|
|
43
|
+
if (child?.type === React.Fragment) return unpackFragment(child.props?.children);
|
|
45
44
|
|
|
46
45
|
// Stop unpacking as soon as any non-fragment child is found
|
|
47
46
|
return child;
|
|
48
47
|
};
|
|
49
48
|
const isStringOrNumber = child => typeof child === 'string' || typeof child === 'number';
|
|
50
49
|
// Wrap an A11yText with neighouring text strings so it doesn't split them into multiple <Text>s
|
|
51
|
-
const isWrapable = child =>
|
|
52
|
-
var _child$type;
|
|
53
|
-
return isStringOrNumber(child) || child.type === A11yText || ((_child$type = child.type) === null || _child$type === void 0 ? void 0 : _child$type.name) === 'FootnoteLink';
|
|
54
|
-
};
|
|
50
|
+
const isWrapable = child => isStringOrNumber(child) || child.type === A11yText || child.type?.name === 'FootnoteLink';
|
|
55
51
|
const combineKeys = childrenArray => childrenArray.reduce((newKey, child) => `${newKey}${child.key || ''}`, '');
|
|
56
52
|
|
|
57
53
|
// Group wrappable children for one `<Text>` parent, merging adjacent text nodes
|
package/lib/utils/input.js
CHANGED
|
@@ -97,7 +97,7 @@ export const useInputValue = function () {
|
|
|
97
97
|
const newValue = typeof arg === 'function' ? arg(valueRef.current.value) : arg;
|
|
98
98
|
if (!isControlled) {
|
|
99
99
|
setOwnValue(newValue);
|
|
100
|
-
if (inputRef
|
|
100
|
+
if (inputRef?.current) inputRef.current.value = newValue ?? '';
|
|
101
101
|
}
|
|
102
102
|
// Call onChange handler if there's something for it to handle (event or a changed value)
|
|
103
103
|
if (onChange && (event || valueRef.current.value !== newValue)) onChange(newValue, event);
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
export default function componentPropType(passedName) {
|
|
11
11
|
const passedNames = typeof passedName === 'string' ? [passedName] : passedName;
|
|
12
12
|
const checkProp = (props, propName, componentName) => {
|
|
13
|
-
var _props$propName$type, _props$propName$type2;
|
|
14
13
|
if (props[propName] === undefined || props[propName] === null) {
|
|
15
14
|
return undefined;
|
|
16
15
|
}
|
|
@@ -19,7 +18,7 @@ export default function componentPropType(passedName) {
|
|
|
19
18
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
|
|
20
19
|
return props[propName].map((_, index) => checkProp(props[propName], index, componentName)).find(Boolean);
|
|
21
20
|
}
|
|
22
|
-
const nameInProp =
|
|
21
|
+
const nameInProp = props[propName].type?.displayName || props[propName].type?.name;
|
|
23
22
|
if (!nameInProp || !passedNames.includes(nameInProp)) {
|
|
24
23
|
const propDescription = nameInProp ? `Component ${nameInProp}` : typeof props[propName];
|
|
25
24
|
return new Error(`${componentName}: ${propDescription} was passed to \`${propName}\` prop; should be ${passedNames.join(' or ')}`);
|
|
@@ -37,7 +37,15 @@ export default {
|
|
|
37
37
|
/**
|
|
38
38
|
* Use to visually mark an input as valid or invalid.
|
|
39
39
|
*/
|
|
40
|
-
validation: PropTypes.oneOf(['error', 'success'])
|
|
40
|
+
validation: PropTypes.oneOf(['error', 'success']),
|
|
41
|
+
/**
|
|
42
|
+
* The text value from an input field.
|
|
43
|
+
*/
|
|
44
|
+
inputValue: PropTypes.string,
|
|
45
|
+
/**
|
|
46
|
+
* Max number of characters allowed id an input text.
|
|
47
|
+
*/
|
|
48
|
+
maxCharacterAllowed: PropTypes.number
|
|
41
49
|
},
|
|
42
50
|
select: _ref => {
|
|
43
51
|
let {
|
|
@@ -49,7 +57,9 @@ export default {
|
|
|
49
57
|
feedbackTokens,
|
|
50
58
|
feedbackProps,
|
|
51
59
|
tooltip,
|
|
52
|
-
validation
|
|
60
|
+
validation,
|
|
61
|
+
inputValue,
|
|
62
|
+
maxCharacterAllowed
|
|
53
63
|
} = _ref;
|
|
54
64
|
return {
|
|
55
65
|
supportsProps: {
|
|
@@ -61,7 +71,9 @@ export default {
|
|
|
61
71
|
feedbackTokens,
|
|
62
72
|
feedbackProps,
|
|
63
73
|
tooltip,
|
|
64
|
-
validation
|
|
74
|
+
validation,
|
|
75
|
+
inputValue,
|
|
76
|
+
maxCharacterAllowed
|
|
65
77
|
}
|
|
66
78
|
};
|
|
67
79
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// those props merged into one object
|
|
3
3
|
export default function selectSystemProps(systemPropHelpers) {
|
|
4
4
|
const selectProps = props => systemPropHelpers.reduce((acc, propHelper) => {
|
|
5
|
-
if (typeof
|
|
5
|
+
if (typeof propHelper?.select !== 'function') {
|
|
6
6
|
throw new Error(`An invalid system prop helper has been passed to 'selectSystemProps': prop selector ('.select') is missing in ${propHelper}`);
|
|
7
7
|
}
|
|
8
8
|
return {
|
|
@@ -11,7 +11,7 @@ export default function selectSystemProps(systemPropHelpers) {
|
|
|
11
11
|
};
|
|
12
12
|
}, {});
|
|
13
13
|
const selectedPropTypes = systemPropHelpers.reduce((acc, propHelper) => {
|
|
14
|
-
if (!
|
|
14
|
+
if (!propHelper?.types) {
|
|
15
15
|
throw new Error(`An invalid system prop helper has been passed to 'selectSystemProps': types selector ('.types') is missing in ${propHelper}`);
|
|
16
16
|
}
|
|
17
17
|
return {
|
|
@@ -10,7 +10,7 @@ const createStyleSheet = stylesWithQuery => {
|
|
|
10
10
|
let cleanStyles;
|
|
11
11
|
const ids = {};
|
|
12
12
|
Object.keys(stylesWithQuery).forEach(key => {
|
|
13
|
-
if (!
|
|
13
|
+
if (!stylesWithQuery?.[key]) return;
|
|
14
14
|
const mediaQueriesAndPseudoClasses = Object.keys(stylesWithQuery[key]).filter(isMediaOrPseudo);
|
|
15
15
|
cleanStyles = JSON.parse(JSON.stringify(stylesWithQuery));
|
|
16
16
|
mediaQueriesAndPseudoClasses.forEach(str => {
|
|
@@ -11,10 +11,9 @@ const createStyleSheet = stylesWithQuery => {
|
|
|
11
11
|
let ids = {};
|
|
12
12
|
const cleanStyles = deepClone(stylesWithQuery);
|
|
13
13
|
Object.keys(stylesWithQuery).forEach(key => {
|
|
14
|
-
if (!
|
|
14
|
+
if (!stylesWithQuery?.[key]) return;
|
|
15
15
|
const mediaQueriesAndPseudoClasses = Object.keys(stylesWithQuery[key]).filter(isMediaOrPseudo);
|
|
16
16
|
mediaQueriesAndPseudoClasses.forEach(query => {
|
|
17
|
-
var _ids;
|
|
18
17
|
const sanitizedStyle = sanitizeStyle(stylesWithQuery[key][query]);
|
|
19
18
|
const css = createDeclarationBlock(sanitizedStyle);
|
|
20
19
|
const stringHash = `rnmq-${hash(`${key}${query}${css}`)}`;
|
|
@@ -23,7 +22,7 @@ const createStyleSheet = stylesWithQuery => {
|
|
|
23
22
|
delete cleanStyles[key][query];
|
|
24
23
|
ids = {
|
|
25
24
|
...ids,
|
|
26
|
-
[key]: `${
|
|
25
|
+
[key]: `${ids?.[key] ? `${ids[key]} ` : ''}${stringHash}`
|
|
27
26
|
};
|
|
28
27
|
});
|
|
29
28
|
});
|
|
@@ -12,14 +12,12 @@ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
|
12
12
|
})();
|
|
13
13
|
}
|
|
14
14
|
export const hasCss = (id, text) => {
|
|
15
|
-
|
|
16
|
-
return !!rules[id] && !!((_rules$id$text = rules[id].text) !== null && _rules$id$text !== void 0 && (_rules$id$text$includ = _rules$id$text.includes) !== null && _rules$id$text$includ !== void 0 && _rules$id$text$includ.call(_rules$id$text, text));
|
|
15
|
+
return !!rules[id] && !!rules[id].text?.includes?.(text);
|
|
17
16
|
};
|
|
18
17
|
export const addCss = (id, text) => {
|
|
19
18
|
if (!hasCss(id, text)) {
|
|
20
|
-
|
|
21
|
-
rules[id] = (rules
|
|
22
|
-
rules[id].text = (((_rules$id = rules[id]) === null || _rules$id === void 0 ? void 0 : _rules$id.text) || '') + text;
|
|
19
|
+
rules[id] = rules?.[id] || {};
|
|
20
|
+
rules[id].text = (rules[id]?.text || '') + text;
|
|
23
21
|
if (styleSheet) {
|
|
24
22
|
styleSheet.insertRule(text, Object.keys(rules).length - 1);
|
|
25
23
|
}
|
package/lib/utils/useHash.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react';
|
|
2
|
-
const doAction = (action, event) =>
|
|
3
|
-
var _window;
|
|
4
|
-
return typeof action === 'function' && action((_window = window) === null || _window === void 0 || (_window = _window.location) === null || _window === void 0 ? void 0 : _window.hash, event);
|
|
5
|
-
};
|
|
2
|
+
const doAction = (action, event) => typeof action === 'function' && action(window?.location?.hash, event);
|
|
6
3
|
|
|
7
4
|
/**
|
|
8
5
|
* @typedef {import('react').SyntheticEvent} SyntheticEvent
|