@telus-uds/components-base 1.12.1 → 1.14.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 (84) hide show
  1. package/CHANGELOG.md +41 -2
  2. package/component-docs.json +888 -66
  3. package/lib/Button/ButtonBase.js +36 -7
  4. package/lib/Button/ButtonGroup.js +7 -0
  5. package/lib/Button/propTypes.js +18 -0
  6. package/lib/Carousel/Carousel.js +69 -12
  7. package/lib/Carousel/CarouselContext.js +17 -11
  8. package/lib/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +73 -0
  9. package/lib/Carousel/CarouselTabs/CarouselTabs.js +70 -0
  10. package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +95 -0
  11. package/lib/Carousel/CarouselTabs/CarouselTabsPanelItem.js +148 -0
  12. package/lib/Carousel/CarouselTabs/index.js +13 -0
  13. package/lib/Carousel/CarouselThumbnail.js +99 -0
  14. package/lib/Carousel/CarouselThumbnailNavigation.js +87 -0
  15. package/lib/Carousel/dictionary.js +4 -2
  16. package/lib/Carousel/index.js +10 -1
  17. package/lib/Checkbox/CheckboxGroup.js +7 -0
  18. package/lib/Icon/IconText.js +1 -1
  19. package/lib/Link/InlinePressable.js +1 -8
  20. package/lib/Link/LinkBase.js +6 -7
  21. package/lib/List/ListItem.js +1 -1
  22. package/lib/Notification/Notification.js +37 -22
  23. package/lib/Radio/RadioGroup.js +8 -0
  24. package/lib/RadioCard/RadioCardGroup.js +7 -0
  25. package/lib/SkipLink/SkipLink.js +216 -0
  26. package/lib/SkipLink/index.js +13 -0
  27. package/lib/ThemeProvider/ThemeProvider.js +6 -1
  28. package/lib/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  29. package/lib/index.js +9 -0
  30. package/lib-module/Button/ButtonBase.js +35 -7
  31. package/lib-module/Button/ButtonGroup.js +7 -0
  32. package/lib-module/Button/propTypes.js +17 -0
  33. package/lib-module/Carousel/Carousel.js +66 -11
  34. package/lib-module/Carousel/CarouselContext.js +17 -11
  35. package/lib-module/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +51 -0
  36. package/lib-module/Carousel/CarouselTabs/CarouselTabs.js +50 -0
  37. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +76 -0
  38. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanelItem.js +126 -0
  39. package/lib-module/Carousel/CarouselTabs/index.js +2 -0
  40. package/lib-module/Carousel/CarouselThumbnail.js +85 -0
  41. package/lib-module/Carousel/CarouselThumbnailNavigation.js +66 -0
  42. package/lib-module/Carousel/dictionary.js +4 -2
  43. package/lib-module/Carousel/index.js +2 -1
  44. package/lib-module/Checkbox/CheckboxGroup.js +7 -0
  45. package/lib-module/Icon/IconText.js +1 -1
  46. package/lib-module/Link/InlinePressable.js +1 -8
  47. package/lib-module/Link/LinkBase.js +6 -7
  48. package/lib-module/List/ListItem.js +1 -1
  49. package/lib-module/Notification/Notification.js +38 -23
  50. package/lib-module/Radio/RadioGroup.js +8 -0
  51. package/lib-module/RadioCard/RadioCardGroup.js +7 -0
  52. package/lib-module/SkipLink/SkipLink.js +188 -0
  53. package/lib-module/SkipLink/index.js +2 -0
  54. package/lib-module/ThemeProvider/ThemeProvider.js +5 -1
  55. package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  56. package/lib-module/index.js +1 -0
  57. package/package.json +46 -47
  58. package/src/Button/ButtonBase.jsx +28 -9
  59. package/src/Button/ButtonGroup.jsx +6 -0
  60. package/src/Button/propTypes.js +14 -0
  61. package/src/Carousel/Carousel.jsx +68 -10
  62. package/src/Carousel/CarouselContext.jsx +22 -9
  63. package/src/Carousel/CarouselFirstFocus/CarouselFirstFocus.jsx +49 -0
  64. package/src/Carousel/CarouselTabs/CarouselTabs.jsx +37 -0
  65. package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +69 -0
  66. package/src/Carousel/CarouselTabs/CarouselTabsPanelItem.jsx +119 -0
  67. package/src/Carousel/CarouselTabs/index.js +3 -0
  68. package/src/Carousel/CarouselThumbnail.jsx +77 -0
  69. package/src/Carousel/CarouselThumbnailNavigation.jsx +53 -0
  70. package/src/Carousel/dictionary.js +4 -2
  71. package/src/Carousel/index.js +1 -0
  72. package/src/Checkbox/CheckboxGroup.jsx +7 -0
  73. package/src/Icon/IconText.jsx +1 -1
  74. package/src/Link/InlinePressable.jsx +2 -8
  75. package/src/Link/LinkBase.jsx +8 -17
  76. package/src/List/ListItem.jsx +1 -1
  77. package/src/Notification/Notification.jsx +35 -20
  78. package/src/Radio/RadioGroup.jsx +7 -0
  79. package/src/RadioCard/RadioCardGroup.jsx +6 -0
  80. package/src/SkipLink/SkipLink.jsx +179 -0
  81. package/src/SkipLink/index.js +3 -0
  82. package/src/ThemeProvider/ThemeProvider.jsx +7 -1
  83. package/src/ToggleSwitch/ToggleSwitchGroup.jsx +6 -0
  84. package/src/index.js +1 -0
