@telus-uds/components-base 1.18.1 → 1.19.1
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 +22 -2
- package/component-docs.json +111 -16
- package/jest.config-android.js +17 -0
- package/jest.config-ios.js +18 -0
- package/jest.config-web.js +31 -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/BaseProvider/TamaguiProvider.js +30 -0
- package/lib/Button/ButtonBase.js +8 -4
- package/lib/Button/ButtonDropdown.js +207 -0
- package/lib/Button/ButtonGroup.js +1 -1
- package/lib/Carousel/Carousel.js +31 -5
- package/lib/Carousel/CarouselContext.js +1 -1
- package/lib/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +1 -1
- package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +1 -10
- 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/MultiSelectFilter/ModalOverlay.js +136 -0
- package/lib/MultiSelectFilter/MultiSelectFilter.js +314 -0
- package/lib/MultiSelectFilter/dictionary.js +19 -0
- package/lib/MultiSelectFilter/index.js +13 -0
- package/lib/Pagination/PageButton.js +2 -2
- package/lib/Pagination/Pagination.js +3 -5
- package/lib/Pagination/SideButton.js +6 -4
- package/lib/Pagination/usePagination.js +2 -2
- package/lib/Progress/ProgressBar.js +3 -3
- package/lib/Progress/ProgressBarBackground.js +3 -3
- package/lib/QuickLinksFeature/QuickLinksFeature.js +91 -0
- package/lib/QuickLinksFeature/QuickLinksFeatureItem.js +157 -0
- package/lib/QuickLinksFeature/index.js +16 -0
- 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/Responsive/Responsive.js +58 -0
- package/lib/Responsive/index.js +13 -0
- package/lib/Search/Search.js +30 -63
- package/lib/Select/constants.js +15 -0
- 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 +11 -5
- package/lib/TextInput/TextInputBase.js +53 -19
- package/lib/TextInput/dictionary.js +19 -0
- package/lib/ThemeProvider/utils/styles.js +3 -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.native.js +357 -0
- package/lib/Tooltip/shared.js +39 -0
- package/lib/Validator/Validator.js +271 -0
- package/lib/Validator/index.js +13 -0
- package/lib/index.js +9 -0
- package/lib/utils/BaseView/BaseView.js +64 -0
- package/lib/utils/BaseView/BaseView.native.js +16 -0
- package/lib/utils/BaseView/index.js +13 -0
- package/lib/utils/animation/useVerticalExpandAnimation.js +1 -1
- package/lib/utils/children.js +2 -2
- package/lib/utils/floating-ui/index.js +43 -0
- package/lib/utils/floating-ui/index.native.js +43 -0
- package/lib/utils/input.js +12 -6
- 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/useOverlaidPosition.js +243 -0
- 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/BaseProvider/TamaguiProvider.js +22 -0
- package/lib-module/Button/ButtonBase.js +8 -4
- package/lib-module/Button/ButtonDropdown.js +181 -0
- package/lib-module/Button/ButtonGroup.js +1 -1
- package/lib-module/Carousel/Carousel.js +31 -5
- package/lib-module/Carousel/CarouselContext.js +1 -1
- package/lib-module/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +1 -1
- package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +1 -10
- 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/MultiSelectFilter/ModalOverlay.js +112 -0
- package/lib-module/MultiSelectFilter/MultiSelectFilter.js +286 -0
- package/lib-module/MultiSelectFilter/dictionary.js +12 -0
- package/lib-module/MultiSelectFilter/index.js +2 -0
- package/lib-module/Pagination/PageButton.js +2 -2
- package/lib-module/Pagination/Pagination.js +3 -5
- package/lib-module/Pagination/SideButton.js +6 -4
- 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/QuickLinksFeature/QuickLinksFeature.js +69 -0
- package/lib-module/QuickLinksFeature/QuickLinksFeatureItem.js +130 -0
- package/lib-module/QuickLinksFeature/index.js +4 -0
- 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/Responsive/Responsive.js +45 -0
- package/lib-module/Responsive/index.js +2 -0
- package/lib-module/Search/Search.js +30 -61
- package/lib-module/Select/constants.js +5 -0
- 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 +11 -5
- package/lib-module/TextInput/TextInputBase.js +52 -19
- package/lib-module/TextInput/dictionary.js +12 -0
- package/lib-module/ThemeProvider/utils/styles.js +3 -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.native.js +326 -0
- package/lib-module/Tooltip/shared.js +27 -0
- package/lib-module/Validator/Validator.js +245 -0
- package/lib-module/Validator/index.js +2 -0
- package/lib-module/index.js +1 -0
- package/lib-module/utils/BaseView/BaseView.js +43 -0
- package/lib-module/utils/BaseView/BaseView.native.js +6 -0
- package/lib-module/utils/BaseView/index.js +2 -0
- package/lib-module/utils/animation/useVerticalExpandAnimation.js +1 -1
- package/lib-module/utils/children.js +2 -2
- package/lib-module/utils/floating-ui/index.js +1 -0
- package/lib-module/utils/floating-ui/index.native.js +1 -0
- package/lib-module/utils/input.js +12 -6
- 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/useOverlaidPosition.js +232 -0
- package/lib-module/utils/useSpacingScale.js +1 -3
- package/lib-module/utils/useUniqueId.js +1 -1
- package/package.json +7 -4
- package/src/Button/ButtonBase.jsx +4 -2
- package/src/Carousel/Carousel.jsx +42 -10
- package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +0 -10
- package/src/Pagination/SideButton.jsx +5 -5
- package/src/Responsive/Responsive.jsx +33 -0
- package/src/Responsive/index.js +3 -0
- package/src/Search/Search.jsx +17 -32
- package/src/Tags/Tags.jsx +46 -33
- package/src/TextInput/TextInputBase.jsx +46 -16
- package/src/index.js +1 -0
|
@@ -99,7 +99,7 @@ const RadioGroup = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
99
99
|
const uniqueFields = ['id', 'label'];
|
|
100
100
|
|
|
101
101
|
if (!containUniqueFields(items, uniqueFields)) {
|
|
102
|
-
throw new Error(
|
|
102
|
+
throw new Error(`RadioGroup items must have unique ${uniqueFields.join(', ')}`);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
const radios = items.map((_ref2, index) => {
|
|
@@ -110,7 +110,7 @@ const RadioGroup = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
110
110
|
ref: itemRef,
|
|
111
111
|
...itemRest
|
|
112
112
|
} = _ref2;
|
|
113
|
-
const radioId = id ||
|
|
113
|
+
const radioId = id || `Radio[${index}]`;
|
|
114
114
|
const isChecked = currentValue === radioId;
|
|
115
115
|
|
|
116
116
|
const handleChange = (newCheckedState, event) => {
|
|
@@ -79,7 +79,7 @@ const RadioCard = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
const uniqueId = useUniqueId('RadioCard');
|
|
82
|
-
const inputId = id
|
|
82
|
+
const inputId = id ?? uniqueId;
|
|
83
83
|
const getTokens = useThemeTokensCallback('RadioCard', tokens, variant);
|
|
84
84
|
|
|
85
85
|
const getCardTokens = cardState => selectPressableCardTokens(getTokens(cardState));
|
|
@@ -105,7 +105,7 @@ const RadioCardGroup = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
105
105
|
const uniqueFields = ['id'];
|
|
106
106
|
|
|
107
107
|
if (!containUniqueFields(items, uniqueFields)) {
|
|
108
|
-
throw new Error(
|
|
108
|
+
throw new Error(`RadioCardGroup items must have unique ${uniqueFields.join(', ')}`);
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
return /*#__PURE__*/_jsx(Fieldset, {
|
|
@@ -133,7 +133,7 @@ const RadioCardGroup = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
133
133
|
onChange: itemOnChange,
|
|
134
134
|
...itemRest
|
|
135
135
|
} = _ref2;
|
|
136
|
-
const cardId = id ||
|
|
136
|
+
const cardId = id || `RadioCard[${index}]`;
|
|
137
137
|
|
|
138
138
|
const handleChange = (newCheckedState, event) => {
|
|
139
139
|
if (typeof itemOnChange === 'function') itemOnChange(newCheckedState, event);
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { viewports } from '@telus-uds/system-constants';
|
|
4
|
+
import { useResponsiveProp } from '../utils';
|
|
5
|
+
/**
|
|
6
|
+
* Responsive conditionally renders children based on whether the viewport matches the provided
|
|
7
|
+
* min and max viewports.
|
|
8
|
+
*
|
|
9
|
+
* In SSR, like other viewport utilities, it treats the viewport as `xs` both in SSR itself and
|
|
10
|
+
* during first hydration on the client side; then if the viewport is not `xs`, it re-renders
|
|
11
|
+
* after hydration. This may cause a layout shift on devices other than the narrowest.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
15
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
16
|
+
|
|
17
|
+
const Responsive = _ref => {
|
|
18
|
+
let {
|
|
19
|
+
min = 'xs',
|
|
20
|
+
max,
|
|
21
|
+
children
|
|
22
|
+
} = _ref;
|
|
23
|
+
// Start returning children at the 'min' viewport or greater
|
|
24
|
+
const byViewports = {
|
|
25
|
+
[min]: children
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
if (max && max !== 'xl') {
|
|
29
|
+
// Stop returning children at the viewport one above 'max' or greater
|
|
30
|
+
const maxIndex = viewports.keys.indexOf(max);
|
|
31
|
+
const maxPlusOne = maxIndex >= 0 ? viewports.keys[maxIndex + 1] : null;
|
|
32
|
+
if (maxPlusOne) byViewports[maxPlusOne] = null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return /*#__PURE__*/_jsx(_Fragment, {
|
|
36
|
+
children: useResponsiveProp(byViewports, null)
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
Responsive.propTypes = {
|
|
41
|
+
min: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl']),
|
|
42
|
+
max: PropTypes.oneOf(['sm', 'md', 'lg', 'xl']),
|
|
43
|
+
children: PropTypes.node.isRequired
|
|
44
|
+
};
|
|
45
|
+
export default Responsive;
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
2
|
import View from "react-native-web/dist/exports/View";
|
|
3
|
-
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
4
3
|
import PropTypes from 'prop-types';
|
|
5
4
|
import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider';
|
|
6
5
|
import { a11yProps, getTokensPropType, selectSystemProps, selectTokens, useInputValue, useSpacingScale, textInputHandlerProps, textInputProps, variantProp, viewProps } from '../utils';
|
|
7
6
|
import TextInputBase from '../TextInput/TextInputBase';
|
|
8
7
|
import ButtonBase from '../Button/ButtonBase';
|
|
9
|
-
import StackView from '../StackView';
|
|
10
8
|
import useCopy from '../utils/useCopy';
|
|
11
9
|
import dictionary from './dictionary';
|
|
12
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
-
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
11
|
const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
15
12
|
const [selectInputProps, selectedInputPropTypes] = selectSystemProps([textInputHandlerProps, textInputProps]);
|
|
16
13
|
|
|
@@ -39,20 +36,11 @@ const selectInputTokens = _ref => {
|
|
|
39
36
|
|
|
40
37
|
const selectButtonTokens = tokens => selectTokens('Button', tokens);
|
|
41
38
|
|
|
42
|
-
const
|
|
43
|
-
let {
|
|
44
|
-
paddingRight
|
|
45
|
-
} = _ref2;
|
|
46
|
-
return {
|
|
47
|
-
paddingRight
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const selectIconTokens = _ref3 => {
|
|
39
|
+
const selectIconTokens = _ref2 => {
|
|
52
40
|
let {
|
|
53
41
|
iconSize,
|
|
54
42
|
iconColor
|
|
55
|
-
} =
|
|
43
|
+
} = _ref2;
|
|
56
44
|
return {
|
|
57
45
|
color: iconColor,
|
|
58
46
|
size: iconSize
|
|
@@ -73,7 +61,7 @@ const selectIconTokens = _ref3 => {
|
|
|
73
61
|
*/
|
|
74
62
|
|
|
75
63
|
|
|
76
|
-
const Search = /*#__PURE__*/forwardRef((
|
|
64
|
+
const Search = /*#__PURE__*/forwardRef((_ref3, ref) => {
|
|
77
65
|
let {
|
|
78
66
|
initialValue,
|
|
79
67
|
value,
|
|
@@ -88,7 +76,7 @@ const Search = /*#__PURE__*/forwardRef((_ref4, ref) => {
|
|
|
88
76
|
tokens,
|
|
89
77
|
variant,
|
|
90
78
|
...rest
|
|
91
|
-
} =
|
|
79
|
+
} = _ref3;
|
|
92
80
|
const {
|
|
93
81
|
currentValue = '',
|
|
94
82
|
setValue
|
|
@@ -134,16 +122,14 @@ const Search = /*#__PURE__*/forwardRef((_ref4, ref) => {
|
|
|
134
122
|
|
|
135
123
|
const a11yLabelText = accessibilityLabel || getCopy('accessibilityLabel'); // Placeholder is optional and may be unset by passing an empty string
|
|
136
124
|
|
|
137
|
-
const placeholderText = placeholder
|
|
125
|
+
const placeholderText = placeholder ?? a11yLabelText;
|
|
138
126
|
const {
|
|
139
127
|
nativeID,
|
|
140
128
|
testID,
|
|
141
129
|
...containerProps
|
|
142
130
|
} = selectContainerProps(rest);
|
|
143
|
-
return /*#__PURE__*/
|
|
144
|
-
|
|
145
|
-
...containerProps,
|
|
146
|
-
children: [/*#__PURE__*/_jsx(TextInputBase, {
|
|
131
|
+
return /*#__PURE__*/_jsx(View, { ...containerProps,
|
|
132
|
+
children: /*#__PURE__*/_jsx(TextInputBase, {
|
|
147
133
|
nativeID: nativeID,
|
|
148
134
|
testID: testID,
|
|
149
135
|
...selectInputProps(rest),
|
|
@@ -163,35 +149,29 @@ const Search = /*#__PURE__*/forwardRef((_ref4, ref) => {
|
|
|
163
149
|
onChange: setValue,
|
|
164
150
|
onSubmitEditing: handleSubmit,
|
|
165
151
|
onFocus: handleFocus,
|
|
166
|
-
accessibilityLabel: a11yLabelText
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
accessibilityLabel: getCopy('submitButtonAccessibilityLabel'),
|
|
185
|
-
tokens: buttonState => selectButtonTokens(getButtonTokens({ ...buttonState,
|
|
152
|
+
accessibilityLabel: a11yLabelText,
|
|
153
|
+
buttons: [ClearButtonIcon && !isEmpty && /*#__PURE__*/_jsx(ButtonBase, {
|
|
154
|
+
accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
|
|
155
|
+
accessibilityRole: "button",
|
|
156
|
+
inactive: inactive,
|
|
157
|
+
onPress: handleClear,
|
|
158
|
+
tokens: appearances => selectButtonTokens(getButtonTokens(appearances)),
|
|
159
|
+
children: buttonState => /*#__PURE__*/_jsx(ClearButtonIcon, { ...selectIconTokens(getButtonTokens(buttonState))
|
|
160
|
+
})
|
|
161
|
+
}, "clear"), SubmitButtonIcon && /*#__PURE__*/_jsx(ButtonBase, {
|
|
162
|
+
accessibilityLabel: getCopy('submitButtonAccessibilityLabel'),
|
|
163
|
+
accessibilityRole: "button",
|
|
164
|
+
inactive: inactive,
|
|
165
|
+
onPress: handleSubmit,
|
|
166
|
+
tokens: buttonState => selectButtonTokens(getButtonTokens({ ...buttonState,
|
|
167
|
+
priority: 'high'
|
|
168
|
+
})),
|
|
169
|
+
children: buttonState => /*#__PURE__*/_jsx(SubmitButtonIcon, { ...selectIconTokens(getButtonTokens({ ...buttonState,
|
|
186
170
|
priority: 'high'
|
|
187
|
-
}))
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
})
|
|
192
|
-
})]
|
|
193
|
-
})
|
|
194
|
-
})]
|
|
171
|
+
}))
|
|
172
|
+
})
|
|
173
|
+
}, "submit")]
|
|
174
|
+
})
|
|
195
175
|
});
|
|
196
176
|
});
|
|
197
177
|
Search.displayName = 'Search';
|
|
@@ -255,15 +235,4 @@ Search.propTypes = { ...selectedContainerPropTypes,
|
|
|
255
235
|
tokens: getTokensPropType('Search'),
|
|
256
236
|
variant: variantProp.propType
|
|
257
237
|
};
|
|
258
|
-
export default Search;
|
|
259
|
-
const staticStyles = StyleSheet.create({
|
|
260
|
-
container: {// No styles needed here except the View defaults (position: relative etc)
|
|
261
|
-
},
|
|
262
|
-
iconsContainer: {
|
|
263
|
-
position: 'absolute',
|
|
264
|
-
right: 0,
|
|
265
|
-
top: 0,
|
|
266
|
-
bottom: 0,
|
|
267
|
-
justifyContent: 'center'
|
|
268
|
-
}
|
|
269
|
-
});
|
|
238
|
+
export default Search;
|
|
@@ -63,7 +63,7 @@ const SideNav = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
63
63
|
|
|
64
64
|
const renderItem = (item, index, groupId) => {
|
|
65
65
|
const {
|
|
66
|
-
itemId =
|
|
66
|
+
itemId = `item-${index}`,
|
|
67
67
|
onPress
|
|
68
68
|
} = item.props;
|
|
69
69
|
|
|
@@ -91,7 +91,7 @@ const SideNav = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
91
91
|
|
|
92
92
|
if (child.type === ItemsGroup) {
|
|
93
93
|
const {
|
|
94
|
-
groupId =
|
|
94
|
+
groupId = `group-${index}`
|
|
95
95
|
} = child.props;
|
|
96
96
|
const isGroupActive = active.itemId !== undefined && active.groupId === groupId;
|
|
97
97
|
|
|
@@ -124,7 +124,7 @@ const Skeleton = /*#__PURE__*/forwardRef((_ref5, ref) => {
|
|
|
124
124
|
return /*#__PURE__*/_jsx(Component, {
|
|
125
125
|
testID: "skeleton",
|
|
126
126
|
style: [selectSkeletonStyles(themeTokens), getAnimationBasedOnPlatform(), getStyledBasedOnShape()]
|
|
127
|
-
},
|
|
127
|
+
}, `skeleton-${index + 1}`);
|
|
128
128
|
};
|
|
129
129
|
|
|
130
130
|
return /*#__PURE__*/_jsx(StackView, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ANIMATION_DURATION, DEFAULT_OPACITY, OPACITY_STOP } from './skeleton.constant';
|
|
2
2
|
export default {
|
|
3
|
-
animationDuration:
|
|
3
|
+
animationDuration: `${ANIMATION_DURATION}ms`,
|
|
4
4
|
animationTimingFunction: 'ease-in-out',
|
|
5
5
|
animationDelay: '0.5s',
|
|
6
6
|
animationIterationCount: 'infinite',
|
|
@@ -24,14 +24,12 @@ const exampleGapValue = '1px';
|
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
const StackWrap = /*#__PURE__*/forwardRef((props, ref) => {
|
|
27
|
-
var _props$gap;
|
|
28
|
-
|
|
29
27
|
const [canUseCSSGap, setCanUseCSSGap] = useState(false);
|
|
30
28
|
const {
|
|
31
29
|
space
|
|
32
30
|
} = props; // Don't apply separate gap if `null` or `undefined`, so can be unset in Storybook etc
|
|
33
31
|
|
|
34
|
-
const gap =
|
|
32
|
+
const gap = props.gap ?? space;
|
|
35
33
|
const gapEqualsSpace = gap === space; // If possible, use the cleaner implementation that applies CSS `gap` styles to the container,
|
|
36
34
|
// preserving direct parent-child relationships between the container and each item, which
|
|
37
35
|
// can result in clearer descriptions on some screen readers (e.g. radio "X of Y" on MacOS).
|
|
@@ -48,7 +48,7 @@ const getStackedContent = (children, _ref) => {
|
|
|
48
48
|
const topLevelChildren = preserveFragments ? children : unpackFragment(children);
|
|
49
49
|
const validChildren = Children.toArray(topLevelChildren).filter(Boolean);
|
|
50
50
|
const content = validChildren.reduce((newChildren, child, index) => {
|
|
51
|
-
const boxID =
|
|
51
|
+
const boxID = `Stack-Box-${index}`;
|
|
52
52
|
const item = box ?
|
|
53
53
|
/*#__PURE__*/
|
|
54
54
|
// If wrapped in Box, that Box needs a key.
|
|
@@ -58,7 +58,7 @@ const getStackedContent = (children, _ref) => {
|
|
|
58
58
|
testID: boxID
|
|
59
59
|
}, child) : child;
|
|
60
60
|
if (!index || !space && !divider) return [...newChildren, item];
|
|
61
|
-
const testID =
|
|
61
|
+
const testID = `Stack-${divider ? 'Divider' : 'Spacer'}-${index}`;
|
|
62
62
|
const commonProps = {
|
|
63
63
|
testID,
|
|
64
64
|
key: testID,
|
package/lib-module/Tabs/Tabs.js
CHANGED
|
@@ -37,8 +37,6 @@ const getDefaultTabItemAccessibilityRole = parentRole => {
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
const Tabs = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
40
|
-
var _restProps$accessibil;
|
|
41
|
-
|
|
42
40
|
let {
|
|
43
41
|
tokens,
|
|
44
42
|
itemTokens,
|
|
@@ -76,7 +74,7 @@ const Tabs = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
76
74
|
if (hashId) setTimeout(setValue(hashId, event), 500);
|
|
77
75
|
}, [items, setValue]), isPositioningReady);
|
|
78
76
|
const restProps = selectProps(rest);
|
|
79
|
-
const parentAccessibilityRole =
|
|
77
|
+
const parentAccessibilityRole = restProps.accessibilityRole ?? 'tablist';
|
|
80
78
|
const defaultTabItemAccessibiltyRole = getDefaultTabItemAccessibilityRole(parentAccessibilityRole);
|
|
81
79
|
return /*#__PURE__*/_jsx(HorizontalScroll, {
|
|
82
80
|
ref: ref,
|
|
@@ -101,7 +99,7 @@ const Tabs = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
101
99
|
linkRouterProps: itemLinkRouterProps,
|
|
102
100
|
...itemRest
|
|
103
101
|
} = _ref3;
|
|
104
|
-
const itemId = id
|
|
102
|
+
const itemId = id ?? label;
|
|
105
103
|
const isSelected = Boolean(currentValue && currentValue === itemId);
|
|
106
104
|
|
|
107
105
|
const handlePress = event => {
|
package/lib-module/Tags/Tags.js
CHANGED
|
@@ -15,7 +15,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
15
15
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
16
16
|
const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, pressProps, viewProps]);
|
|
17
17
|
|
|
18
|
-
const
|
|
18
|
+
const separateIconTextTokens = (_ref, returnRest) => {
|
|
19
19
|
let {
|
|
20
20
|
icon,
|
|
21
21
|
iconPosition,
|
|
@@ -27,9 +27,10 @@ const selectIconTextTokens = _ref => {
|
|
|
27
27
|
iconAlignSelf,
|
|
28
28
|
iconPadding,
|
|
29
29
|
iconTranslateX,
|
|
30
|
-
iconTranslateY
|
|
30
|
+
iconTranslateY,
|
|
31
|
+
...rest
|
|
31
32
|
} = _ref;
|
|
32
|
-
return {
|
|
33
|
+
return returnRest ? rest : {
|
|
33
34
|
icon,
|
|
34
35
|
iconPosition,
|
|
35
36
|
iconSpace,
|
|
@@ -54,6 +55,10 @@ const selectIconTextTokens = _ref => {
|
|
|
54
55
|
};
|
|
55
56
|
};
|
|
56
57
|
|
|
58
|
+
const selectIconTextTokens = tokens => separateIconTextTokens(tokens, false);
|
|
59
|
+
|
|
60
|
+
const selectNonIconTextTokens = tokens => separateIconTextTokens(tokens, true);
|
|
61
|
+
|
|
57
62
|
const Tags = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
58
63
|
let {
|
|
59
64
|
variant,
|
|
@@ -82,7 +87,8 @@ const Tags = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
82
87
|
} = themeTokens;
|
|
83
88
|
const getItemTokens = useThemeTokensCallback('TagsItem', tokens, variant);
|
|
84
89
|
|
|
85
|
-
const getButtonTokens = buttonState =>
|
|
90
|
+
const getButtonTokens = buttonState => // Remove icon-text-related tokens, since we want to handle them ourselves, not use ButtonBase's handling
|
|
91
|
+
selectTokens('Button', selectNonIconTextTokens(getItemTokens(buttonState)));
|
|
86
92
|
|
|
87
93
|
const {
|
|
88
94
|
currentValues,
|
|
@@ -102,7 +108,7 @@ const Tags = /*#__PURE__*/forwardRef((_ref2, ref) => {
|
|
|
102
108
|
const uniqueFields = ['id', 'label'];
|
|
103
109
|
|
|
104
110
|
if (!containUniqueFields(items, uniqueFields)) {
|
|
105
|
-
throw new Error(
|
|
111
|
+
throw new Error(`Tags items must have unique ${uniqueFields.join(', ')}`);
|
|
106
112
|
}
|
|
107
113
|
|
|
108
114
|
return /*#__PURE__*/_jsx(StackWrap, {
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import React, { forwardRef, useEffect, useState } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
2
3
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
3
4
|
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
4
5
|
import NativeTextInput from "react-native-web/dist/exports/TextInput";
|
|
5
6
|
import View from "react-native-web/dist/exports/View";
|
|
6
|
-
import PropTypes from 'prop-types';
|
|
7
7
|
import { applyTextStyles, useTheme, useThemeTokens, applyOuterBorder } from '../ThemeProvider';
|
|
8
|
-
import
|
|
8
|
+
import StackView from '../StackView';
|
|
9
|
+
import { a11yProps, getTokensPropType, selectSystemProps, textInputHandlerProps, textInputProps, useInputValue, useSpacingScale, variantProp, viewProps } from '../utils';
|
|
9
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
11
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
12
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, textInputHandlerProps, textInputProps, viewProps]);
|
|
@@ -110,35 +111,47 @@ const selectIconTokens = _ref3 => {
|
|
|
110
111
|
};
|
|
111
112
|
};
|
|
112
113
|
|
|
113
|
-
const selectIconContainerStyles = _ref4 => {
|
|
114
|
+
const selectIconContainerStyles = (_ref4, buttonCount) => {
|
|
114
115
|
let {
|
|
116
|
+
buttonSize,
|
|
117
|
+
buttonsGapSize,
|
|
115
118
|
paddingRight,
|
|
116
119
|
paddingBottom
|
|
117
120
|
} = _ref4;
|
|
118
121
|
return {
|
|
119
|
-
paddingRight,
|
|
122
|
+
paddingRight: paddingRight + buttonCount * (buttonSize + buttonsGapSize),
|
|
120
123
|
paddingBottom
|
|
121
124
|
};
|
|
122
125
|
};
|
|
123
126
|
|
|
124
|
-
const
|
|
127
|
+
const selectButtonsContainerStyle = _ref5 => {
|
|
125
128
|
let {
|
|
126
|
-
|
|
129
|
+
buttonsPaddingRight
|
|
130
|
+
} = _ref5;
|
|
131
|
+
return {
|
|
132
|
+
paddingRight: buttonsPaddingRight
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const TextInputBase = /*#__PURE__*/forwardRef((_ref6, ref) => {
|
|
137
|
+
let {
|
|
138
|
+
buttons = [],
|
|
127
139
|
height,
|
|
128
|
-
initialValue,
|
|
129
140
|
inactive,
|
|
130
|
-
|
|
141
|
+
initialValue,
|
|
142
|
+
onBlur,
|
|
131
143
|
onChange,
|
|
132
144
|
onChangeText,
|
|
133
145
|
onFocus,
|
|
134
|
-
onBlur,
|
|
135
|
-
onMouseOver,
|
|
136
146
|
onMouseOut,
|
|
147
|
+
onMouseOver,
|
|
137
148
|
pattern,
|
|
149
|
+
readOnly,
|
|
138
150
|
tokens,
|
|
151
|
+
value,
|
|
139
152
|
variant = {},
|
|
140
153
|
...rest
|
|
141
|
-
} =
|
|
154
|
+
} = _ref6;
|
|
142
155
|
const [isFocused, setIsFocused] = useState(false);
|
|
143
156
|
|
|
144
157
|
const handleFocus = event => {
|
|
@@ -197,7 +210,8 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref5, ref) => {
|
|
|
197
210
|
};
|
|
198
211
|
const themeTokens = useThemeTokens('TextInput', tokens, variant, states);
|
|
199
212
|
const {
|
|
200
|
-
icon: IconComponent
|
|
213
|
+
icon: IconComponent,
|
|
214
|
+
buttonsGap
|
|
201
215
|
} = themeTokens;
|
|
202
216
|
const inputProps = { ...selectProps(rest),
|
|
203
217
|
editable: !inactive,
|
|
@@ -210,7 +224,9 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref5, ref) => {
|
|
|
210
224
|
// currentValue is being updated even if the input is not controlled, passing it down to the
|
|
211
225
|
// Input could lead to changing its state from uncontrolled to controlled
|
|
212
226
|
value: isControlled ? currentValue : undefined
|
|
213
|
-
};
|
|
227
|
+
}; // Get the actual gap value for the current viewport
|
|
228
|
+
|
|
229
|
+
const buttonsGapSize = useSpacingScale(buttonsGap);
|
|
214
230
|
const {
|
|
215
231
|
themeOptions
|
|
216
232
|
} = useTheme();
|
|
@@ -226,30 +242,47 @@ const TextInputBase = /*#__PURE__*/forwardRef((_ref5, ref) => {
|
|
|
226
242
|
}), IconComponent && /*#__PURE__*/_jsx(View, {
|
|
227
243
|
pointerEvents: "none" // avoid hijacking input press events
|
|
228
244
|
,
|
|
229
|
-
style: [staticStyles.iconContainer, selectIconContainerStyles(themeTokens
|
|
245
|
+
style: [staticStyles.iconContainer, selectIconContainerStyles({ ...themeTokens,
|
|
246
|
+
buttonsGapSize
|
|
247
|
+
}, buttons === null || buttons === void 0 ? void 0 : buttons.length)],
|
|
230
248
|
children: /*#__PURE__*/_jsx(IconComponent, { ...selectIconTokens(themeTokens)
|
|
231
249
|
})
|
|
250
|
+
}), (buttons === null || buttons === void 0 ? void 0 : buttons.length) > 0 && /*#__PURE__*/_jsx(View, {
|
|
251
|
+
style: [staticStyles.buttonsContainer, selectButtonsContainerStyle(themeTokens)],
|
|
252
|
+
children: /*#__PURE__*/_jsx(StackView, {
|
|
253
|
+
direction: "row",
|
|
254
|
+
space: buttonsGap,
|
|
255
|
+
children: buttons
|
|
256
|
+
})
|
|
232
257
|
})]
|
|
233
258
|
});
|
|
234
259
|
});
|
|
235
260
|
TextInputBase.displayName = 'TextInputBase';
|
|
236
261
|
TextInputBase.propTypes = { ...selectedSystemPropTypes,
|
|
237
|
-
|
|
262
|
+
buttons: PropTypes.arrayOf(PropTypes.node),
|
|
238
263
|
height: PropTypes.number,
|
|
239
|
-
initialValue: PropTypes.string,
|
|
240
264
|
inactive: PropTypes.bool,
|
|
241
|
-
|
|
265
|
+
initialValue: PropTypes.string,
|
|
266
|
+
onBlur: PropTypes.func,
|
|
242
267
|
onChange: PropTypes.func,
|
|
243
268
|
onChangeText: PropTypes.func,
|
|
244
269
|
onFocus: PropTypes.func,
|
|
245
|
-
onBlur: PropTypes.func,
|
|
246
|
-
onMouseOver: PropTypes.func,
|
|
247
270
|
onMouseOut: PropTypes.func,
|
|
271
|
+
onMouseOver: PropTypes.func,
|
|
272
|
+
readOnly: PropTypes.bool,
|
|
248
273
|
tokens: getTokensPropType('TextInput', 'TextArea'),
|
|
274
|
+
value: PropTypes.string,
|
|
249
275
|
variant: variantProp.propType
|
|
250
276
|
};
|
|
251
277
|
export default TextInputBase;
|
|
252
278
|
const staticStyles = StyleSheet.create({
|
|
279
|
+
buttonsContainer: {
|
|
280
|
+
position: 'absolute',
|
|
281
|
+
right: 0,
|
|
282
|
+
top: 0,
|
|
283
|
+
bottom: 0,
|
|
284
|
+
justifyContent: 'center'
|
|
285
|
+
},
|
|
253
286
|
iconContainer: {
|
|
254
287
|
position: 'absolute',
|
|
255
288
|
right: 0,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
en: {
|
|
3
|
+
clearButtonAccessibilityLabel: 'Clear',
|
|
4
|
+
showPasswordAccessibilityLabel: 'Show Password',
|
|
5
|
+
hidePasswordAccessibilityLabel: 'Hide Password'
|
|
6
|
+
},
|
|
7
|
+
fr: {
|
|
8
|
+
clearButtonAccessibilityLabel: 'Effacer',
|
|
9
|
+
showPasswordAccessibilityLabel: 'montrer le mot de passe',
|
|
10
|
+
hidePasswordAccessibilityLabel: 'masquer le mot de passe'
|
|
11
|
+
}
|
|
12
|
+
};
|
|
@@ -28,7 +28,7 @@ export function applyTextStyles(_ref) {
|
|
|
28
28
|
|
|
29
29
|
if (fontSize) {
|
|
30
30
|
// If relative font sizes are needed, catch and calculate them here
|
|
31
|
-
styles.fontSize = Platform.OS === 'web' && !forceAbsoluteFontSizing ?
|
|
31
|
+
styles.fontSize = Platform.OS === 'web' && !forceAbsoluteFontSizing ? `${fontSize / fontBasePixels}rem` : fontSize;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
if (typeof lineHeight === 'number') {
|
|
@@ -44,7 +44,7 @@ export function applyTextStyles(_ref) {
|
|
|
44
44
|
if (fontName) {
|
|
45
45
|
// Don't set undefined font families. May need some validation here that the font is available.
|
|
46
46
|
// Android doesn't recognise font weights natively so apply custom font weights via `fontFamily`.
|
|
47
|
-
styles.fontFamily =
|
|
47
|
+
styles.fontFamily = `${fontName}${fontWeight}${fontStyle}`;
|
|
48
48
|
} else if (fontWeight) {
|
|
49
49
|
// If using system default font, apply the font weight directly.
|
|
50
50
|
// Font weight support in Android is limited to 'bold' or anything else === 'normal'.
|
|
@@ -91,7 +91,7 @@ function applyWebShadow(_ref2) {
|
|
|
91
91
|
} = _ref2;
|
|
92
92
|
const insetString = inset ? 'inset ' : '';
|
|
93
93
|
const boxShadow = {
|
|
94
|
-
boxShadow:
|
|
94
|
+
boxShadow: `${insetString}${offsetX}px ${offsetY}px ${blur}px ${spread}px ${color}`
|
|
95
95
|
};
|
|
96
96
|
return boxShadow;
|
|
97
97
|
}
|
|
@@ -17,29 +17,27 @@ export const getComponentTheme = (theme, componentName) => {
|
|
|
17
17
|
// Give clear and understandable error messages for common dev errors, for example,
|
|
18
18
|
// typo in component name, missing export or accessing old version of theme
|
|
19
19
|
if (!theme) {
|
|
20
|
-
throw new Error(
|
|
20
|
+
throw new Error(`Called useTheme's getStyle on "${componentName}" with no theme provided`);
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const themeName = ((_theme$metadata = theme.metadata) === null || _theme$metadata === void 0 ? void 0 : _theme$metadata.name) || '';
|
|
24
24
|
|
|
25
25
|
if (!theme.components) {
|
|
26
|
-
throw new Error(
|
|
26
|
+
throw new Error(`Theme "${themeName}" has no components defined (looking for "${componentName}")`);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const componentTheme = theme.components[componentName];
|
|
30
30
|
|
|
31
31
|
if (!componentTheme) {
|
|
32
|
-
throw new Error(
|
|
32
|
+
throw new Error(`Theme "${themeName}" does not have styles for component "${componentName}"`);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
return componentTheme;
|
|
36
36
|
};
|
|
37
37
|
export const doesThemeConditionApply = (_ref, appearances) => {
|
|
38
|
-
var _appearances$key;
|
|
39
|
-
|
|
40
38
|
let [key, value] = _ref;
|
|
41
39
|
// use null rather than undefined so we can serialise the value in themes
|
|
42
|
-
const appearanceValue =
|
|
40
|
+
const appearanceValue = appearances[key] ?? null;
|
|
43
41
|
return Array.isArray(value) ? value.includes(appearanceValue) : value === appearanceValue;
|
|
44
42
|
};
|
|
45
43
|
export const doesThemeRuleApply = (rule, appearances) => Object.entries(rule.if).every(condition => doesThemeConditionApply(condition, appearances));
|
|
@@ -158,6 +156,10 @@ export const validateThemeTokensVersion = theme => {
|
|
|
158
156
|
const actualThemeTokensVersion = theme === null || theme === void 0 ? void 0 : (_theme$metadata2 = theme.metadata) === null || _theme$metadata2 === void 0 ? void 0 : _theme$metadata2.themeTokensVersion;
|
|
159
157
|
|
|
160
158
|
if (!semVerSatisfies(actualThemeTokensVersion, expectedThemeTokensVersion)) {
|
|
161
|
-
throw new Error(
|
|
159
|
+
throw new Error(`Invalid UDS token schema version detected.
|
|
160
|
+
|
|
161
|
+
The UDS base components ${pkg.name} v${pkg.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}.
|
|
162
|
+
|
|
163
|
+
If you see this error than most likely you have attempted to install ${pkg.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`);
|
|
162
164
|
}
|
|
163
165
|
};
|
|
@@ -141,7 +141,7 @@ const Timeline = /*#__PURE__*/forwardRef((_ref7, ref) => {
|
|
|
141
141
|
style: selectItemContentStyles(themeTokens, index + 1 === children.length),
|
|
142
142
|
children: child
|
|
143
143
|
})]
|
|
144
|
-
},
|
|
144
|
+
}, `timeline-${index}-${child.displayName}`);
|
|
145
145
|
})
|
|
146
146
|
});
|
|
147
147
|
});
|