@telus-uds/components-base 1.30.0 → 1.31.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 +26 -2
- package/component-docs.json +17 -0
- package/lib/ActivityIndicator/Spinner.js +7 -7
- package/lib/ActivityIndicator/Spinner.native.js +2 -2
- package/lib/BaseProvider/HydrationContext.js +1 -1
- package/lib/Box/Box.js +1 -1
- package/lib/Button/ButtonBase.js +2 -2
- package/lib/Button/ButtonGroup.js +1 -1
- package/lib/Carousel/Carousel.js +2 -4
- package/lib/Carousel/CarouselContext.js +1 -1
- package/lib/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +1 -1
- package/lib/Carousel/CarouselThumbnail.js +2 -2
- package/lib/Checkbox/Checkbox.js +1 -1
- package/lib/Checkbox/CheckboxGroup.js +2 -2
- package/lib/Divider/Divider.js +2 -2
- package/lib/FlexGrid/Col/Col.js +1 -1
- package/lib/Icon/Icon.js +1 -1
- package/lib/List/ListItemContent.js +5 -2
- package/lib/List/PressableListItemBase.js +2 -0
- package/lib/MultiSelectFilter/MultiSelectFilter.js +2 -2
- package/lib/Pagination/PageButton.js +2 -2
- package/lib/Pagination/Pagination.js +3 -5
- package/lib/Pagination/usePagination.js +2 -2
- package/lib/Progress/ProgressBar.js +3 -3
- package/lib/Progress/ProgressBarBackground.js +3 -3
- package/lib/Radio/Radio.js +2 -2
- package/lib/Radio/RadioGroup.js +2 -2
- package/lib/RadioCard/RadioCard.js +1 -1
- package/lib/RadioCard/RadioCardGroup.js +2 -2
- package/lib/Search/Search.js +1 -1
- package/lib/SideNav/SideNav.js +2 -2
- package/lib/Skeleton/Skeleton.js +1 -1
- package/lib/Skeleton/skeletonWebAnimation.js +1 -1
- package/lib/StackView/StackWrap.js +1 -3
- package/lib/StackView/getStackedContent.js +2 -2
- package/lib/Tabs/Tabs.js +2 -4
- package/lib/Tags/Tags.js +1 -1
- package/lib/TextInput/TextInputBase.js +1 -1
- package/lib/ThemeProvider/utils/styles.js +8 -3
- package/lib/ThemeProvider/utils/theme-tokens.js +9 -7
- package/lib/Timeline/Timeline.js +1 -1
- package/lib/ToggleSwitch/ToggleSwitch.js +1 -1
- package/lib/ToggleSwitch/ToggleSwitchGroup.js +1 -1
- package/lib/Tooltip/Backdrop.js +10 -2
- package/lib/Tooltip/Tooltip.js +2 -2
- package/lib/Validator/Validator.js +14 -15
- package/lib/utils/animation/useVerticalExpandAnimation.js +1 -1
- package/lib/utils/children.js +2 -2
- package/lib/utils/input.js +13 -7
- package/lib/utils/props/componentPropType.js +3 -3
- package/lib/utils/props/selectSystemProps.js +2 -2
- package/lib/utils/props/tokens.js +2 -2
- package/lib/utils/useSpacingScale.js +1 -3
- package/lib/utils/useUniqueId.js +1 -1
- package/lib-module/ActivityIndicator/Spinner.js +7 -7
- package/lib-module/ActivityIndicator/Spinner.native.js +2 -2
- package/lib-module/BaseProvider/HydrationContext.js +1 -1
- package/lib-module/Box/Box.js +1 -1
- package/lib-module/Button/ButtonBase.js +2 -2
- package/lib-module/Button/ButtonGroup.js +1 -1
- package/lib-module/Carousel/Carousel.js +2 -4
- package/lib-module/Carousel/CarouselContext.js +1 -1
- package/lib-module/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +1 -1
- package/lib-module/Carousel/CarouselThumbnail.js +2 -2
- package/lib-module/Checkbox/Checkbox.js +1 -1
- package/lib-module/Checkbox/CheckboxGroup.js +2 -2
- package/lib-module/Divider/Divider.js +2 -2
- package/lib-module/FlexGrid/Col/Col.js +1 -1
- package/lib-module/Icon/Icon.js +1 -1
- package/lib-module/List/ListItemContent.js +5 -2
- package/lib-module/List/PressableListItemBase.js +2 -0
- package/lib-module/MultiSelectFilter/MultiSelectFilter.js +2 -2
- package/lib-module/Pagination/PageButton.js +2 -2
- package/lib-module/Pagination/Pagination.js +3 -5
- package/lib-module/Pagination/usePagination.js +2 -2
- package/lib-module/Progress/ProgressBar.js +3 -3
- package/lib-module/Progress/ProgressBarBackground.js +3 -3
- package/lib-module/Radio/Radio.js +2 -2
- package/lib-module/Radio/RadioGroup.js +2 -2
- package/lib-module/RadioCard/RadioCard.js +1 -1
- package/lib-module/RadioCard/RadioCardGroup.js +2 -2
- package/lib-module/Search/Search.js +1 -1
- package/lib-module/SideNav/SideNav.js +2 -2
- package/lib-module/Skeleton/Skeleton.js +1 -1
- package/lib-module/Skeleton/skeletonWebAnimation.js +1 -1
- package/lib-module/StackView/StackWrap.js +1 -3
- package/lib-module/StackView/getStackedContent.js +2 -2
- package/lib-module/Tabs/Tabs.js +2 -4
- package/lib-module/Tags/Tags.js +1 -1
- package/lib-module/TextInput/TextInputBase.js +1 -1
- package/lib-module/ThemeProvider/utils/styles.js +8 -3
- package/lib-module/ThemeProvider/utils/theme-tokens.js +9 -7
- package/lib-module/Timeline/Timeline.js +1 -1
- package/lib-module/ToggleSwitch/ToggleSwitch.js +1 -1
- package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +1 -1
- package/lib-module/Tooltip/Backdrop.js +10 -2
- package/lib-module/Tooltip/Tooltip.js +2 -2
- package/lib-module/Validator/Validator.js +14 -15
- package/lib-module/utils/animation/useVerticalExpandAnimation.js +1 -1
- package/lib-module/utils/children.js +2 -2
- package/lib-module/utils/input.js +13 -7
- package/lib-module/utils/props/componentPropType.js +3 -3
- package/lib-module/utils/props/selectSystemProps.js +2 -2
- package/lib-module/utils/props/tokens.js +2 -2
- package/lib-module/utils/useSpacingScale.js +1 -3
- package/lib-module/utils/useUniqueId.js +1 -1
- package/package.json +2 -2
- package/src/List/ListItemContent.jsx +4 -2
- package/src/List/PressableListItemBase.jsx +2 -0
- package/src/ThemeProvider/utils/styles.js +5 -0
- package/src/Validator/Validator.jsx +2 -1
|
@@ -42,14 +42,12 @@ const exampleGapValue = '1px';
|
|
|
42
42
|
*/
|
|
43
43
|
|
|
44
44
|
const StackWrap = /*#__PURE__*/(0, _react.forwardRef)((props, ref) => {
|
|
45
|
-
var _props$gap;
|
|
46
|
-
|
|
47
45
|
const [canUseCSSGap, setCanUseCSSGap] = (0, _react.useState)(false);
|
|
48
46
|
const {
|
|
49
47
|
space
|
|
50
48
|
} = props; // Don't apply separate gap if `null` or `undefined`, so can be unset in Storybook etc
|
|
51
49
|
|
|
52
|
-
const gap =
|
|
50
|
+
const gap = props.gap ?? space;
|
|
53
51
|
const gapEqualsSpace = gap === space; // If possible, use the cleaner implementation that applies CSS `gap` styles to the container,
|
|
54
52
|
// preserving direct parent-child relationships between the container and each item, which
|
|
55
53
|
// can result in clearer descriptions on some screen readers (e.g. radio "X of Y" on MacOS).
|
|
@@ -65,7 +65,7 @@ const getStackedContent = (children, _ref) => {
|
|
|
65
65
|
const validChildren = _react.Children.toArray(topLevelChildren).filter(Boolean);
|
|
66
66
|
|
|
67
67
|
const content = validChildren.reduce((newChildren, child, index) => {
|
|
68
|
-
const boxID =
|
|
68
|
+
const boxID = `Stack-Box-${index}`;
|
|
69
69
|
const item = box ?
|
|
70
70
|
/*#__PURE__*/
|
|
71
71
|
// If wrapped in Box, that Box needs a key.
|
|
@@ -75,7 +75,7 @@ const getStackedContent = (children, _ref) => {
|
|
|
75
75
|
testID: boxID
|
|
76
76
|
}, child) : child;
|
|
77
77
|
if (!index || !space && !divider) return [...newChildren, item];
|
|
78
|
-
const testID =
|
|
78
|
+
const testID = `Stack-${divider ? 'Divider' : 'Spacer'}-${index}`;
|
|
79
79
|
const commonProps = {
|
|
80
80
|
testID,
|
|
81
81
|
key: testID,
|
package/lib/Tabs/Tabs.js
CHANGED
|
@@ -59,8 +59,6 @@ const getDefaultTabItemAccessibilityRole = parentRole => {
|
|
|
59
59
|
|
|
60
60
|
|
|
61
61
|
const Tabs = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
62
|
-
var _restProps$accessibil;
|
|
63
|
-
|
|
64
62
|
let {
|
|
65
63
|
tokens,
|
|
66
64
|
itemTokens,
|
|
@@ -98,7 +96,7 @@ const Tabs = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
|
98
96
|
if (hashId) setTimeout(setValue(hashId, event), 500);
|
|
99
97
|
}, [items, setValue]), isPositioningReady);
|
|
100
98
|
const restProps = selectProps(rest);
|
|
101
|
-
const parentAccessibilityRole =
|
|
99
|
+
const parentAccessibilityRole = restProps.accessibilityRole ?? 'tablist';
|
|
102
100
|
const defaultTabItemAccessibiltyRole = getDefaultTabItemAccessibilityRole(parentAccessibilityRole);
|
|
103
101
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_HorizontalScroll.default, {
|
|
104
102
|
ref: ref,
|
|
@@ -123,7 +121,7 @@ const Tabs = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
|
123
121
|
linkRouterProps: itemLinkRouterProps,
|
|
124
122
|
...itemRest
|
|
125
123
|
} = _ref3;
|
|
126
|
-
const itemId = id
|
|
124
|
+
const itemId = id ?? label;
|
|
127
125
|
const isSelected = Boolean(currentValue && currentValue === itemId);
|
|
128
126
|
|
|
129
127
|
const handlePress = event => {
|
package/lib/Tags/Tags.js
CHANGED
|
@@ -135,7 +135,7 @@ const Tags = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
135
135
|
const uniqueFields = ['id', 'label'];
|
|
136
136
|
|
|
137
137
|
if (!(0, _utils.containUniqueFields)(items, uniqueFields)) {
|
|
138
|
-
throw new Error(
|
|
138
|
+
throw new Error(`Tags items must have unique ${uniqueFields.join(', ')}`);
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.StackWrap, {
|
|
@@ -208,7 +208,7 @@ const TextInputBase = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
|
|
|
208
208
|
};
|
|
209
209
|
|
|
210
210
|
const defaultRef = (0, _react.useRef)();
|
|
211
|
-
const inputRef = ref
|
|
211
|
+
const inputRef = ref ?? defaultRef;
|
|
212
212
|
const {
|
|
213
213
|
currentValue,
|
|
214
214
|
resetValue,
|
|
@@ -21,6 +21,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
21
21
|
// Make design tokens fit React Native's text styles' specific requirements and quirks
|
|
22
22
|
function applyTextStyles(_ref) {
|
|
23
23
|
let {
|
|
24
|
+
fontColor,
|
|
24
25
|
fontSize,
|
|
25
26
|
fontScaleCap,
|
|
26
27
|
lineHeight,
|
|
@@ -42,7 +43,7 @@ function applyTextStyles(_ref) {
|
|
|
42
43
|
|
|
43
44
|
if (fontSize) {
|
|
44
45
|
// If relative font sizes are needed, catch and calculate them here
|
|
45
|
-
styles.fontSize = _Platform.default.OS === 'web' && !forceAbsoluteFontSizing ?
|
|
46
|
+
styles.fontSize = _Platform.default.OS === 'web' && !forceAbsoluteFontSizing ? `${fontSize / _systemConstants.fontBasePixels}rem` : fontSize;
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
if (typeof lineHeight === 'number') {
|
|
@@ -58,11 +59,15 @@ function applyTextStyles(_ref) {
|
|
|
58
59
|
if (fontName) {
|
|
59
60
|
// Don't set undefined font families. May need some validation here that the font is available.
|
|
60
61
|
// Android doesn't recognise font weights natively so apply custom font weights via `fontFamily`.
|
|
61
|
-
styles.fontFamily =
|
|
62
|
+
styles.fontFamily = `${fontName}${fontWeight}${fontStyle}`;
|
|
62
63
|
} else if (fontWeight) {
|
|
63
64
|
// If using system default font, apply the font weight directly.
|
|
64
65
|
// Font weight support in Android is limited to 'bold' or anything else === 'normal'.
|
|
65
66
|
styles.fontWeight = _Platform.default.OS === 'android' && Number(fontWeight) > 400 ? 'bold' : fontWeight;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (fontColor) {
|
|
70
|
+
styles.color = fontColor;
|
|
66
71
|
} // TODO: look into calculating typographic spacing with PixelRatio.getFontScale()
|
|
67
72
|
// Do while implementing advanced typography e.g. paragraph etc
|
|
68
73
|
// https://github.com/telus/universal-design-system/issues/89
|
|
@@ -108,7 +113,7 @@ function applyWebShadow(_ref2) {
|
|
|
108
113
|
} = _ref2;
|
|
109
114
|
const insetString = inset ? 'inset ' : '';
|
|
110
115
|
const boxShadow = {
|
|
111
|
-
boxShadow:
|
|
116
|
+
boxShadow: `${insetString}${offsetX}px ${offsetY}px ${blur}px ${spread}px ${color}`
|
|
112
117
|
};
|
|
113
118
|
return boxShadow;
|
|
114
119
|
}
|
|
@@ -28,19 +28,19 @@ const getComponentTheme = (theme, componentName) => {
|
|
|
28
28
|
// Give clear and understandable error messages for common dev errors, for example,
|
|
29
29
|
// typo in component name, missing export or accessing old version of theme
|
|
30
30
|
if (!theme) {
|
|
31
|
-
throw new Error(
|
|
31
|
+
throw new Error(`Called useTheme's getStyle on "${componentName}" with no theme provided`);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
const themeName = ((_theme$metadata = theme.metadata) === null || _theme$metadata === void 0 ? void 0 : _theme$metadata.name) || '';
|
|
35
35
|
|
|
36
36
|
if (!theme.components) {
|
|
37
|
-
throw new Error(
|
|
37
|
+
throw new Error(`Theme "${themeName}" has no components defined (looking for "${componentName}")`);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const componentTheme = theme.components[componentName];
|
|
41
41
|
|
|
42
42
|
if (!componentTheme) {
|
|
43
|
-
throw new Error(
|
|
43
|
+
throw new Error(`Theme "${themeName}" does not have styles for component "${componentName}"`);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
return componentTheme;
|
|
@@ -49,11 +49,9 @@ const getComponentTheme = (theme, componentName) => {
|
|
|
49
49
|
exports.getComponentTheme = getComponentTheme;
|
|
50
50
|
|
|
51
51
|
const doesThemeConditionApply = (_ref, appearances) => {
|
|
52
|
-
var _appearances$key;
|
|
53
|
-
|
|
54
52
|
let [key, value] = _ref;
|
|
55
53
|
// use null rather than undefined so we can serialise the value in themes
|
|
56
|
-
const appearanceValue =
|
|
54
|
+
const appearanceValue = appearances[key] ?? null;
|
|
57
55
|
return Array.isArray(value) ? value.includes(appearanceValue) : value === appearanceValue;
|
|
58
56
|
};
|
|
59
57
|
|
|
@@ -194,7 +192,11 @@ const validateThemeTokensVersion = theme => {
|
|
|
194
192
|
const actualThemeTokensVersion = theme === null || theme === void 0 ? void 0 : (_theme$metadata2 = theme.metadata) === null || _theme$metadata2 === void 0 ? void 0 : _theme$metadata2.themeTokensVersion;
|
|
195
193
|
|
|
196
194
|
if (!(0, _satisfies.default)(actualThemeTokensVersion, expectedThemeTokensVersion)) {
|
|
197
|
-
throw new Error(
|
|
195
|
+
throw new Error(`Invalid UDS token schema version detected.
|
|
196
|
+
|
|
197
|
+
The UDS base components ${_package.default.name} v${_package.default.version} are only compatible with UDS themes that are built with @telus-uds/system-theme-tokens version that is semver compatible with ${expectedThemeTokensVersion}. The current theme was built with @telus-uds/system-theme-tokens v${actualThemeTokensVersion}.
|
|
198
|
+
|
|
199
|
+
If you see this error than most likely you have attempted to install ${_package.default.name} and a UDS theme manually because you are building a multi-brand application. If you are building a single brand application, consider installing the brand specific design system package such as @telus-uds/ds-allium. For more information, see https://github.com/telus/universal-design-system/blob/main/docs/docs/multi-brand-usage.md`);
|
|
198
200
|
}
|
|
199
201
|
};
|
|
200
202
|
|
package/lib/Timeline/Timeline.js
CHANGED
|
@@ -159,7 +159,7 @@ const Timeline = /*#__PURE__*/(0, _react.forwardRef)((_ref7, ref) => {
|
|
|
159
159
|
style: selectItemContentStyles(themeTokens, index + 1 === children.length),
|
|
160
160
|
children: child
|
|
161
161
|
})]
|
|
162
|
-
},
|
|
162
|
+
}, `timeline-${index}-${child.displayName}`);
|
|
163
163
|
})
|
|
164
164
|
});
|
|
165
165
|
});
|
|
@@ -160,7 +160,7 @@ const ToggleSwitch = /*#__PURE__*/(0, _react.forwardRef)((_ref7, ref) => {
|
|
|
160
160
|
const getButtonTokens = buttonState => selectButtonTokens(getTokens(buttonState));
|
|
161
161
|
|
|
162
162
|
const uniqueId = (0, _utils.useUniqueId)('toggleSwitch');
|
|
163
|
-
const inputId = id
|
|
163
|
+
const inputId = id ?? uniqueId;
|
|
164
164
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_StackView.default, {
|
|
165
165
|
space: 2,
|
|
166
166
|
direction: "row",
|
|
@@ -87,7 +87,7 @@ const ToggleSwitchGroup = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
|
|
|
87
87
|
const uniqueFields = ['id', 'label'];
|
|
88
88
|
|
|
89
89
|
if (!(0, _utils.containUniqueFields)(items, uniqueFields)) {
|
|
90
|
-
throw new Error(
|
|
90
|
+
throw new Error(`ToggleSwitchGroup items must have unique ${uniqueFields.join(', ')}`);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
const toggleSwitches = items.map((_ref2, index) => {
|
package/lib/Tooltip/Backdrop.js
CHANGED
|
@@ -19,7 +19,15 @@ function createPortalNode(nodeId) {
|
|
|
19
19
|
// this way the backdrop stays in place when scrolling the window - that's why we need to
|
|
20
20
|
// position it at the scroll position when rendering
|
|
21
21
|
|
|
22
|
-
node.style.cssText =
|
|
22
|
+
node.style.cssText = `
|
|
23
|
+
position: absolute;
|
|
24
|
+
top: ${window.scrollY}px;
|
|
25
|
+
left: ${window.scrollX}px;
|
|
26
|
+
right: 0;
|
|
27
|
+
bottom: 0;
|
|
28
|
+
z-index: 9999;
|
|
29
|
+
pointer-events: none;
|
|
30
|
+
`;
|
|
23
31
|
document.body.appendChild(node);
|
|
24
32
|
return node;
|
|
25
33
|
}
|
|
@@ -40,7 +48,7 @@ function Backdrop(_ref) {
|
|
|
40
48
|
} = _ref;
|
|
41
49
|
const [portalNode, setPortalNode] = (0, _react.useState)();
|
|
42
50
|
(0, _react.useEffect)(() => {
|
|
43
|
-
const nodeId =
|
|
51
|
+
const nodeId = `tooltip-backdrop-${Date.now()}`;
|
|
44
52
|
const node = createPortalNode(nodeId);
|
|
45
53
|
setPortalNode(node);
|
|
46
54
|
return () => {
|
package/lib/Tooltip/Tooltip.js
CHANGED
|
@@ -262,8 +262,8 @@ const Tooltip = /*#__PURE__*/(0, _react.forwardRef)((_ref6, ref) => {
|
|
|
262
262
|
style: [selectTooltipShadowStyles(themeTokens), staticStyles.tooltip, // applied separately so that it doesn't cover the arrow
|
|
263
263
|
selectMobileTooltipPositionStyles({
|
|
264
264
|
position: strategy,
|
|
265
|
-
top: y
|
|
266
|
-
left: x
|
|
265
|
+
top: y ?? 0,
|
|
266
|
+
left: x ?? 0
|
|
267
267
|
})],
|
|
268
268
|
onLayout: onTooltipLayout,
|
|
269
269
|
accessibilityRole: "alert",
|
|
@@ -57,7 +57,7 @@ const Validator = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
57
57
|
...rest
|
|
58
58
|
} = _ref2;
|
|
59
59
|
const defaultRef = (0, _react.useRef)();
|
|
60
|
-
const codeRef = ref
|
|
60
|
+
const codeRef = ref ?? defaultRef;
|
|
61
61
|
const {
|
|
62
62
|
supportsProps
|
|
63
63
|
} = selectProps(rest);
|
|
@@ -112,15 +112,13 @@ const Validator = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
112
112
|
};
|
|
113
113
|
|
|
114
114
|
const handleChangeCodeValues = (event, codeId, nextIndex) => {
|
|
115
|
-
var _codeReferences$codeI, _event$nativeEvent, _event$target, _codeElement$value, _codeElement$value2
|
|
115
|
+
var _codeReferences$codeI, _event$nativeEvent, _event$target, _codeElement$value, _codeElement$value2;
|
|
116
116
|
|
|
117
117
|
const codeElement = (_codeReferences$codeI = codeReferences[codeId]) === null || _codeReferences$codeI === void 0 ? void 0 : _codeReferences$codeI.current;
|
|
118
118
|
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);
|
|
119
119
|
|
|
120
120
|
if (Number(val).toString() === 'NaN') {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
codeElement.value = (_singleCodes$codeId = singleCodes[codeId]) !== null && _singleCodes$codeId !== void 0 ? _singleCodes$codeId : '';
|
|
121
|
+
codeElement.value = singleCodes[codeId] ?? '';
|
|
124
122
|
return;
|
|
125
123
|
}
|
|
126
124
|
|
|
@@ -131,7 +129,7 @@ const Validator = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
131
129
|
handleSingleCodes(codeId, codeElement.value, 'success');
|
|
132
130
|
}
|
|
133
131
|
|
|
134
|
-
handleSingleCodes(codeId, (
|
|
132
|
+
handleSingleCodes(codeId, (codeElement === null || codeElement === void 0 ? void 0 : codeElement.value) ?? singleCodes[codeId], 'success');
|
|
135
133
|
handleChangeCode();
|
|
136
134
|
|
|
137
135
|
if (nextIndex === validatorsLength) {
|
|
@@ -139,7 +137,7 @@ const Validator = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
139
137
|
return;
|
|
140
138
|
}
|
|
141
139
|
|
|
142
|
-
if ((codeElement === null || codeElement === void 0 ? void 0 : (_codeElement$
|
|
140
|
+
if ((codeElement === null || codeElement === void 0 ? void 0 : (_codeElement$value2 = codeElement.value) === null || _codeElement$value2 === void 0 ? void 0 : _codeElement$value2.length) > 0) codeReferences[prefix + nextIndex].current.focus();
|
|
143
141
|
};
|
|
144
142
|
|
|
145
143
|
const handleKeyPress = (event, currentIndex, previousIndex) => {
|
|
@@ -158,15 +156,18 @@ const Validator = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
158
156
|
const components = [];
|
|
159
157
|
|
|
160
158
|
for (let i = 0; validatorsLength && i < validatorsLength; i += 1) {
|
|
161
|
-
var _codeReferences$codeI2;
|
|
162
|
-
|
|
163
159
|
const codeId = prefix + i;
|
|
164
160
|
const codeInputProps = {
|
|
165
161
|
nativeID: codeId,
|
|
166
|
-
|
|
162
|
+
keyboardType: 'numeric',
|
|
163
|
+
ref: codeReferences[codeId] ?? null,
|
|
167
164
|
validation: strValidation || singleCodes[codeId + sufixValidation],
|
|
168
165
|
tokens: selectCodeTextInputTokens(themeTokens),
|
|
169
|
-
onFocus: () =>
|
|
166
|
+
onFocus: () => {
|
|
167
|
+
var _codeReferences$codeI2, _codeReferences$codeI3;
|
|
168
|
+
|
|
169
|
+
return ((_codeReferences$codeI2 = codeReferences[codeId]) === null || _codeReferences$codeI2 === void 0 ? void 0 : (_codeReferences$codeI3 = _codeReferences$codeI2.current) === null || _codeReferences$codeI3 === void 0 ? void 0 : _codeReferences$codeI3.select()) ?? null;
|
|
170
|
+
},
|
|
170
171
|
onKeyPress: event => handleKeyPress(event, i, i - 1),
|
|
171
172
|
onMouseOver: handleMouseOver,
|
|
172
173
|
onMouseOut: handleMouseOut,
|
|
@@ -191,10 +192,8 @@ const Validator = /*#__PURE__*/(0, _react.forwardRef)((_ref2, ref) => {
|
|
|
191
192
|
|
|
192
193
|
(0, _react.useEffect)(() => {
|
|
193
194
|
for (let i = 0; i < validatorsLength; i += 1) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
codeReferences[prefix + i].current.value = (_text$i = text[i]) !== null && _text$i !== void 0 ? _text$i : '';
|
|
197
|
-
handleSingleCodes(prefix + i, (_text$i2 = text[i]) !== null && _text$i2 !== void 0 ? _text$i2 : '', text[i] ? 'success' : '');
|
|
195
|
+
codeReferences[prefix + i].current.value = text[i] ?? '';
|
|
196
|
+
handleSingleCodes(prefix + i, text[i] ?? '', text[i] ? 'success' : '');
|
|
198
197
|
}
|
|
199
198
|
}, [text]);
|
|
200
199
|
/* eslint-disable react-hooks/exhaustive-deps */
|
|
@@ -88,7 +88,7 @@ function useVerticalExpandAnimation(_ref) {
|
|
|
88
88
|
}
|
|
89
89
|
} else if (_Platform.default.OS === 'web') {
|
|
90
90
|
const transitionDuration = isExpanded ? expandDuration : collapseDuration;
|
|
91
|
-
containerStyles.transition =
|
|
91
|
+
containerStyles.transition = `height ${transitionDuration}ms ease-in-out`;
|
|
92
92
|
containerStyles.height = isExpanded ? containerHeight : 0;
|
|
93
93
|
} else if (_Platform.default.OS === 'ios' && isExpanded && !isAnimating && !expandStateChanged && typeof containerHeight === 'number') {
|
|
94
94
|
// iOS reflows text while the height animation is in progress. Sometimes, it hits a timing bug where
|
package/lib/utils/children.js
CHANGED
|
@@ -73,7 +73,7 @@ const isWrapable = child => {
|
|
|
73
73
|
return isStringOrNumber(child) || child.type === _A11yText.default || ((_child$type = child.type) === null || _child$type === void 0 ? void 0 : _child$type.name) === 'FootnoteLink';
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
-
const combineKeys = childrenArray => childrenArray.reduce((newKey, child) =>
|
|
76
|
+
const combineKeys = childrenArray => childrenArray.reduce((newKey, child) => `${newKey}${child.key || ''}`, ''); // Group wrappable children for one `<Text>` parent, merging adjacent text nodes
|
|
77
77
|
|
|
78
78
|
|
|
79
79
|
const wrapChild = (child, wrappedText) => {
|
|
@@ -82,7 +82,7 @@ const wrapChild = (child, wrappedText) => {
|
|
|
82
82
|
|
|
83
83
|
if (lastIndex >= 0 && isStringOrNumber(child) && isStringOrNumber(wrappedText[lastIndex])) {
|
|
84
84
|
/* eslint-disable-next-line no-param-reassign */
|
|
85
|
-
wrappedText[lastIndex] =
|
|
85
|
+
wrappedText[lastIndex] = `${wrappedText[lastIndex]}${child}`;
|
|
86
86
|
} else {
|
|
87
87
|
wrappedText.push(child);
|
|
88
88
|
}
|
package/lib/utils/input.js
CHANGED
|
@@ -28,23 +28,29 @@ const validateProps = (_ref, _ref2, hookName) => {
|
|
|
28
28
|
const usageError = error => {
|
|
29
29
|
// Errors inside hooks in React Native get incomplete stack traces pointing at parent component only.
|
|
30
30
|
// Help devs out by telling them exactly which hook threw the error as well as why.
|
|
31
|
-
throw new Error(
|
|
31
|
+
throw new Error(`${hookName} ${error}.
|
|
32
|
+
|
|
33
|
+
Consumers of this hook must be one of:
|
|
34
|
+
1. An "uncontrolled" component responding directly to user actions, with an optional \`initialValue${s}\` but no \`value${s}\` prop,
|
|
35
|
+
2. A "controlled" component where an always-defined \`value${s}\` prop is managed by an \`onChange\` handler, with no \`initialValue${s}\`,
|
|
36
|
+
3. A "read-only" component, with \`readOnly\` prop set as \`true\`.
|
|
37
|
+
`);
|
|
32
38
|
};
|
|
33
39
|
|
|
34
40
|
if (value && !onChange && !readOnly) {
|
|
35
|
-
usageError(
|
|
41
|
+
usageError(`has \`value${s}\` prop without \`onChange\` or \`readOnly\``);
|
|
36
42
|
}
|
|
37
43
|
|
|
38
44
|
if (initialValue && value) {
|
|
39
|
-
usageError(
|
|
45
|
+
usageError(`has both \`initialValue${s}\` and \`value${s}\``);
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
if (isControlled && !isCurrentlyControlled) {
|
|
43
|
-
usageError(
|
|
49
|
+
usageError(`stopped receiving \`value${s}\` from parent after delegating state management`);
|
|
44
50
|
}
|
|
45
51
|
|
|
46
52
|
if (!isControlled && isCurrentlyControlled) {
|
|
47
|
-
usageError(
|
|
53
|
+
usageError(`started receiving \`value${s}\` from parent after starting managing own state`);
|
|
48
54
|
}
|
|
49
55
|
};
|
|
50
56
|
/**
|
|
@@ -105,7 +111,7 @@ const useInputValue = function () {
|
|
|
105
111
|
|
|
106
112
|
if (!isControlled) {
|
|
107
113
|
setOwnValue(newValue);
|
|
108
|
-
if (inputRef !== null && inputRef !== void 0 && inputRef.current) inputRef.current.value = newValue
|
|
114
|
+
if (inputRef !== null && inputRef !== void 0 && inputRef.current) inputRef.current.value = newValue ?? '';
|
|
109
115
|
} // Call onChange handler if there's something for it to handle (event or a changed value)
|
|
110
116
|
|
|
111
117
|
|
|
@@ -166,7 +172,7 @@ const useMultipleInputValues = function () {
|
|
|
166
172
|
onChange,
|
|
167
173
|
value: values,
|
|
168
174
|
// if we're controlling our own state, always start with an array
|
|
169
|
-
initialValue: initialValues
|
|
175
|
+
initialValue: initialValues ?? (values === undefined ? [] : undefined)
|
|
170
176
|
}, 'useMultipleInputValues');
|
|
171
177
|
const enforceMaxValues = (0, _react.useCallback)(newValues => {
|
|
172
178
|
if (!maxValues) return newValues;
|
|
@@ -33,8 +33,8 @@ function componentPropType(passedName) {
|
|
|
33
33
|
const nameInProp = ((_props$propName$type = props[propName].type) === null || _props$propName$type === void 0 ? void 0 : _props$propName$type.displayName) || ((_props$propName$type2 = props[propName].type) === null || _props$propName$type2 === void 0 ? void 0 : _props$propName$type2.name);
|
|
34
34
|
|
|
35
35
|
if (!nameInProp || !passedNames.includes(nameInProp)) {
|
|
36
|
-
const propDescription = nameInProp ?
|
|
37
|
-
return new Error(
|
|
36
|
+
const propDescription = nameInProp ? `Component ${nameInProp}` : typeof props[propName];
|
|
37
|
+
return new Error(`${componentName}: ${propDescription} was passed to \`${propName}\` prop; should be ${passedNames.join(' or ')}`);
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
return undefined;
|
|
@@ -42,7 +42,7 @@ function componentPropType(passedName) {
|
|
|
42
42
|
|
|
43
43
|
const checkRequired = (props, propName, componentName) => {
|
|
44
44
|
if (props[propName] === undefined) {
|
|
45
|
-
return new Error(
|
|
45
|
+
return new Error(`The prop \`${propName}\` is marked as required in \`${componentName}\`, but its value is ${props[propName]}.`);
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
return undefined;
|
|
@@ -10,7 +10,7 @@ exports.default = selectSystemProps;
|
|
|
10
10
|
function selectSystemProps(systemPropHelpers) {
|
|
11
11
|
const selectProps = props => systemPropHelpers.reduce((acc, propHelper) => {
|
|
12
12
|
if (typeof (propHelper === null || propHelper === void 0 ? void 0 : propHelper.select) !== 'function') {
|
|
13
|
-
throw new Error(
|
|
13
|
+
throw new Error(`An invalid system prop helper has been passed to 'selectSystemProps': prop selector ('.select') is missing in ${propHelper}`);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
return { ...acc,
|
|
@@ -20,7 +20,7 @@ function selectSystemProps(systemPropHelpers) {
|
|
|
20
20
|
|
|
21
21
|
const selectedPropTypes = systemPropHelpers.reduce((acc, propHelper) => {
|
|
22
22
|
if (!(propHelper !== null && propHelper !== void 0 && propHelper.types)) {
|
|
23
|
-
throw new Error(
|
|
23
|
+
throw new Error(`An invalid system prop helper has been passed to 'selectSystemProps': types selector ('.types') is missing in ${propHelper}`);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
return { ...acc,
|
|
@@ -22,7 +22,7 @@ const getTokenNames = componentName => {
|
|
|
22
22
|
const componentTokenSchema = _systemThemeTokens.components[componentName];
|
|
23
23
|
|
|
24
24
|
if (!componentTokenSchema) {
|
|
25
|
-
throw new Error(
|
|
25
|
+
throw new Error(`No "${componentName}" tokenKeys in @telus-uds/system-theme-tokens`);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
return Object.keys(componentTokenSchema);
|
|
@@ -63,7 +63,7 @@ exports.getTokenNames = getTokenNames;
|
|
|
63
63
|
const selectTokens = (specifier, tokens, prefix) => {
|
|
64
64
|
const tokenNames = typeof specifier === 'string' ? getTokenNames(specifier) : specifier;
|
|
65
65
|
const filteredTokens = tokenNames.reduce((validTokens, key) => {
|
|
66
|
-
const prefixedKey = prefix ?
|
|
66
|
+
const prefixedKey = prefix ? `${prefix}${key[0].toUpperCase()}${key.slice(1)}` : key;
|
|
67
67
|
const token = tokens[prefixedKey];
|
|
68
68
|
return token !== undefined ? { ...validTokens,
|
|
69
69
|
[key]: token
|
|
@@ -110,8 +110,6 @@ const resolveSpacingOptions = space => {
|
|
|
110
110
|
|
|
111
111
|
|
|
112
112
|
const useSpacingScale = spaceValue => {
|
|
113
|
-
var _spaceValue$space;
|
|
114
|
-
|
|
115
113
|
// In future, may need to consider window height as well as width, particularly for native apps,
|
|
116
114
|
// e.g. to ensure designs don't look lost on large, tall, not-so-wide portrait screens.
|
|
117
115
|
const viewport = (0, _ViewportProvider.useViewport)();
|
|
@@ -121,7 +119,7 @@ const useSpacingScale = spaceValue => {
|
|
|
121
119
|
overridden,
|
|
122
120
|
subtract = 0
|
|
123
121
|
} = resolveSpacingOptions(spaceValue);
|
|
124
|
-
const space = !overridden && ((
|
|
122
|
+
const space = !overridden && ((spaceValue === null || spaceValue === void 0 ? void 0 : spaceValue.space) ?? (0, _useResponsiveProp.resolveResponsiveProp)(spaceValue, viewport, 0));
|
|
125
123
|
const {
|
|
126
124
|
size
|
|
127
125
|
} = (0, _ThemeProvider.useThemeTokens)('spacingScale', tokens, variant, {
|
package/lib/utils/useUniqueId.js
CHANGED
|
@@ -13,7 +13,7 @@ function useUniqueId() {
|
|
|
13
13
|
let prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
14
14
|
const [uniqueId] = (0, _react.useState)(() => {
|
|
15
15
|
id += 1;
|
|
16
|
-
return
|
|
16
|
+
return `${prefix}-${id}`;
|
|
17
17
|
});
|
|
18
18
|
return uniqueId;
|
|
19
19
|
}
|
|
@@ -10,14 +10,14 @@ const MIN_SVG_LENGTH = MIN_STROKE_ANGLE / 360 * SVG_CIRCUMFERENCE;
|
|
|
10
10
|
const MAX_SVG_LENGTH = (1 - MIN_EMPTY_ANGLE / 360) * SVG_CIRCUMFERENCE;
|
|
11
11
|
const animationProps = {
|
|
12
12
|
begin: '0s',
|
|
13
|
-
dur:
|
|
13
|
+
dur: `${DURATION}ms`,
|
|
14
14
|
fill: 'freeze',
|
|
15
15
|
repeatCount: 'indefinite'
|
|
16
16
|
};
|
|
17
17
|
const bezierProps = {
|
|
18
18
|
calcMode: 'spline',
|
|
19
19
|
keyTimes: '0; 0.5; 1',
|
|
20
|
-
keySplines:
|
|
20
|
+
keySplines: `${BEZIER.join(', ')} ; ${BEZIER.join(', ')}`
|
|
21
21
|
}; // We're using svg rather than css here to define the animation to avoid needing to introduce css injection mechanism
|
|
22
22
|
// It's possible to replicate this functionality with RNW animations, but it snags on chrome at least, see https://github.com/telus/universal-design-system/pull/477 for details.
|
|
23
23
|
|
|
@@ -35,8 +35,8 @@ const Spinner = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
35
35
|
const reduceMotion = reduceMotionEnabled || isStatic;
|
|
36
36
|
return /*#__PURE__*/_jsx("svg", {
|
|
37
37
|
ref: ref,
|
|
38
|
-
width:
|
|
39
|
-
height:
|
|
38
|
+
width: `${size}px`,
|
|
39
|
+
height: `${size}px`,
|
|
40
40
|
viewBox: "0 0 48 48",
|
|
41
41
|
"aria-valuetext": label,
|
|
42
42
|
role: "progressbar",
|
|
@@ -45,7 +45,7 @@ const Spinner = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
45
45
|
children: [reduceMotion ? null : /*#__PURE__*/_jsx("animateTransform", {
|
|
46
46
|
attributeName: "transform",
|
|
47
47
|
type: "rotate",
|
|
48
|
-
values:
|
|
48
|
+
values: `-180 24 24;${360 + MIN_STROKE_ANGLE - 180} 24 24`,
|
|
49
49
|
...animationProps
|
|
50
50
|
}), /*#__PURE__*/_jsx("circle", {
|
|
51
51
|
fill: "none",
|
|
@@ -60,12 +60,12 @@ const Spinner = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
60
60
|
children: reduceMotion ? null : /*#__PURE__*/_jsxs(_Fragment, {
|
|
61
61
|
children: [/*#__PURE__*/_jsx("animate", {
|
|
62
62
|
attributeName: "stroke-dashoffset",
|
|
63
|
-
values:
|
|
63
|
+
values: `0;-10;${MIN_SVG_LENGTH - SVG_CIRCUMFERENCE}`,
|
|
64
64
|
...animationProps,
|
|
65
65
|
...bezierProps
|
|
66
66
|
}), /*#__PURE__*/_jsx("animate", {
|
|
67
67
|
attributeName: "stroke-dasharray",
|
|
68
|
-
values:
|
|
68
|
+
values: `${MIN_SVG_LENGTH}, 200;${MAX_SVG_LENGTH}, 200;${MIN_SVG_LENGTH}, 200`,
|
|
69
69
|
...animationProps,
|
|
70
70
|
...bezierProps
|
|
71
71
|
})]
|
|
@@ -69,7 +69,7 @@ const Spinner = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
const direction = index ? -1 : +1;
|
|
72
|
-
return
|
|
72
|
+
return `${direction * (180 - (sa + ea)) * easing(progress) + rotation}deg`;
|
|
73
73
|
});
|
|
74
74
|
const layerStyle = {
|
|
75
75
|
width: size,
|
|
@@ -84,7 +84,7 @@ const Spinner = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
84
84
|
layerStyle.transform = [{
|
|
85
85
|
rotate: timer.interpolate({
|
|
86
86
|
inputRange: [0, 1],
|
|
87
|
-
outputRange: [
|
|
87
|
+
outputRange: [`${0 + ea + sa}deg`, `${2 * 360 + ea + sa}deg`]
|
|
88
88
|
})
|
|
89
89
|
}];
|
|
90
90
|
viewportStyle.transform = [{
|
|
@@ -39,7 +39,7 @@ export const HydrationProvider = _ref => {
|
|
|
39
39
|
}, []); // If we've got a HydrationProvider inside a HydrationProvider somehow, defer to the top one
|
|
40
40
|
|
|
41
41
|
const valueFromAncestor = useHydrationContext();
|
|
42
|
-
const isHydrating = valueFromAncestor
|
|
42
|
+
const isHydrating = valueFromAncestor ?? Boolean(!hasMounted && hasWebStyleTag());
|
|
43
43
|
return /*#__PURE__*/_jsx(HydrationContext.Provider, {
|
|
44
44
|
value: isHydrating,
|
|
45
45
|
children: children
|
package/lib-module/Box/Box.js
CHANGED
|
@@ -26,7 +26,7 @@ const selectBoxStyles = tokens => {
|
|
|
26
26
|
}
|
|
27
27
|
} = tokens;
|
|
28
28
|
styles = { ...styles,
|
|
29
|
-
backgroundImage:
|
|
29
|
+
backgroundImage: `linear-gradient(${angle}deg, ${stopOne.color}, 75% , ${stopTwo.color})`
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -76,7 +76,7 @@ const selectOuterWidthStyles = _ref3 => {
|
|
|
76
76
|
|
|
77
77
|
|
|
78
78
|
if (Platform.OS === 'web') {
|
|
79
|
-
widthStyles.width =
|
|
79
|
+
widthStyles.width = `calc(${width} + ${outerBorderOffset * 2}px)`;
|
|
80
80
|
return widthStyles;
|
|
81
81
|
} // Can't use calc() on native but (unlike on web) flexGrow fills the container width here
|
|
82
82
|
|
|
@@ -163,7 +163,7 @@ const selectWebOnlyStyles = (inactive, themeTokens, _ref7) => {
|
|
|
163
163
|
return Platform.select({
|
|
164
164
|
web: {
|
|
165
165
|
// if it would overflow the container, wraps instead
|
|
166
|
-
maxWidth:
|
|
166
|
+
maxWidth: `calc(100% + ${getOuterBorderOffset(themeTokens) * 2}px)`,
|
|
167
167
|
outline: 'none',
|
|
168
168
|
// removes the default browser :focus outline
|
|
169
169
|
...getCursorStyle(inactive, accessibilityRole)
|
|
@@ -68,7 +68,7 @@ const ButtonGroup = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
68
68
|
const uniqueFields = ['id', 'label'];
|
|
69
69
|
|
|
70
70
|
if (!containUniqueFields(items, uniqueFields)) {
|
|
71
|
-
throw new Error(
|
|
71
|
+
throw new Error(`ButtonGroup items must have unique ${uniqueFields.join(', ')}`);
|
|
72
72
|
} // Some web screenreaders e.g. MacOS Voiceover don't handle radiogroups properly unless radio is direct child of radiogroup
|
|
73
73
|
|
|
74
74
|
|