@@ -23,6 +23,8 @@ var _propTypes2 = _interopRequireDefault(require("./propTypes"));
23
23
 
24
24
  var _utils = require("../utils");
25
25
 
26
+ var _Icon = require("../Icon");
27
+
26
28
  var _jsxRuntime = require("react/jsx-runtime");
27
29
 
28
30
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -190,7 +192,18 @@ const selectWebOnlyStyles = (inactive, themeTokens, _ref7) => {
190
192
  });
191
193
  };
192
194
 
193
- const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref8, ref) => {
195
+ const selectItemIconTokens = _ref8 => {
196
+ let {
197
+ color,
198
+ iconSize
199
+ } = _ref8;
200
+ return {
201
+ size: iconSize,
202
+ color
203
+ };
204
+ };
205
+
206
+ const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref9, ref) => {
194
207
  let {
195
208
  id,
196
209
  href,
@@ -201,8 +214,11 @@ const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref8, ref) => {
201
214
  // alias for inactive
202
215
  inactive = disabled,
203
216
  selected = false,
217
+ icon,
218
+ iconPosition = icon ? 'left' : undefined,
219
+ iconProps,
204
220
  ...rawRest
205
- } = _ref8;
221
+ } = _ref9;
206
222
 
207
223
  const {
208
224
  onPress,
@@ -241,10 +257,15 @@ const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref8, ref) => {
241
257
  const themeTokens = resolveButtonTokens(pressableState);
242
258
  const containerStyles = selectInnerContainerStyles(themeTokens);
243
259
  const borderStyles = selectBorderStyles(themeTokens);
244
- const textStyles = [selectTextStyles(themeTokens, themeOptions), staticStyles.text]; // If the container has a width set, fill it instead of sizing from content.
260
+ const textStyles = [selectTextStyles(themeTokens, themeOptions), staticStyles.text];
261
+ const iconTokens = selectItemIconTokens(themeTokens);
262
+ const {
263
+ iconSpace
264
+ } = themeTokens; // If the container has a width set, fill it instead of sizing from content.
245
265
  // If in future we support text alignments other than center, add here.
246
266
 
247
267
  const stretchStyles = themeTokens.width ? staticStyles.stretch : staticStyles.align;
268
+ const IconComponent = icon || themeTokens.icon;
248
269
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
249
270
  id: id,
250
271
  style: [containerStyles, borderStyles, stretchStyles, staticStyles.row, _Platform.default.select({
@@ -255,10 +276,18 @@ const ButtonBase = /*#__PURE__*/(0, _react.forwardRef)((_ref8, ref) => {
255
276
  transition: 'background-color 200ms, border-color 200ms'
256
277
  }
257
278
  })],
258
- children: (0, _utils.wrapStringsInText)(typeof children === 'function' ? children({ ...(0, _utils.resolvePressableState)(pressableState, extraButtonState),
259
- textStyles
260
- }) : children, {
261
- style: textStyles
279
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.IconText, {
280
+ icon: IconComponent,
281
+ iconPosition: iconPosition,
282
+ space: iconSpace,
283
+ iconProps: { ...iconProps,
284
+ tokens: iconTokens
285
+ },
286
+ children: (0, _utils.wrapStringsInText)(typeof children === 'function' ? children({ ...(0, _utils.resolvePressableState)(pressableState, extraButtonState),
287
+ textStyles
288
+ }) : children, {
289
+ style: textStyles
290
+ })
262
291
  })
263
292
  });
264
293
  }
