@telus-uds/components-base 3.22.0 → 3.24.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +29 -1
  2. package/lib/cjs/Button/Button.js +2 -0
  3. package/lib/cjs/Button/ButtonBase.js +10 -5
  4. package/lib/cjs/Button/ButtonDropdown.js +2 -0
  5. package/lib/cjs/Button/ButtonGroup.js +45 -38
  6. package/lib/cjs/Button/propTypes.js +6 -0
  7. package/lib/cjs/Card/CardBase.js +97 -17
  8. package/lib/cjs/Card/PressableCardBase.js +12 -8
  9. package/lib/cjs/Carousel/Carousel.js +52 -19
  10. package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +23 -3
  11. package/lib/cjs/HorizontalScroll/HorizontalScroll.js +5 -2
  12. package/lib/cjs/Icon/Icon.js +11 -11
  13. package/lib/cjs/Icon/IconText.js +0 -1
  14. package/lib/cjs/Listbox/GroupControl.js +44 -44
  15. package/lib/cjs/Listbox/Listbox.js +63 -20
  16. package/lib/cjs/Listbox/ListboxGroup.js +141 -9
  17. package/lib/cjs/Listbox/ListboxOverlay.js +13 -5
  18. package/lib/cjs/Listbox/PressableItem.js +8 -4
  19. package/lib/cjs/Listbox/SecondLevelHeader.js +201 -0
  20. package/lib/cjs/Listbox/dictionary.js +14 -0
  21. package/lib/cjs/Shortcuts/Shortcuts.js +169 -0
  22. package/lib/cjs/Shortcuts/ShortcutsItem.js +280 -0
  23. package/lib/cjs/Shortcuts/index.js +16 -0
  24. package/lib/cjs/TextInput/TextInputBase.js +5 -1
  25. package/lib/cjs/Tooltip/Tooltip.native.js +2 -0
  26. package/lib/cjs/Validator/Validator.js +171 -135
  27. package/lib/cjs/index.js +15 -0
  28. package/lib/esm/Button/Button.js +2 -0
  29. package/lib/esm/Button/ButtonBase.js +10 -5
  30. package/lib/esm/Button/ButtonDropdown.js +2 -0
  31. package/lib/esm/Button/ButtonGroup.js +44 -39
  32. package/lib/esm/Button/propTypes.js +6 -0
  33. package/lib/esm/Card/CardBase.js +97 -17
  34. package/lib/esm/Card/PressableCardBase.js +10 -8
  35. package/lib/esm/Carousel/Carousel.js +52 -19
  36. package/lib/esm/Carousel/CarouselItem/CarouselItem.js +23 -3
  37. package/lib/esm/HorizontalScroll/HorizontalScroll.js +6 -3
  38. package/lib/esm/Icon/Icon.js +11 -11
  39. package/lib/esm/Icon/IconText.js +0 -1
  40. package/lib/esm/Listbox/GroupControl.js +44 -44
  41. package/lib/esm/Listbox/Listbox.js +64 -21
  42. package/lib/esm/Listbox/ListboxGroup.js +143 -11
  43. package/lib/esm/Listbox/ListboxOverlay.js +13 -5
  44. package/lib/esm/Listbox/PressableItem.js +8 -4
  45. package/lib/esm/Listbox/SecondLevelHeader.js +194 -0
  46. package/lib/esm/Listbox/dictionary.js +8 -0
  47. package/lib/esm/Shortcuts/Shortcuts.js +160 -0
  48. package/lib/esm/Shortcuts/ShortcutsItem.js +273 -0
  49. package/lib/esm/Shortcuts/index.js +3 -0
  50. package/lib/esm/TextInput/TextInputBase.js +5 -1
  51. package/lib/esm/Tooltip/Tooltip.native.js +2 -0
  52. package/lib/esm/Validator/Validator.js +171 -135
  53. package/lib/esm/index.js +1 -0
  54. package/lib/package.json +2 -2
  55. package/package.json +2 -2
  56. package/src/Button/Button.jsx +2 -1
  57. package/src/Button/ButtonBase.jsx +18 -12
  58. package/src/Button/ButtonDropdown.jsx +2 -0
  59. package/src/Button/ButtonGroup.jsx +62 -45
  60. package/src/Button/propTypes.js +6 -0
  61. package/src/Card/CardBase.jsx +113 -14
  62. package/src/Card/PressableCardBase.jsx +17 -5
  63. package/src/Carousel/Carousel.jsx +58 -5
  64. package/src/Carousel/CarouselItem/CarouselItem.jsx +31 -3
  65. package/src/HorizontalScroll/HorizontalScroll.jsx +6 -3
  66. package/src/Icon/Icon.jsx +14 -14
  67. package/src/Icon/IconText.jsx +0 -1
  68. package/src/Listbox/GroupControl.jsx +72 -70
  69. package/src/Listbox/Listbox.jsx +67 -11
  70. package/src/Listbox/ListboxGroup.jsx +160 -27
  71. package/src/Listbox/ListboxOverlay.jsx +23 -5
  72. package/src/Listbox/PressableItem.jsx +8 -4
  73. package/src/Listbox/SecondLevelHeader.jsx +182 -0
  74. package/src/Listbox/dictionary.js +8 -0
  75. package/src/Shortcuts/Shortcuts.jsx +174 -0
  76. package/src/Shortcuts/ShortcutsItem.jsx +297 -0
  77. package/src/Shortcuts/index.js +4 -0
  78. package/src/TextInput/TextInputBase.jsx +5 -1
  79. package/src/Tooltip/Tooltip.native.jsx +2 -1
  80. package/src/Validator/Validator.jsx +180 -159
  81. package/src/index.js +1 -0
  82. package/types/Listbox.d.ts +24 -0
  83. package/types/Shortcuts.d.ts +136 -0
  84. package/types/index.d.ts +12 -0
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _react = _interopRequireDefault(require("react"));
8
+ var _Image = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Image"));
9
+ var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
10
+ var _Pressable = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Pressable"));
11
+ var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
12
+ var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
13
+ var _propTypes = _interopRequireDefault(require("prop-types"));
14
+ var _ThemeProvider = require("../ThemeProvider");
15
+ var _utils = require("../utils");
16
+ var _Icon = _interopRequireDefault(require("../Icon"));
17
+ var _jsxRuntime = require("react/jsx-runtime");
18
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
+ const DYNAMIC_WIDTH_VARIANT = 'dynamic';
20
+ const EQUAL_WIDTH_VARIANT = 'equal';
21
+ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.linkProps, _utils.viewProps]);
22
+ const selectPressableStyles = (tokens, widthVariant, equalWidth) => {
23
+ const styles = {
24
+ borderColor: tokens.borderColor,
25
+ borderRadius: tokens.borderRadius,
26
+ borderWidth: tokens.borderWidth,
27
+ ..._Platform.default.select({
28
+ web: {
29
+ outline: 'none'
30
+ }
31
+ })
32
+ };
33
+ if (widthVariant === DYNAMIC_WIDTH_VARIANT) {
34
+ styles.width = 'auto';
35
+ } else if (widthVariant === EQUAL_WIDTH_VARIANT) {
36
+ if (equalWidth) {
37
+ styles.width = equalWidth;
38
+ } else {
39
+ styles.minWidth = tokens.width;
40
+ }
41
+ } else {
42
+ styles.width = tokens.width;
43
+ }
44
+ return styles;
45
+ };
46
+ const selectIconContainerStyles = tokens => ({
47
+ paddingBottom: tokens.iconContainerPaddingBottom,
48
+ paddingLeft: tokens.iconContainerPaddingLeft,
49
+ paddingRight: tokens.iconContainerPaddingRight,
50
+ paddingTop: tokens.iconContainerPaddingTop
51
+ });
52
+ const selectIconVariant = () => ({
53
+ background: true,
54
+ padding: 'medium'
55
+ });
56
+ const selectIconTokens = tokens => ({
57
+ backgroundColor: tokens.iconBackgroundColor,
58
+ color: tokens.iconColor,
59
+ size: tokens.iconSize,
60
+ width: tokens.iconWidth
61
+ });
62
+ const selectImageStyles = tokens => ({
63
+ width: tokens.imageWidth,
64
+ height: tokens.imageHeight
65
+ });
66
+ const selectLabelContainerStyles = tokens => ({
67
+ paddingBottom: tokens.labelContainerPaddingBottom,
68
+ paddingLeft: tokens.labelContainerPaddingLeft,
69
+ paddingRight: tokens.labelContainerPaddingRight,
70
+ paddingTop: tokens.labelContainerPaddingTop
71
+ });
72
+ const selectTitleTextStyles = tokens => (0, _ThemeProvider.applyTextStyles)({
73
+ fontColor: tokens.labelFontColor,
74
+ fontName: tokens.labelFontName,
75
+ fontSize: tokens.labelFontSize,
76
+ fontWeight: tokens.labelFontWeight,
77
+ lineHeight: tokens.labelLineHeight,
78
+ textDecorationLine: tokens.labelUnderline,
79
+ textAlign: tokens.labelTextAlign
80
+ });
81
+
82
+ /**
83
+ * A clickable shortcut item component that displays an icon or image with an optional label.
84
+ * Can be used within a Shortcuts container to create a grid of navigation shortcuts.
85
+ *
86
+ * @component
87
+ * @param {Object} props - Component props
88
+ * @param {string} [props.icon] - Icon identifier to display
89
+ * @param {Object} [props.image={ src: '', alt: '' }] - Image object with src and alt properties
90
+ * @param {string} [props.image.src] - Image source URL
91
+ * @param {string} [props.image.alt] - Image alt text for accessibility
92
+ * @param {string|React.ReactNode} props.label - Label text or content to display below the icon/image
93
+ * @param {boolean} [props.hideLabel=false] - Whether to hide the label for this specific item
94
+ * @param {string} [props.href] - Link URL for navigation
95
+ * @param {Object} [props.iconVariant] - Icon variant to apply to this specific item
96
+ * @param {Object} [props.tokens] - Theme tokens to customize appearance
97
+ * @param {Object} [props.variant] - Variant configuration object for this specific item
98
+ * @param {string} [props.variant.width] - Width variant (e.g., 'dynamic', 'equal')
99
+ * @param {Function} [props.onPressableStateChange] - Callback function that receives the pressable state object (pressed, hovered, focused)
100
+ * @param {number} [props.maxWidth] - Maximum width for equal width variant (injected by Shortcuts container)
101
+ * @param {Function} [props.registerWidth] - Callback to register width for equal width variant (injected by Shortcuts container)
102
+ * @param {Object} [props.containerVariant] - Variant configuration from Shortcuts container (injected by Shortcuts container)
103
+ * @param {boolean} [props.containerHideLabels] - Hide labels setting from Shortcuts container (injected by Shortcuts container)
104
+ * @param {Object} [props.containerIconVariant] - Icon variant from Shortcuts container (injected by Shortcuts container)
105
+ * @param {React.Ref} ref - Forwarded ref to the Pressable component
106
+ * @returns {React.ReactElement} The rendered shortcut item
107
+ *
108
+ * @example
109
+ * <ShortcutsItem
110
+ * icon={HomeIcon}
111
+ * label="Home"
112
+ * href="/home"
113
+ * onPressableStateChange={(state) => console.log(state)}
114
+ * />
115
+ */
116
+ const ShortcutsItem = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
117
+ let {
118
+ icon,
119
+ image = {
120
+ src: '',
121
+ alt: ''
122
+ },
123
+ label,
124
+ hideLabel = false,
125
+ href,
126
+ iconVariant,
127
+ tokens,
128
+ variant,
129
+ onPressableStateChange,
130
+ maxWidth,
131
+ registerWidth,
132
+ containerVariant,
133
+ containerHideLabels,
134
+ containerIconVariant,
135
+ ...rest
136
+ } = _ref;
137
+ const mergedVariant = {
138
+ ...containerVariant,
139
+ ...variant
140
+ };
141
+ const widthVariant = mergedVariant?.width;
142
+ const shouldHideLabel = hideLabel || containerHideLabels;
143
+ const mergedIconVariant = iconVariant ?? containerIconVariant;
144
+ const getThemeTokens = (0, _ThemeProvider.useThemeTokensCallback)('ShortcutsItem', tokens, mergedVariant);
145
+ const getTokens = pressableState => getThemeTokens((0, _utils.resolvePressableState)(pressableState));
146
+ const {
147
+ onPress,
148
+ ...props
149
+ } = _utils.clickProps.toPressProps(rest);
150
+ const {
151
+ hrefAttrs,
152
+ rawRest
153
+ } = _utils.hrefAttrsProp.bundle(props);
154
+ const selectedProps = selectProps({
155
+ href,
156
+ onPress: _utils.linkProps.handleHref({
157
+ href,
158
+ onPress
159
+ }),
160
+ hrefAttrs,
161
+ ...rawRest
162
+ });
163
+ const handleLayout = event => {
164
+ if (widthVariant === EQUAL_WIDTH_VARIANT && registerWidth) {
165
+ const {
166
+ width
167
+ } = event.nativeEvent.layout;
168
+ registerWidth(width);
169
+ }
170
+ };
171
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Pressable.default, {
172
+ ref: ref,
173
+ style: pressableState => selectPressableStyles(getTokens(pressableState), widthVariant, maxWidth),
174
+ onLayout: handleLayout,
175
+ ...selectedProps,
176
+ children: pressableState => {
177
+ const themeTokens = getTokens(pressableState);
178
+ if (onPressableStateChange) {
179
+ onPressableStateChange((0, _utils.resolvePressableState)(pressableState));
180
+ }
181
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
182
+ style: staticStyles.container,
183
+ children: [icon && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
184
+ style: selectIconContainerStyles(themeTokens),
185
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, {
186
+ icon: icon,
187
+ variant: mergedIconVariant ?? selectIconVariant(),
188
+ tokens: mergedIconVariant ? {} : selectIconTokens(themeTokens),
189
+ ...(_Platform.default.OS === 'web' && {
190
+ accessibilityLabel: label
191
+ })
192
+ })
193
+ }), !icon && image && /*#__PURE__*/(0, _jsxRuntime.jsx)(_Image.default, {
194
+ source: image.src,
195
+ alt: image.alt,
196
+ style: selectImageStyles(themeTokens),
197
+ resizeMethod: "resize",
198
+ accessibilityIgnoresInvertColors: true
199
+ }), label && !shouldHideLabel && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
200
+ style: [staticStyles.label, selectLabelContainerStyles(themeTokens)],
201
+ children: (0, _utils.wrapStringsInText)(label, {
202
+ style: selectTitleTextStyles(themeTokens)
203
+ })
204
+ })]
205
+ });
206
+ }
207
+ });
208
+ });
209
+ ShortcutsItem.displayName = 'ShortcutsItem';
210
+ ShortcutsItem.propTypes = {
211
+ ...selectedSystemPropTypes,
212
+ tokens: (0, _utils.getTokensPropType)('ShortcutsItem'),
213
+ variant: _utils.variantProp.propType,
214
+ /**
215
+ * Icon for the ShortcutsItem
216
+ */
217
+ icon: _propTypes.default.elementType,
218
+ /**
219
+ * Image for the ShortcutsItem
220
+ */
221
+ image: _propTypes.default.shape({
222
+ src: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number, _propTypes.default.object]),
223
+ alt: _propTypes.default.string
224
+ }),
225
+ /**
226
+ * Label for the ShortcutsItem
227
+ */
228
+ label: _propTypes.default.string,
229
+ /**
230
+ * Hide the label for this specific ShortcutsItem. When true, the label is visually hidden but remains accessible to screen readers via the icon's accessibilityLabel.
231
+ */
232
+ hideLabel: _propTypes.default.bool,
233
+ /**
234
+ * href for the ShortcutsItem
235
+ */
236
+ href: _propTypes.default.string,
237
+ /**
238
+ * Icon variant for this specific ShortcutsItem
239
+ */
240
+ iconVariant: _utils.variantProp.propType,
241
+ /**
242
+ * Callback function that receives the pressable state object containing pressed, hovered, and focused boolean properties
243
+ */
244
+ onPressableStateChange: _propTypes.default.func,
245
+ /**
246
+ * Maximum width for equal width variant (automatically injected by Shortcuts container)
247
+ * @private
248
+ */
249
+ maxWidth: _propTypes.default.number,
250
+ /**
251
+ * Callback to register width for equal width variant (automatically injected by Shortcuts container)
252
+ * @private
253
+ */
254
+ registerWidth: _propTypes.default.func,
255
+ /**
256
+ * Variant configuration from Shortcuts container (automatically injected by Shortcuts container)
257
+ * @private
258
+ */
259
+ containerVariant: _utils.variantProp.propType,
260
+ /**
261
+ * Hide labels setting from Shortcuts container (automatically injected by Shortcuts container)
262
+ * @private
263
+ */
264
+ containerHideLabels: _propTypes.default.bool,
265
+ /**
266
+ * Icon variant from Shortcuts container (automatically injected by Shortcuts container)
267
+ * @private
268
+ */
269
+ containerIconVariant: _utils.variantProp.propType
270
+ };
271
+ const staticStyles = _StyleSheet.default.create({
272
+ container: {
273
+ alignItems: 'center',
274
+ justifyContent: 'center'
275
+ },
276
+ label: {
277
+ flexWrap: 'wrap'
278
+ }
279
+ });
280
+ var _default = exports.default = ShortcutsItem;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "ShortcutsItem", {
7
+ enumerable: true,
8
+ get: function () {
9
+ return _ShortcutsItem.default;
10
+ }
11
+ });
12
+ exports.default = void 0;
13
+ var _Shortcuts = _interopRequireDefault(require("./Shortcuts"));
14
+ var _ShortcutsItem = _interopRequireDefault(require("./ShortcutsItem"));
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ var _default = exports.default = _Shortcuts.default;
@@ -286,6 +286,10 @@ const TextInputBase = /*#__PURE__*/_react.default.forwardRef((_ref8, ref) => {
286
286
  // Add a space every 4 digits starting from the 5th position
287
287
  filteredText = formattedValue.replace(regex, '$1 ').trim();
288
288
  }
289
+ // Apply maxLength if provided
290
+ if (rest.maxLength && filteredText && filteredText.length > rest.maxLength) {
291
+ filteredText = filteredText.substring(0, rest.maxLength);
292
+ }
289
293
  setValue(filteredText, event);
290
294
  if (typeof onChangeText === 'function') onChangeText(filteredText, event);
291
295
  };
