@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.
Files changed (160) hide show
  1. package/CHANGELOG.md +22 -2
  2. package/component-docs.json +111 -16
  3. package/jest.config-android.js +17 -0
  4. package/jest.config-ios.js +18 -0
  5. package/jest.config-web.js +31 -0
  6. package/lib/ActivityIndicator/Spinner.js +7 -7
  7. package/lib/ActivityIndicator/Spinner.native.js +2 -2
  8. package/lib/BaseProvider/HydrationContext.js +1 -1
  9. package/lib/BaseProvider/TamaguiProvider.js +30 -0
  10. package/lib/Button/ButtonBase.js +8 -4
  11. package/lib/Button/ButtonDropdown.js +207 -0
  12. package/lib/Button/ButtonGroup.js +1 -1
  13. package/lib/Carousel/Carousel.js +31 -5
  14. package/lib/Carousel/CarouselContext.js +1 -1
  15. package/lib/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +1 -1
  16. package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +1 -10
  17. package/lib/Carousel/CarouselThumbnail.js +2 -2
  18. package/lib/Checkbox/Checkbox.js +1 -1
  19. package/lib/Checkbox/CheckboxGroup.js +2 -2
  20. package/lib/Divider/Divider.js +2 -2
  21. package/lib/FlexGrid/Col/Col.js +1 -1
  22. package/lib/Icon/Icon.js +1 -1
  23. package/lib/MultiSelectFilter/ModalOverlay.js +136 -0
  24. package/lib/MultiSelectFilter/MultiSelectFilter.js +314 -0
  25. package/lib/MultiSelectFilter/dictionary.js +19 -0
  26. package/lib/MultiSelectFilter/index.js +13 -0
  27. package/lib/Pagination/PageButton.js +2 -2
  28. package/lib/Pagination/Pagination.js +3 -5
  29. package/lib/Pagination/SideButton.js +6 -4
  30. package/lib/Pagination/usePagination.js +2 -2
  31. package/lib/Progress/ProgressBar.js +3 -3
  32. package/lib/Progress/ProgressBarBackground.js +3 -3
  33. package/lib/QuickLinksFeature/QuickLinksFeature.js +91 -0
  34. package/lib/QuickLinksFeature/QuickLinksFeatureItem.js +157 -0
  35. package/lib/QuickLinksFeature/index.js +16 -0
  36. package/lib/Radio/Radio.js +2 -2
  37. package/lib/Radio/RadioGroup.js +2 -2
  38. package/lib/RadioCard/RadioCard.js +1 -1
  39. package/lib/RadioCard/RadioCardGroup.js +2 -2
  40. package/lib/Responsive/Responsive.js +58 -0
  41. package/lib/Responsive/index.js +13 -0
  42. package/lib/Search/Search.js +30 -63
  43. package/lib/Select/constants.js +15 -0
  44. package/lib/SideNav/SideNav.js +2 -2
  45. package/lib/Skeleton/Skeleton.js +1 -1
  46. package/lib/Skeleton/skeletonWebAnimation.js +1 -1
  47. package/lib/StackView/StackWrap.js +1 -3
  48. package/lib/StackView/getStackedContent.js +2 -2
  49. package/lib/Tabs/Tabs.js +2 -4
  50. package/lib/Tags/Tags.js +11 -5
  51. package/lib/TextInput/TextInputBase.js +53 -19
  52. package/lib/TextInput/dictionary.js +19 -0
  53. package/lib/ThemeProvider/utils/styles.js +3 -3
  54. package/lib/ThemeProvider/utils/theme-tokens.js +9 -7
  55. package/lib/Timeline/Timeline.js +1 -1
  56. package/lib/ToggleSwitch/ToggleSwitch.js +1 -1
  57. package/lib/ToggleSwitch/ToggleSwitchGroup.js +1 -1
  58. package/lib/Tooltip/Backdrop.js +10 -2
  59. package/lib/Tooltip/Tooltip.native.js +357 -0
  60. package/lib/Tooltip/shared.js +39 -0
  61. package/lib/Validator/Validator.js +271 -0
  62. package/lib/Validator/index.js +13 -0
  63. package/lib/index.js +9 -0
  64. package/lib/utils/BaseView/BaseView.js +64 -0
  65. package/lib/utils/BaseView/BaseView.native.js +16 -0
  66. package/lib/utils/BaseView/index.js +13 -0
  67. package/lib/utils/animation/useVerticalExpandAnimation.js +1 -1
  68. package/lib/utils/children.js +2 -2
  69. package/lib/utils/floating-ui/index.js +43 -0
  70. package/lib/utils/floating-ui/index.native.js +43 -0
  71. package/lib/utils/input.js +12 -6
  72. package/lib/utils/props/componentPropType.js +3 -3
  73. package/lib/utils/props/selectSystemProps.js +2 -2
  74. package/lib/utils/props/tokens.js +2 -2
  75. package/lib/utils/useOverlaidPosition.js +243 -0
  76. package/lib/utils/useSpacingScale.js +1 -3
  77. package/lib/utils/useUniqueId.js +1 -1
  78. package/lib-module/ActivityIndicator/Spinner.js +7 -7
  79. package/lib-module/ActivityIndicator/Spinner.native.js +2 -2
  80. package/lib-module/BaseProvider/HydrationContext.js +1 -1
  81. package/lib-module/BaseProvider/TamaguiProvider.js +22 -0
  82. package/lib-module/Button/ButtonBase.js +8 -4
  83. package/lib-module/Button/ButtonDropdown.js +181 -0
  84. package/lib-module/Button/ButtonGroup.js +1 -1
  85. package/lib-module/Carousel/Carousel.js +31 -5
  86. package/lib-module/Carousel/CarouselContext.js +1 -1
  87. package/lib-module/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +1 -1
  88. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +1 -10
  89. package/lib-module/Carousel/CarouselThumbnail.js +2 -2
  90. package/lib-module/Checkbox/Checkbox.js +1 -1
  91. package/lib-module/Checkbox/CheckboxGroup.js +2 -2
  92. package/lib-module/Divider/Divider.js +2 -2
  93. package/lib-module/FlexGrid/Col/Col.js +1 -1
  94. package/lib-module/Icon/Icon.js +1 -1
  95. package/lib-module/MultiSelectFilter/ModalOverlay.js +112 -0
  96. package/lib-module/MultiSelectFilter/MultiSelectFilter.js +286 -0
  97. package/lib-module/MultiSelectFilter/dictionary.js +12 -0
  98. package/lib-module/MultiSelectFilter/index.js +2 -0
  99. package/lib-module/Pagination/PageButton.js +2 -2
  100. package/lib-module/Pagination/Pagination.js +3 -5
  101. package/lib-module/Pagination/SideButton.js +6 -4
  102. package/lib-module/Pagination/usePagination.js +2 -2
  103. package/lib-module/Progress/ProgressBar.js +3 -3
  104. package/lib-module/Progress/ProgressBarBackground.js +3 -3
  105. package/lib-module/QuickLinksFeature/QuickLinksFeature.js +69 -0
  106. package/lib-module/QuickLinksFeature/QuickLinksFeatureItem.js +130 -0
  107. package/lib-module/QuickLinksFeature/index.js +4 -0
  108. package/lib-module/Radio/Radio.js +2 -2
  109. package/lib-module/Radio/RadioGroup.js +2 -2
  110. package/lib-module/RadioCard/RadioCard.js +1 -1
  111. package/lib-module/RadioCard/RadioCardGroup.js +2 -2
  112. package/lib-module/Responsive/Responsive.js +45 -0
  113. package/lib-module/Responsive/index.js +2 -0
  114. package/lib-module/Search/Search.js +30 -61
  115. package/lib-module/Select/constants.js +5 -0
  116. package/lib-module/SideNav/SideNav.js +2 -2
  117. package/lib-module/Skeleton/Skeleton.js +1 -1
  118. package/lib-module/Skeleton/skeletonWebAnimation.js +1 -1
  119. package/lib-module/StackView/StackWrap.js +1 -3
  120. package/lib-module/StackView/getStackedContent.js +2 -2
  121. package/lib-module/Tabs/Tabs.js +2 -4
  122. package/lib-module/Tags/Tags.js +11 -5
  123. package/lib-module/TextInput/TextInputBase.js +52 -19
  124. package/lib-module/TextInput/dictionary.js +12 -0
  125. package/lib-module/ThemeProvider/utils/styles.js +3 -3
  126. package/lib-module/ThemeProvider/utils/theme-tokens.js +9 -7
  127. package/lib-module/Timeline/Timeline.js +1 -1
  128. package/lib-module/ToggleSwitch/ToggleSwitch.js +1 -1
  129. package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +1 -1
  130. package/lib-module/Tooltip/Backdrop.js +10 -2
  131. package/lib-module/Tooltip/Tooltip.native.js +326 -0
  132. package/lib-module/Tooltip/shared.js +27 -0
  133. package/lib-module/Validator/Validator.js +245 -0
  134. package/lib-module/Validator/index.js +2 -0
  135. package/lib-module/index.js +1 -0
  136. package/lib-module/utils/BaseView/BaseView.js +43 -0
  137. package/lib-module/utils/BaseView/BaseView.native.js +6 -0
  138. package/lib-module/utils/BaseView/index.js +2 -0
  139. package/lib-module/utils/animation/useVerticalExpandAnimation.js +1 -1
  140. package/lib-module/utils/children.js +2 -2
  141. package/lib-module/utils/floating-ui/index.js +1 -0
  142. package/lib-module/utils/floating-ui/index.native.js +1 -0
  143. package/lib-module/utils/input.js +12 -6
  144. package/lib-module/utils/props/componentPropType.js +3 -3
  145. package/lib-module/utils/props/selectSystemProps.js +2 -2
  146. package/lib-module/utils/props/tokens.js +2 -2
  147. package/lib-module/utils/useOverlaidPosition.js +232 -0
  148. package/lib-module/utils/useSpacingScale.js +1 -3
  149. package/lib-module/utils/useUniqueId.js +1 -1
  150. package/package.json +7 -4
  151. package/src/Button/ButtonBase.jsx +4 -2
  152. package/src/Carousel/Carousel.jsx +42 -10
  153. package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +0 -10
  154. package/src/Pagination/SideButton.jsx +5 -5
  155. package/src/Responsive/Responsive.jsx +33 -0
  156. package/src/Responsive/index.js +3 -0
  157. package/src/Search/Search.jsx +17 -32
  158. package/src/Tags/Tags.jsx +46 -33
  159. package/src/TextInput/TextInputBase.jsx +46 -16
  160. 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("RadioGroup items must have unique ".concat(uniqueFields.join(', ')));
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 || "Radio[".concat(index, "]");
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 !== null && id !== void 0 ? id : uniqueId;
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("RadioCardGroup items must have unique ".concat(uniqueFields.join(', ')));
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 || "RadioCard[".concat(index, "]");
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;
@@ -0,0 +1,2 @@
1
+ import Responsive from './Responsive';
2
+ 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 selectIconsContainerStyle = _ref2 => {
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
- } = _ref3;
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((_ref4, ref) => {
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
- } = _ref4;
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 !== null && placeholder !== void 0 ? placeholder : a11yLabelText;
125
+ const placeholderText = placeholder ?? a11yLabelText;
138
126
  const {
139
127
  nativeID,
140
128
  testID,
141
129
  ...containerProps
142
130
  } = selectContainerProps(rest);
143
- return /*#__PURE__*/_jsxs(View, {
144
- style: staticStyles.container,
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
- }), /*#__PURE__*/_jsx(View, {
168
- style: [staticStyles.iconsContainer, selectIconsContainerStyle(themeTokens)],
169
- children: /*#__PURE__*/_jsxs(StackView, {
170
- direction: "row",
171
- space: buttonsGap,
172
- children: [ClearButtonIcon && !isEmpty && /*#__PURE__*/_jsx(ButtonBase, {
173
- onPress: handleClear,
174
- inactive: inactive,
175
- accessibilityRole: "button",
176
- accessibilityLabel: getCopy('clearButtonAccessibilityLabel'),
177
- tokens: appearances => selectButtonTokens(getButtonTokens(appearances)),
178
- children: buttonState => /*#__PURE__*/_jsx(ClearButtonIcon, { ...selectIconTokens(getButtonTokens(buttonState))
179
- })
180
- }), SubmitButtonIcon && /*#__PURE__*/_jsx(ButtonBase, {
181
- onPress: handleSubmit,
182
- inactive: inactive,
183
- accessibilityRole: "button",
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
- children: buttonState => /*#__PURE__*/_jsx(SubmitButtonIcon, { ...selectIconTokens(getButtonTokens({ ...buttonState,
189
- priority: 'high'
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;
@@ -0,0 +1,5 @@
1
+ // Because Android
2
+ export const ANDROID_VALIDATION_ICON_CONTAINER_OFFSET = 5;
3
+ export const ANDROID_HEIGHT_OFFSET = 12;
4
+ export const ANDROID_HORIZONTAL_PADDING_OFFSET = 8;
5
+ export const ANDROID_DEFAULT_PADDING = 0;
@@ -63,7 +63,7 @@ const SideNav = /*#__PURE__*/forwardRef((_ref, ref) => {
63
63
 
64
64
  const renderItem = (item, index, groupId) => {
65
65
  const {
66
- itemId = "item-".concat(index),
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 = "group-".concat(index)
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
- }, "skeleton-".concat(index + 1));
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: "".concat(ANIMATION_DURATION, "ms"),
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 = (_props$gap = props.gap) !== null && _props$gap !== void 0 ? _props$gap : space;
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 = "Stack-Box-".concat(index);
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 = "Stack-".concat(divider ? 'Divider' : 'Spacer', "-").concat(index);
61
+ const testID = `Stack-${divider ? 'Divider' : 'Spacer'}-${index}`;
62
62
  const commonProps = {
63
63
  testID,
64
64
  key: testID,
@@ -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 = (_restProps$accessibil = restProps.accessibilityRole) !== null && _restProps$accessibil !== void 0 ? _restProps$accessibil : 'tablist';
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 !== null && id !== void 0 ? id : label;
102
+ const itemId = id ?? label;
105
103
  const isSelected = Boolean(currentValue && currentValue === itemId);
106
104
 
107
105
  const handlePress = event => {
@@ -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 selectIconTextTokens = _ref => {
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 => selectTokens('Button', getItemTokens(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("Tags items must have unique ".concat(uniqueFields.join(', ')));
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 { a11yProps, getTokensPropType, selectSystemProps, textInputHandlerProps, textInputProps, useInputValue, variantProp, viewProps } from '../utils';
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 TextInputBase = /*#__PURE__*/forwardRef((_ref5, ref) => {
127
+ const selectButtonsContainerStyle = _ref5 => {
125
128
  let {
126
- value,
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
- readOnly,
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
- } = _ref5;
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
- value: PropTypes.string,
262
+ buttons: PropTypes.arrayOf(PropTypes.node),
238
263
  height: PropTypes.number,
239
- initialValue: PropTypes.string,
240
264
  inactive: PropTypes.bool,
241
- readOnly: PropTypes.bool,
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 ? "".concat(fontSize / fontBasePixels, "rem") : fontSize;
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 = "".concat(fontName).concat(fontWeight).concat(fontStyle);
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: "".concat(insetString).concat(offsetX, "px ").concat(offsetY, "px ").concat(blur, "px ").concat(spread, "px ").concat(color)
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("Called useTheme's getStyle on \"".concat(componentName, "\" with no theme provided"));
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("Theme \"".concat(themeName, "\" has no components defined (looking for \"").concat(componentName, "\")"));
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("Theme \"".concat(themeName, "\" does not have styles for component \"").concat(componentName, "\""));
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 = (_appearances$key = appearances[key]) !== null && _appearances$key !== void 0 ? _appearances$key : null;
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("Invalid UDS token schema version detected.\n\nThe UDS base components ".concat(pkg.name, " v").concat(pkg.version, " are only compatible with UDS themes that are built with @telus-uds/system-theme-tokens version that is semver compatible with ").concat(expectedThemeTokensVersion, ". The current theme was built with @telus-uds/system-theme-tokens v").concat(actualThemeTokensVersion, ".\n\nIf you see this error than most likely you have attempted to install ").concat(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"));
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
- }, "timeline-".concat(index, "-").concat(child.displayName));
144
+ }, `timeline-${index}-${child.displayName}`);
145
145
  })
146
146
  });
147
147
  });