@@ -51,6 +51,7 @@ const ButtonGroup = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
51
51
  legend,
52
52
  tooltip,
53
53
  hint,
54
+ hintPosition = 'inline',
54
55
  validation,
55
56
  feedback,
56
57
  name: inputGroupName,
@@ -102,6 +103,7 @@ const ButtonGroup = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
102
103
  legend: legend,
103
104
  tooltip: tooltip,
104
105
  hint: hint,
106
+ hintPosition: hintPosition,
105
107
  space: fieldSpace,
106
108
  feedback: feedback,
107
109
  readOnly: readOnly,
@@ -233,6 +235,11 @@ ButtonGroup.propTypes = { ...selectedSystemPropTypes,
233
235
  */
234
236
  hint: _propTypes.default.string,
235
237
 
238
+ /**
239
+ * Position of the hint relative to label. Use `below` to display a larger hint below the label.
240
+ */
241
+ hintPosition: _propTypes.default.oneOf(['inline', 'below']),
242
+
236
243
  /**
237
244
  * Optional tooltip text content to include alongside the legend and hint.
238
245
  */
@@ -13,6 +13,8 @@ var _props = require("../utils/props");
13
13
 
14
14
  var _A11yText = _interopRequireDefault(require("../A11yText"));
15
15
 
16
+ var _Icon = require("../Icon");
17
+
16
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
19
 
18
20
  const textAndA11yText = _airbnbPropTypes.default.childrenOf(_propTypes.default.oneOfType([_airbnbPropTypes.default.elementType(_A11yText.default), _propTypes.default.string]));
@@ -46,6 +48,22 @@ const buttonPropTypes = {
46
48
  * Function called when the button is pressed. Required unless the button has a href.
47
49
  */
48
50
  onPress: _propTypes.default.func,
51
+
52
+ /**
53
+ * Optional variant that may be passed down to the link's icon if there is one
54
+ */
55
+ iconProps: _propTypes.default.exact(_Icon.iconComponentPropTypes),
56
+
57
+ /**
58
+ * When `icon` is provided, use `iconPosition` to place the Icon to the left or right side of the button.
59
+ */
60
+ iconPosition: _propTypes.default.oneOf(['left', 'right']),
61
+
62
+ /**
63
+ * A function component for an SVG icon to render inside the link. Inherits size and color from
64
+ * the link and any Typography the link is nested inside.
65
+ */
66
+ icon: _propTypes.default.func,
49
67
  variant: _props.variantProp.propType
50
68
  };
51
69
  var _default = buttonPropTypes;
@@ -33,7 +33,13 @@ var _CarouselItem = _interopRequireDefault(require("./CarouselItem"));
33
33
 
34
34
  var _IconButton = _interopRequireDefault(require("../IconButton"));
35
35
 
36
- var _CarouselStepTracker = _interopRequireDefault(require("./CarouselStepTracker/CarouselStepTracker"));
36
+ var _SkipLink = _interopRequireDefault(require("../SkipLink"));
37
+
38
+ var _A11yText = _interopRequireDefault(require("../A11yText"));
39
+
40
+ var _CarouselStepTracker = _interopRequireDefault(require("./CarouselStepTracker"));
41
+
42
+ var _CarouselThumbnailNavigation = _interopRequireDefault(require("./CarouselThumbnailNavigation"));
37
43
 
38
44
  var _dictionary = _interopRequireDefault(require("./dictionary"));
39
45
 
@@ -159,11 +165,18 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
159
165
  onAnimationStart,
160
166
  onAnimationEnd,
161
167
  onIndexChanged,
168
+ skipLinkHref,
169
+ refocus,
170
+ title = 'carousel',
162
171
  springConfig = undefined,
163
- panelNavigation = /*#__PURE__*/(0, _jsxRuntime.jsx)(_CarouselStepTracker.default, {}),
172
+ thumbnails = undefined,
173
+ panelNavigation = thumbnails ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_CarouselThumbnailNavigation.default, {
174
+ thumbnails: thumbnails
175
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_CarouselStepTracker.default, {}),
164
176
  tag = 'ul',
165
- accessibilityRole = 'adjustable',
166
- accessibilityLabel = 'carousel',
177
+ accessibilityRole,
178
+ accessibilityLabel = title,
179
+ accessibilityLiveRegion = 'polite',
167
180
  copy,
168
181
  ...rest
169
182
  } = _ref;