@@ -358,7 +362,7 @@ const TextInputBase = /*#__PURE__*/_react.default.forwardRef((_ref8, ref) => {
358
362
  onMouseOut: handleMouseOut,
359
363
  onChange: handleChangeText,
360
364
  defaultValue: initialValue,
361
- maxLength: type === 'card' ? 19 : undefined,
365
+ maxLength: type === 'card' ? 19 : rest.maxLength,
362
366
  value: isControlled ? currentValue : undefined,
363
367
  onKeyPress
364
368
  };
@@ -169,6 +169,7 @@ const Tooltip = /*#__PURE__*/_react.default.forwardRef((_ref7, ref) => {
169
169
  nativeID,
170
170
  activateOnHover = false,
171
171
  tooltipButtonTokens,
172
+ testID,
172
173
  ...rest
173
174
  } = _ref7;
174
175
  const [isOpen, setIsOpen] = _react.default.useState(false);
@@ -312,6 +313,7 @@ const Tooltip = /*#__PURE__*/_react.default.forwardRef((_ref7, ref) => {
312
313
  display: inline ? 'inline-block' : 'flex'
313
314
  }
314
315
  })],
316
+ testID: testID,
315
317
  ...selectProps(rest),
316
318
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Pressable.default, {
317
319
  onPress: toggleIsOpen,