@telus-uds/components-base 2.4.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 +15 -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/InputSupports/InputSupports.js +4 -4
- package/lib/Link/LinkBase.js +8 -3
- 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 +1 -1
- package/lib/Notification/Notification.js +10 -12
- 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 +2 -3
- package/lib/Select/Picker.js +2 -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 +1 -1
- package/lib/TextInput/TextInput.js +1 -1
- package/lib/TextInput/TextInputBase.js +10 -12
- 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/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 +1 -1
- 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/Link/LinkBase.jsx +8 -3
- package/src/index.js +1 -0
- package/src/utils/useOverlaidPosition.js +23 -0
package/lib/Select/Picker.js
CHANGED
|
@@ -39,8 +39,8 @@ const Picker = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
39
39
|
style: style,
|
|
40
40
|
onMouseOver: onMouseOver,
|
|
41
41
|
onMouseOut: () => {
|
|
42
|
-
onMouseOut
|
|
43
|
-
onClose
|
|
42
|
+
onMouseOut?.();
|
|
43
|
+
onClose?.();
|
|
44
44
|
},
|
|
45
45
|
onFocus: onFocus,
|
|
46
46
|
onBlur: onBlur,
|
|
@@ -6,10 +6,7 @@ import StackWrapGap from './StackWrapGap';
|
|
|
6
6
|
|
|
7
7
|
// In Jest/CI/SSR, global CSS isn't always available and doesn't always have .supports method
|
|
8
8
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
9
|
-
const cssSupports = (property, value) =>
|
|
10
|
-
var _window$CSS;
|
|
11
|
-
return Platform.OS === 'web' && typeof window !== 'undefined' && typeof ((_window$CSS = window.CSS) === null || _window$CSS === void 0 ? void 0 : _window$CSS.supports) === 'function' && window.CSS.supports(property, value);
|
|
12
|
-
};
|
|
9
|
+
const cssSupports = (property, value) => Platform.OS === 'web' && typeof window !== 'undefined' && typeof window.CSS?.supports === 'function' && window.CSS.supports(property, value);
|
|
13
10
|
|
|
14
11
|
// CSS.supports needs an example of the type of value you intend to use.
|
|
15
12
|
// Will be an integer appended `px` after hooks and JSX styles are resolved.
|
|
@@ -109,12 +109,11 @@ const getStackedContent = (children, _ref) => {
|
|
|
109
109
|
* @returns {ReactChildren}
|
|
110
110
|
*/
|
|
111
111
|
const unpackFragment = child => {
|
|
112
|
-
var _child$props;
|
|
113
112
|
// If this level is a set of top-level siblings rather than one child, check each in turn
|
|
114
113
|
if (React.Children.count(child) > 1) return React.Children.map(child, unpackFragment);
|
|
115
114
|
|
|
116
115
|
// When a fragment is found, unpack its children to the top level and check them
|
|
117
|
-
if (
|
|
116
|
+
if (child?.type === React.Fragment) return unpackFragment(child.props?.children);
|
|
118
117
|
|
|
119
118
|
// Stop unpacking as soon as any non-fragment child is found
|
|
120
119
|
return child;
|
|
@@ -112,8 +112,7 @@ const StepTracker = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
|
112
112
|
const stepTrackerLabel = showStepTrackerLabel ? (typeof copy === 'string' ? getCopy(textStepTrackerLabel ?? 1).stepTrackerLabel : getCopy('stepTrackerLabel')).replace('%{stepNumber}', current < steps.length ? current + 1 : steps.length).replace('%{stepCount}', steps.length).replace('%{stepLabel}', current < steps.length ? steps[current] : steps[steps.length - 1]) : getCopy('stepTrackerLabel');
|
|
113
113
|
const getStepLabel = index => {
|
|
114
114
|
if (themeTokens.showStepLabel) {
|
|
115
|
-
|
|
116
|
-
return (_getCopy = getCopy(index + 1)) === null || _getCopy === void 0 ? void 0 : _getCopy.stepLabel.replace('%{stepNumber}', index + 1);
|
|
115
|
+
return getCopy(index + 1)?.stepLabel.replace('%{stepNumber}', index + 1);
|
|
117
116
|
}
|
|
118
117
|
return '';
|
|
119
118
|
};
|
package/lib/TabBar/TabBar.js
CHANGED
|
@@ -68,7 +68,7 @@ const TabBar = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
|
|
|
68
68
|
const themeTokens = useThemeTokens('TabBar', tokens, variant);
|
|
69
69
|
const handlePress = itemId => {
|
|
70
70
|
setIsSelected(itemId);
|
|
71
|
-
onChange
|
|
71
|
+
onChange?.(itemId);
|
|
72
72
|
};
|
|
73
73
|
return /*#__PURE__*/_jsx(View, {
|
|
74
74
|
ref: ref,
|
package/lib/Tabs/Tabs.js
CHANGED
|
@@ -25,7 +25,7 @@ const getDefaultTabItemAccessibilityRole = parentRole => {
|
|
|
25
25
|
}
|
|
26
26
|
};
|
|
27
27
|
const getStackViewTokens = variant => {
|
|
28
|
-
const equalWidth = variant
|
|
28
|
+
const equalWidth = variant?.equalWidth;
|
|
29
29
|
return Platform.select({
|
|
30
30
|
web: {
|
|
31
31
|
justifyContent: equalWidth ? 'space-evenly' : 'flex-start',
|
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
|
}
|
|
@@ -68,7 +68,7 @@ const TextArea = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
68
68
|
};
|
|
69
69
|
return /*#__PURE__*/_jsx(InputSupports, {
|
|
70
70
|
...supportsProps,
|
|
71
|
-
inputValue: selectedProps
|
|
71
|
+
inputValue: selectedProps?.value,
|
|
72
72
|
children: _ref3 => {
|
|
73
73
|
let {
|
|
74
74
|
inputId,
|
|
@@ -44,7 +44,7 @@ const TextInput = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
44
44
|
children: [/*#__PURE__*/_jsx(InputSupports, {
|
|
45
45
|
nativeID: nativeID,
|
|
46
46
|
...supportsProps,
|
|
47
|
-
inputValue: selectedProps
|
|
47
|
+
inputValue: selectedProps?.value,
|
|
48
48
|
children: _ref2 => {
|
|
49
49
|
let {
|
|
50
50
|
inputId,
|
|
@@ -262,7 +262,7 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
262
262
|
} = variant;
|
|
263
263
|
const isNumeric = numeric || type === 'card' || type === 'number';
|
|
264
264
|
const isPassword = password || type === 'password';
|
|
265
|
-
const element = inputRef
|
|
265
|
+
const element = inputRef?.current;
|
|
266
266
|
React.useEffect(() => {
|
|
267
267
|
if (Platform.OS === 'web' && pattern && element) {
|
|
268
268
|
// React Native Web doesn't support `pattern`, so we have to attach it via a ref,
|
|
@@ -271,9 +271,8 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
271
271
|
}
|
|
272
272
|
}, [element, pattern]);
|
|
273
273
|
const handleChangeText = event => {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
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;
|
|
277
276
|
if (type === 'card' && filteredText) {
|
|
278
277
|
const formattedValue = filteredText.replace(/[^a-zA-Z0-9]/g, '');
|
|
279
278
|
const regex = new RegExp(`([a-zA-Z0-9]{4})(?=[a-zA-Z0-9])`, 'g');
|
|
@@ -290,10 +289,9 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
290
289
|
};
|
|
291
290
|
const themeTokens = useThemeTokens('TextInput', tokens, variant, states);
|
|
292
291
|
const handleClear = event => {
|
|
293
|
-
|
|
294
|
-
onClear === null || onClear === void 0 || onClear(event);
|
|
292
|
+
onClear?.(event);
|
|
295
293
|
resetValue(event);
|
|
296
|
-
inputRef
|
|
294
|
+
inputRef?.current?.focus();
|
|
297
295
|
};
|
|
298
296
|
const handleShowOrHide = () => {
|
|
299
297
|
if (!variant.inactive) setShowPassword(!showPassword);
|
|
@@ -318,7 +316,7 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
318
316
|
const textInputButtons = direction === 'left' ? buttons.filter(button => button && button.key !== 'submitIcon') : buttons;
|
|
319
317
|
const submitIcon = direction === 'left' ? buttons.find(button => button && button.key === 'submitIcon') : null;
|
|
320
318
|
if (onClear && isDirty) {
|
|
321
|
-
textInputButtons
|
|
319
|
+
textInputButtons?.unshift(/*#__PURE__*/_jsx(IconButton, {
|
|
322
320
|
accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
|
|
323
321
|
icon: ClearButtonIcon,
|
|
324
322
|
onPress: handleClear,
|
|
@@ -328,7 +326,7 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
328
326
|
}, "clear"));
|
|
329
327
|
}
|
|
330
328
|
if (isPassword) {
|
|
331
|
-
textInputButtons
|
|
329
|
+
textInputButtons?.unshift(/*#__PURE__*/_jsx(IconButton, {
|
|
332
330
|
accessibilityLabel: showPassword ? getCopy('hidePasswordAccessibilityLabel') : getCopy('showPasswordAccessibilityLabel'),
|
|
333
331
|
icon: !showPassword ? passwordShowButtonIcon : passwordHideButtonIcon,
|
|
334
332
|
onPress: handleShowOrHide,
|
|
@@ -364,7 +362,7 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
364
362
|
const nativeInputStyle = selectInputStyles({
|
|
365
363
|
...themeTokens,
|
|
366
364
|
height
|
|
367
|
-
}, themeOptions, inactive, type, buttons
|
|
365
|
+
}, themeOptions, inactive, type, buttons?.length, themeTokens.buttonSize, buttonsGapSize, isPassword, iconLeftWidth, iconLeftGap, direction);
|
|
368
366
|
const shouldShowSubmitIcon = submitIcon && direction === 'left' && !inactive;
|
|
369
367
|
return /*#__PURE__*/_jsxs(View, {
|
|
370
368
|
style: selectOuterBorderStyles(themeTokens),
|
|
@@ -393,11 +391,11 @@ const TextInputBase = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
|
|
|
393
391
|
style: [staticStyles.rightIconContainer, selectIconContainerStyles({
|
|
394
392
|
...themeTokens,
|
|
395
393
|
buttonsGapSize
|
|
396
|
-
}, buttons
|
|
394
|
+
}, buttons?.length)],
|
|
397
395
|
children: /*#__PURE__*/_jsx(IconComponent, {
|
|
398
396
|
...selectIconTokens(themeTokens)
|
|
399
397
|
})
|
|
400
|
-
}),
|
|
398
|
+
}), buttons?.length > 0 && !inactive && /*#__PURE__*/_jsx(View, {
|
|
401
399
|
style: [staticStyles.buttonsContainer, selectButtonsContainerStyle(themeTokens)],
|
|
402
400
|
children: /*#__PURE__*/_jsx(StackView, {
|
|
403
401
|
direction: "row",
|
|
@@ -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 ')}`);
|
|
@@ -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
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import Dimensions from "react-native-web/dist/exports/Dimensions";
|
|
3
3
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
4
|
+
import debounce from 'lodash.debounce';
|
|
5
|
+
const DEBOUNCE_DELAY = 100;
|
|
4
6
|
const adjustHorizontalToFit = (initialOffset, windowWidth, sourceWidth) => {
|
|
5
7
|
const offset = Math.max(0, initialOffset);
|
|
6
8
|
const otherEdgeOverflow = Math.max(0, offset + sourceWidth - windowWidth);
|
|
@@ -157,12 +159,11 @@ const useOverlaidPosition = _ref3 => {
|
|
|
157
159
|
const readyToShow = Boolean(isShown && sourceRef.current);
|
|
158
160
|
useEffect(() => {
|
|
159
161
|
const handleDimensionsChange = _ref5 => {
|
|
160
|
-
var _sourceRef$current;
|
|
161
162
|
let {
|
|
162
163
|
window
|
|
163
164
|
} = _ref5;
|
|
164
165
|
const measurementFunction = Platform.OS === 'web' ? 'measureInWindow' : 'measure';
|
|
165
|
-
|
|
166
|
+
sourceRef.current?.[measurementFunction]((x, y, width, height) => {
|
|
166
167
|
setWindowDimensions(window);
|
|
167
168
|
setSourceLayout({
|
|
168
169
|
x,
|
|
@@ -174,8 +175,7 @@ const useOverlaidPosition = _ref3 => {
|
|
|
174
175
|
};
|
|
175
176
|
let subscription;
|
|
176
177
|
const unsubscribe = () => {
|
|
177
|
-
|
|
178
|
-
if (typeof ((_subscription = subscription) === null || _subscription === void 0 ? void 0 : _subscription.remove) === 'function') {
|
|
178
|
+
if (typeof subscription?.remove === 'function') {
|
|
179
179
|
// React Native >=0.65.0
|
|
180
180
|
subscription.remove();
|
|
181
181
|
} else if (typeof Dimensions.remove === 'function') {
|
|
@@ -195,6 +195,27 @@ const useOverlaidPosition = _ref3 => {
|
|
|
195
195
|
}
|
|
196
196
|
return unsubscribe;
|
|
197
197
|
}, [readyToShow]);
|
|
198
|
+
useEffect(() => {
|
|
199
|
+
if (Platform.OS !== 'web') {
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
const handleScroll = debounce(() => {
|
|
203
|
+
sourceRef.current?.measureInWindow((x, y, width, height) => {
|
|
204
|
+
setWindowDimensions(window);
|
|
205
|
+
setSourceLayout({
|
|
206
|
+
x,
|
|
207
|
+
y,
|
|
208
|
+
width,
|
|
209
|
+
height
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
}, DEBOUNCE_DELAY);
|
|
213
|
+
window.addEventListener('scroll', handleScroll);
|
|
214
|
+
return () => {
|
|
215
|
+
window.removeEventListener('scroll', handleScroll);
|
|
216
|
+
handleScroll.cancel();
|
|
217
|
+
};
|
|
218
|
+
}, [sourceRef]);
|
|
198
219
|
const isReady = Boolean(isShown && sourceLayout && windowDimensions && targetDimensions);
|
|
199
220
|
const overlaidPosition = isReady ? getOverlaidPosition({
|
|
200
221
|
sourceLayout,
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
const addScrollBlocking = (preventScrolling, stopPropagation, ref) => {
|
|
3
|
-
var _ref$current;
|
|
4
3
|
document.body.addEventListener('touchmove', preventScrolling, {
|
|
5
4
|
passive: false
|
|
6
5
|
});
|
|
7
|
-
|
|
6
|
+
ref.current?.addEventListener('touchmove', stopPropagation);
|
|
8
7
|
document.body.style.overflow = 'hidden';
|
|
9
8
|
};
|
|
10
9
|
const removeScrollBlocking = (preventScrolling, stopPropagation, ref) => {
|
|
11
|
-
var _ref$current2;
|
|
12
10
|
document.body.removeEventListener('touchmove', preventScrolling);
|
|
13
|
-
|
|
11
|
+
ref.current?.removeEventListener('touchmove', stopPropagation);
|
|
14
12
|
document.body.style.overflow = 'inherit';
|
|
15
13
|
};
|
|
16
14
|
|
|
@@ -10,7 +10,7 @@ import { resolveResponsiveProp } from './useResponsiveProp';
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
const resolveSpacingOptions = space => {
|
|
13
|
-
if (!
|
|
13
|
+
if (!space?.options) return {};
|
|
14
14
|
const {
|
|
15
15
|
size,
|
|
16
16
|
variant,
|
|
@@ -111,7 +111,7 @@ const useSpacingScale = spaceValue => {
|
|
|
111
111
|
overridden,
|
|
112
112
|
subtract = 0
|
|
113
113
|
} = resolveSpacingOptions(spaceValue);
|
|
114
|
-
const space = !overridden && (
|
|
114
|
+
const space = !overridden && (spaceValue?.space ?? resolveResponsiveProp(spaceValue, viewport, 0));
|
|
115
115
|
const {
|
|
116
116
|
size
|
|
117
117
|
} = useThemeTokens('spacingScale', tokens, variant, {
|
package/package.json
CHANGED
|
@@ -33,6 +33,9 @@ const CarouselStepTracker = React.forwardRef(
|
|
|
33
33
|
const steps = Array.from(Array(totalItems)).map((_, index) => String(index))
|
|
34
34
|
|
|
35
35
|
if (enableDisplayMultipleItemsPerSlide) {
|
|
36
|
+
if (totalItems === 1) {
|
|
37
|
+
return null
|
|
38
|
+
}
|
|
36
39
|
return (
|
|
37
40
|
<>
|
|
38
41
|
<Spacer space={4} />
|