@@ -197,9 +210,7 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
197
210
  dictionary: _dictionary.default,
198
211
  copy
199
212
  });
200
-
201
- const childrenArray = _react.default.Children.toArray(children);
202
-
213
+ const childrenArray = (0, _utils.unpackFragment)(children);
203
214
  const systemProps = selectProps({ ...rest,
204
215
  accessibilityRole,
205
216
  accessibilityLabel,
@@ -221,6 +232,8 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
221
232
 
222
233
  const [previousNextNavigationButtonWidth, setPreviousNextNavigationButtonWidth] = _react.default.useState(0);
223
234
 
235
+ const firstFocusRef = _react.default.useRef(null);
236
+
224
237
  const pan = _react.default.useRef(new _Animated.default.ValueXY()).current;
225
238
 
226
239
  const animatedX = _react.default.useRef(0);
@@ -326,10 +339,13 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
326
339
  }, [containerLayout.width, activeIndex, animate, children.length, onIndexChanged]);
327
340
 
328
341
  const fixOffsetAndGo = _react.default.useCallback(delta => {
342
+ var _firstFocusRef$curren;
343
+
329
344
  updateOffset();
330
345
  handleAnimationStart(activeIndex);
331
346
  updateIndex(delta);
332
- }, [updateIndex, updateOffset, activeIndex, handleAnimationStart]);
347
+ if (refocus) (_firstFocusRef$curren = firstFocusRef.current) === null || _firstFocusRef$curren === void 0 ? void 0 : _firstFocusRef$curren.focus();
348
+ }, [updateIndex, updateOffset, activeIndex, handleAnimationStart, refocus]);
333
349
 
334
350
  const goToNeighboring = _react.default.useCallback(function () {
335
351
  let toPrev = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
@@ -421,18 +437,21 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
421
437
  };
422
438
 
423
439
  const getCopyWithPlaceholders = _react.default.useCallback(copyKey => {
424
- const copyText = getCopy(copyKey).replace(/%\{itemLabel\}/g, itemLabel).replace(/%\{stepNumber\}/g, activeIndex + 1).replace(/%\{stepCount\}/g, childrenArray.length); // First word might be a lowercase placeholder: capitalize the first letter
440
+ const copyText = getCopy(copyKey).replace(/%\{title\}/g, title).replace(/%\{itemLabel\}/g, itemLabel).replace(/%\{stepNumber\}/g, activeIndex + 1).replace(/%\{stepCount\}/g, childrenArray.length); // First word might be a lowercase placeholder: capitalize the first letter
425
441
 
426
442
  return "".concat(copyText[0].toUpperCase()).concat(copyText.slice(1));
427
- }, [activeIndex, childrenArray.length, itemLabel, getCopy]);
443
+ }, [activeIndex, childrenArray.length, itemLabel, getCopy, title]);
428
444
 
429
445
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CarouselContext.CarouselProvider, {
430
446
  activeIndex: activeIndex,
431
- totalItems: childrenArray.length,
432
- width: containerLayout.width,
433
447
  goTo: goTo,
434
448
  getCopyWithPlaceholders: getCopyWithPlaceholders,
449
+ itemLabel: itemLabel,
450
+ totalItems: childrenArray.length,
435
451
  themeTokens: themeTokens,
452
+ firstFocusRef: firstFocusRef,
453
+ refocus: refocus,
454
+ width: containerLayout.width,
436
455
  children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
437
456
  style: staticStyles.root,
438
457
  onLayout: onContainerLayout,
@@ -448,6 +467,17 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
448
467
  variant: previousNextIconButtonVariants,
449
468
  accessibilityLabel: getCopyWithPlaceholders('iconButtonLabel').replace('%{targetStep}', activeIndex)
450
469
  })
470
+ }), Boolean(skipLinkHref) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_SkipLink.default, {
471
+ ref: firstFocusRef,
472
+ href: skipLinkHref,
473
+ children: getCopyWithPlaceholders('skipLink')
474
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_A11yText.default // Read the current slide position to screen readers on slide.
475
+ // If it's set to refocus and doesn't have a SkipLink to focus to, focus this.
476
+ , {
477
+ ref: !skipLinkHref && refocus ? firstFocusRef : null,
478
+ accessibilityLiveRegion: !skipLinkHref && refocus ? undefined : 'polite',
479
+ focusable: !skipLinkHref && refocus,
480
+ text: getCopyWithPlaceholders('stepTrackerLabel')
451
481
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
452
482
  style: selectContainerStyles(containerLayout.width),
453
483
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Animated.default.View, {
@@ -460,6 +490,9 @@ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
460
490
  }]),
461
491
  ...panResponder.panHandlers,
462
492
  ...(0, _utils.getA11yPropsFromHtmlTag)(tag),
493
+ // In iframes on Mac (e.g. in Storybook), this content may be misread or read twice.
494
+ // This is a known Voiceover bug: https://github.com/phetsims/a11y-research/issues/132
495
+ accessibilityLiveRegion: accessibilityLiveRegion,
463
496
  children: childrenArray.map((element, index) => {
464
497
  const hidden = !isAnimating && index !== activeIndex;
465
498
 
@@ -522,6 +555,15 @@ Carousel.propTypes = { ...selectedSystemPropTypes,
522
555
  */
523
556
  springConfig: _propTypes.default.object,
524
557
 
558
+ /**
559
+ * An array of objects containing information on the thumbnails to be rendered as navigation panel
560
+ */
561
+ thumbnails: _propTypes.default.arrayOf(_propTypes.default.shape({
562
+ accessibilityLabel: _propTypes.default.string,
563
+ alt: _propTypes.default.string,
564
+ src: _propTypes.default.string
565
+ })),
566
+
525
567
  /**
526
568
  * Minimal part of slide width must be swiped for changing index.
527
569
  * Otherwise animation restore current slide. Default value 0.2 means that 20% must be swiped for change index
@@ -551,6 +593,21 @@ Carousel.propTypes = { ...selectedSystemPropTypes,
551
593
  */
552
594
  onIndexChanged: _propTypes.default.func,
553
595
 
596
+ /**
597
+ * If this is a complex carousel with a lot of focusable content, pass a href for a skip link. Typically, this will be an anchor link
598
+ * with the ID of a focusable element immediately after the Carousel, e.g. `'#section-2-heading'`.
599
+ */
600
+ skipLinkHref: _propTypes.default.string,
601
+
602
+ /**
603
+ * If true, whenever a new slide comes into view, the focus of the Carousel switches to the start.
604
+ *
605
+ * Pass this as true when using carousel items that contain interactive content, so a user can easily tab into that content.
606
+ *
607
+ * If skipLinkHref is passed, the focus target will be the SkipLink; if not, it'll be an empty element before the slide content.
608
+ */
609
+ refocus: _propTypes.default.bool,
610
+
554
611
  /**
555
612
  * Use this to render a custom panel navigation element instead of the default StepTracker's based navigation
556
613
  * You can make use of `useCarousel` within your custom panel navigation component to hook into various Carousel states such as:
@@ -20,23 +20,27 @@ const CarouselContext = /*#__PURE__*/_react.default.createContext();
20
20
 
21
21
  const CarouselProvider = _ref => {
22
22
  let {
23
- children,
24
23
  activeIndex,
25
- totalItems,
26
- width,
24
+ children,
27
25
  goTo,
28
26
  getCopyWithPlaceholders,
29
- themeTokens
27
+ itemLabel,
28
+ refocus = false,
29
+ themeTokens,
30
+ totalItems,
31
+ width
30
32
  } = _ref;
31
33
 
32
34
  const value = _react.default.useMemo(() => ({
33
35
  activeIndex,
34
- totalItems,
35
- width,
36
36
  goTo,
37
37
  getCopyWithPlaceholders,
38
- themeTokens
39
- }), [activeIndex, totalItems, width, goTo, getCopyWithPlaceholders, themeTokens]);
38
+ itemLabel,
39
+ refocus,
40
+ themeTokens,
41
+ totalItems,
42
+ width
43
+ }), [activeIndex, goTo, getCopyWithPlaceholders, itemLabel, refocus, totalItems, themeTokens, width]);
40
44
 
41
45
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(CarouselContext.Provider, {
42
46
  value: value,
@@ -59,9 +63,11 @@ function useCarousel() {
59
63
  CarouselProvider.propTypes = {
60
64
  children: _propTypes.default.arrayOf(_propTypes.default.element).isRequired,
61
65
  activeIndex: _propTypes.default.number.isRequired,
62
- totalItems: _propTypes.default.number.isRequired,
63
- width: _propTypes.default.number.isRequired,
64
66
  goTo: _propTypes.default.func.isRequired,
65
67
  getCopyWithPlaceholders: _propTypes.default.func.isRequired,
66
- themeTokens: (0, _utils.getTokensPropType)('Carousel')
68
+ itemLabel: _propTypes.default.string.isRequired,
69
+ refocus: _propTypes.default.bool,
70
+ themeTokens: (0, _utils.getTokensPropType)('Carousel'),
71
+ totalItems: _propTypes.default.number.isRequired,
72
+ width: _propTypes.default.number.isRequired
67
73
  };
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = _interopRequireWildcard(require("react"));
9
+
10
+ var _Pressable = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Pressable"));
11
+
12
+ var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
13
+
14
+ var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
15
+
16
+ var _propTypes = require("prop-types");
17
+
18
+ var _CarouselContext = require("../CarouselContext");
19
+
20
+ var _jsxRuntime = require("react/jsx-runtime");
21
+
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
+
24
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
+
26
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
27
+
28
+ /**
29
+ * Focus target so that when a new slide is shown, the user can tab into
30
+ * its content using the keyboard.
31
+ *
32
+ * @TODO rework this after integrating with SkipLink when available.
33
+ */
34
+ const CarouselFirstFocus = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
35
+ let {
36
+ title
37
+ } = _ref;
38
+ const {
39
+ getCopyWithPlaceholders
40
+ } = (0, _CarouselContext.useCarousel)(); // TODO: integrate skip link description if behaving as skip link.
41
+ // Consider moving this content to aria-live area while only the skip link is focused.
42
+
43
+ const accessibilityLabel = "".concat(title, ", ").concat(getCopyWithPlaceholders('stepTrackerLabel'));
44
+
45
+ const accessibilityRole = _Platform.default.select({
46
+ web: 'link',
47
+ // The focused item will ultimately be a skip link.
48
+ default: 'button' // 'link' role usually denotes opening browser on Native.
49
+
50
+ });
51
+
52
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Pressable.default // TODO: integrate skip link functionality, jump focus to after Carousel
53
+ , {
54
+ onPress: undefined,
55
+ ref: ref,
56
+ accessibilityLabel: accessibilityLabel,
57
+ accessibilityRole: accessibilityRole,
58
+ style: _StyleSheet.default.absoluteFill,
59
+ focusable: true
60
+ });
61
+ });
62
+ CarouselFirstFocus.displayName = 'CarouselFirstFocus';
63
+ CarouselFirstFocus.propTypes = {
64
+ /**
65
+ * Simple description of this carousel for screenreaders, to be read before
66
+ * "{itemLabel} {index} of {count}.
67
+ *
68
+ * For example, "Summer offers" in "Summer offers, offer 1 of 3"
69
+ */
70
+ title: _propTypes.PropTypes.string
71
+ };
72
+ var _default = CarouselFirstFocus;
73
+ exports.default = _default;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = _interopRequireWildcard(require("react"));
9
+
10
+ var _propTypes = _interopRequireDefault(require("prop-types"));
11
+
12
+ var _utils = require("../../utils");
13
+
14
+ var _Carousel = _interopRequireDefault(require("../Carousel"));
15
+
16
+ var _CarouselTabsPanel = _interopRequireDefault(require("./CarouselTabsPanel"));
17
+
18
+ var _jsxRuntime = require("react/jsx-runtime");
19
+
20
+ var _CarouselTabs$propTyp, _CarouselTabs$propTyp2;
21
+
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
+
24
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
+
26
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
27
+
28
+ const CarouselTabs = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
29
+ let {
30
+ items,
31
+ refocus = true,
32
+ ...carouselProps
33
+ } = _ref;
34
+ const panelNavigation = (0, _utils.useResponsiveProp)({
35
+ md: /*#__PURE__*/(0, _jsxRuntime.jsx)(_CarouselTabsPanel.default, {
36
+ items: items
37
+ })
38
+ });
39
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Carousel.default, {
40
+ refocus: refocus,
41
+ ...carouselProps,
42
+ ref: ref,
43
+ panelNavigation: panelNavigation,
44
+ children: items.map(_ref2 => {
45
+ let {
46
+ title,
47
+ content
48
+ } = _ref2;
49
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.default.Fragment, {
50
+ children: content
51
+ }, title);
52
+ })
53
+ });
54
+ });
55
+ CarouselTabs.displayName = 'CarouselTabs';
56
+ CarouselTabs.propTypes = {
57
+ /**
58
+ * An array of objects where title is the string shown in the slide's tab and content is the JSX for the slide itself
59
+ */
60
+ items: _propTypes.default.arrayOf(_propTypes.default.shape({
61
+ title: _propTypes.default.string.isRequired,
62
+ content: _propTypes.default.node.isRequired
63
+ })),
64
+ ..._Carousel.default.propTypes
65
+ }; // CarouselTabs doesn't require `children` prop, it uses `items` instead.
66
+ // eslint-disable-next-line react/forbid-foreign-prop-types
67
+
68
+ if ((_CarouselTabs$propTyp = CarouselTabs.propTypes) !== null && _CarouselTabs$propTyp !== void 0 && _CarouselTabs$propTyp.children) (_CarouselTabs$propTyp2 = CarouselTabs.propTypes) === null || _CarouselTabs$propTyp2 === void 0 ? true : delete _CarouselTabs$propTyp2.children;
69
+ var _default = CarouselTabs;
70
+ exports.default = _default;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = _interopRequireWildcard(require("react"));
9
+
10
+ var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
11
+
12
+ var _propTypes = _interopRequireDefault(require("prop-types"));
13
+
14
+ var _StackView = _interopRequireDefault(require("../../StackView"));
15
+
16
+ var _CarouselContext = require("../CarouselContext");
17
+
18
+ var _CarouselTabsPanelItem = _interopRequireDefault(require("./CarouselTabsPanelItem"));
19
+
20
+ var _jsxRuntime = require("react/jsx-runtime");
21
+
22
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
23
+
24
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
25
+
26
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
27
+
28
+ const CarouselTabsPanel = /*#__PURE__*/(0, _react.forwardRef)((_ref, ref) => {
29
+ let {
30
+ items
31
+ } = _ref;
32
+ const {
33
+ activeIndex,
34
+ goTo
35
+ } = (0, _CarouselContext.useCarousel)();
36
+ const nextFocusRef = (0, _react.useRef)();
37
+ const firstTabRef = (0, _react.useRef)(); // TODO: figure out a better cross-brand way to specify subcomponent variants.
38
+ // For now, this picks an Allium variant, and does nothing in brands that lack it.
39
+ // See similar comment in Carousel and https://github.com/telus/universal-design-system/issues/1549
40
+
41
+ const dividerVariant = {
42
+ decorative: true
43
+ };
44
+ const lastTabSelected = activeIndex === items.length - 1;
45
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
46
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
47
+ focusable: true,
48
+ accessible: true,
49
+ onFocus: event => {
50
+ // When user forward-tabs into this section, focus the next tab; if they backwards-tab
51
+ // (shift-tab) back into the carousel content, don't interfere.
52
+ const previousWebFocus = event.relatedTarget;
53
+ if (previousWebFocus !== firstTabRef.current) nextFocusRef.current.focus();
54
+ }
55
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.default, {
56
+ direction: "row",
57
+ space: 3,
58
+ divider: {
59
+ variant: dividerVariant
60
+ },
61
+ ref: ref,
62
+ children: items.map((_ref2, index) => {
63
+ let {
64
+ title,
65
+ onPress,
66
+ ...panelItemProps
67
+ } = _ref2;
68
+ const selected = index === activeIndex;
69
+ const isNext = index === activeIndex + 1; // Selected item should be always unfocusable and unpressable
70
+
71
+ const handlePress = selected ? undefined : event => {
72
+ if (typeof onPress === 'function') onPress(event, index);
73
+ goTo(index);
74
+ };
75
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_CarouselTabsPanelItem.default, {
76
+ ref: isNext && nextFocusRef || index === 0 && firstTabRef || null,
77
+ title: title,
78
+ selected: selected,
79
+ onPress: handlePress,
80
+ ...panelItemProps
81
+ }, title);
82
+ })
83
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
84
+ focusable: true,
85
+ accessible: true,
86
+ ref: lastTabSelected ? nextFocusRef : null
87
+ })]
88
+ });
89
+ });
90
+ CarouselTabsPanel.displayName = 'CarouselTabsPanel';
91
+ CarouselTabsPanel.propTypes = {
92
+ items: _propTypes.default.arrayOf(_propTypes.default.shape(_CarouselTabsPanelItem.default.propTypes || {}))
93
+ };
94
+ var _default = CarouselTabsPanel;
95
+ exports.default = _default;