@telus-uds/components-base 1.12.1 → 1.13.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 (69) hide show
  1. package/CHANGELOG.md +20 -2
  2. package/component-docs.json +740 -33
  3. package/lib/Button/ButtonGroup.js +7 -0
  4. package/lib/Carousel/Carousel.js +69 -12
  5. package/lib/Carousel/CarouselContext.js +17 -11
  6. package/lib/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +73 -0
  7. package/lib/Carousel/CarouselTabs/CarouselTabs.js +70 -0
  8. package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +95 -0
  9. package/lib/Carousel/CarouselTabs/CarouselTabsPanelItem.js +148 -0
  10. package/lib/Carousel/CarouselTabs/index.js +13 -0
  11. package/lib/Carousel/CarouselThumbnail.js +99 -0
  12. package/lib/Carousel/CarouselThumbnailNavigation.js +87 -0
  13. package/lib/Carousel/dictionary.js +4 -2
  14. package/lib/Carousel/index.js +10 -1
  15. package/lib/Checkbox/CheckboxGroup.js +7 -0
  16. package/lib/Link/InlinePressable.js +1 -8
  17. package/lib/Link/LinkBase.js +5 -6
  18. package/lib/Radio/RadioGroup.js +8 -0
  19. package/lib/RadioCard/RadioCardGroup.js +7 -0
  20. package/lib/SkipLink/SkipLink.js +216 -0
  21. package/lib/SkipLink/index.js +13 -0
  22. package/lib/ThemeProvider/ThemeProvider.js +6 -1
  23. package/lib/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  24. package/lib/index.js +9 -0
  25. package/lib-module/Button/ButtonGroup.js +7 -0
  26. package/lib-module/Carousel/Carousel.js +66 -11
  27. package/lib-module/Carousel/CarouselContext.js +17 -11
  28. package/lib-module/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +51 -0
  29. package/lib-module/Carousel/CarouselTabs/CarouselTabs.js +50 -0
  30. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +76 -0
  31. package/lib-module/Carousel/CarouselTabs/CarouselTabsPanelItem.js +126 -0
  32. package/lib-module/Carousel/CarouselTabs/index.js +2 -0
  33. package/lib-module/Carousel/CarouselThumbnail.js +85 -0
  34. package/lib-module/Carousel/CarouselThumbnailNavigation.js +66 -0
  35. package/lib-module/Carousel/dictionary.js +4 -2
  36. package/lib-module/Carousel/index.js +2 -1
  37. package/lib-module/Checkbox/CheckboxGroup.js +7 -0
  38. package/lib-module/Link/InlinePressable.js +1 -8
  39. package/lib-module/Link/LinkBase.js +5 -6
  40. package/lib-module/Radio/RadioGroup.js +8 -0
  41. package/lib-module/RadioCard/RadioCardGroup.js +7 -0
  42. package/lib-module/SkipLink/SkipLink.js +188 -0
  43. package/lib-module/SkipLink/index.js +2 -0
  44. package/lib-module/ThemeProvider/ThemeProvider.js +5 -1
  45. package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +7 -0
  46. package/lib-module/index.js +1 -0
  47. package/package.json +46 -47
  48. package/src/Button/ButtonGroup.jsx +6 -0
  49. package/src/Carousel/Carousel.jsx +68 -10
  50. package/src/Carousel/CarouselContext.jsx +22 -9
  51. package/src/Carousel/CarouselFirstFocus/CarouselFirstFocus.jsx +49 -0
  52. package/src/Carousel/CarouselTabs/CarouselTabs.jsx +37 -0
  53. package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +69 -0
  54. package/src/Carousel/CarouselTabs/CarouselTabsPanelItem.jsx +119 -0
  55. package/src/Carousel/CarouselTabs/index.js +3 -0
  56. package/src/Carousel/CarouselThumbnail.jsx +77 -0
  57. package/src/Carousel/CarouselThumbnailNavigation.jsx +53 -0
  58. package/src/Carousel/dictionary.js +4 -2
  59. package/src/Carousel/index.js +1 -0
  60. package/src/Checkbox/CheckboxGroup.jsx +7 -0
  61. package/src/Link/InlinePressable.jsx +2 -8
  62. package/src/Link/LinkBase.jsx +7 -16
  63. package/src/Radio/RadioGroup.jsx +7 -0
  64. package/src/RadioCard/RadioCardGroup.jsx +6 -0
  65. package/src/SkipLink/SkipLink.jsx +179 -0
  66. package/src/SkipLink/index.js +3 -0
  67. package/src/ThemeProvider/ThemeProvider.jsx +7 -1
  68. package/src/ToggleSwitch/ToggleSwitchGroup.jsx +6 -0
  69. package/src/index.js +1 -0
@@ -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
  */
@@ -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;
@@ -0,0 +1,148 @@
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 _Pressable = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Pressable"));
13
+
14
+ var _Text = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Text"));
15
+
16
+ var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
17
+
18
+ var _ThemeProvider = require("../../ThemeProvider");
19
+
20
+ var _utils = require("../../utils");
21
+
22
+ var _jsxRuntime = require("react/jsx-runtime");
23
+
24
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
25
+
26
+ 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); }
27
+
28
+ 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; }
29
+
30
+ const [selectPressProps, pressPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.pressProps, _utils.viewProps]);
31
+ const [selectTextProps, textPropTypes] = (0, _utils.selectSystemProps)([_utils.textProps]);
32
+
33
+ const selectContainerStyles = _ref => {
34
+ let {
35
+ paddingLeft,
36
+ paddingRight,
37
+ paddingTop,
38
+ paddingBottom = 0,
39
+ borderBottomColor,
40
+ borderBottomWidth = 0,
41
+ borderBottomStyle,
42
+ flex,
43
+ alignItems,
44
+ justifyContent
45
+ } = _ref;
46
+ return {
47
+ paddingLeft,
48
+ paddingRight,
49
+ paddingTop,
50
+ paddingBottom: paddingBottom - borderBottomWidth,
51
+ borderBottomColor,
52
+ borderBottomWidth,
53
+ borderBottomStyle,
54
+ flex,
55
+ alignItems,
56
+ justifyContent,
57
+ ..._Platform.default.select({
58
+ // Removes the default browser :focus outline
59
+ web: {
60
+ outline: 'none'
61
+ }
62
+ })
63
+ };
64
+ };
65
+
66
+ const selectTextStyles = _ref2 => {
67
+ let {
68
+ fontSize,
69
+ fontScaleCap,
70
+ lineHeight,
71
+ letterSpacing,
72
+ fontWeight,
73
+ fontName,
74
+ color
75
+ } = _ref2;
76
+ return (0, _ThemeProvider.applyTextStyles)({
77
+ fontSize,
78
+ fontScaleCap,
79
+ lineHeight,
80
+ letterSpacing,
81
+ fontWeight,
82
+ fontName,
83
+ color
84
+ });
85
+ };
86
+
87
+ const CarouselTabsPanelItem = /*#__PURE__*/(0, _react.forwardRef)((_ref3, ref) => {
88
+ let {
89
+ title,
90
+ selected,
91
+ inactive,
92
+ variant,
93
+ tokens,
94
+ accessibilityRole = 'tab',
95
+ ...rest
96
+ } = _ref3;
97
+ // Workaround for React Native Web https://github.com/necolas/react-native-web/issues/2357
98
+ // Don't allow disabled to be set while focus is true else focus state gets locked `true`
99
+ // (must refocus _after_ calling `goTo`, else focus target content is not up to date)
100
+ const [isFocused, setIsFocused] = (0, _react.useState)(false);
101
+ const disabled = (inactive || selected) && !isFocused;
102
+ const getTokens = (0, _ThemeProvider.useThemeTokensCallback)('CarouselTabsPanelItem', tokens, variant);
103
+
104
+ const resolveTokens = pressState => getTokens((0, _utils.resolvePressableState)(pressState, {
105
+ selected
106
+ }));
107
+
108
+ const getContainerStyle = pressState => selectContainerStyles(resolveTokens(pressState));
109
+
110
+ const getTextStyle = pressState => selectTextStyles(resolveTokens(pressState));
111
+
112
+ const {
113
+ onPress,
114
+ ...selectedPressProps
115
+ } = selectPressProps(rest);
116
+
117
+ const handleKeyDown = event => {
118
+ // Allow using the spacebar for navigation
119
+ if ((event === null || event === void 0 ? void 0 : event.key) === ' ') onPress(event);
120
+ };
121
+
122
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Pressable.default, {
123
+ onPress: onPress,
124
+ style: getContainerStyle,
125
+ accessibilityRole: accessibilityRole,
126
+ ref: ref,
127
+ onKeyDown: handleKeyDown,
128
+ onFocus: () => setIsFocused(true),
129
+ onBlur: () => setIsFocused(false),
130
+ disabled: disabled,
131
+ ...selectedPressProps,
132
+ children: pressState => /*#__PURE__*/(0, _jsxRuntime.jsx)(_Text.default, {
133
+ style: getTextStyle(pressState),
134
+ ...selectTextProps(rest),
135
+ children: title
136
+ })
137
+ });
138
+ });
139
+ CarouselTabsPanelItem.displayName = 'CarouselTabsPanelItem';
140
+ CarouselTabsPanelItem.propTypes = { ...pressPropTypes,
141
+ ...textPropTypes,
142
+ title: _propTypes.default.string.isRequired,
143
+ selected: _propTypes.default.bool,
144
+ tokens: (0, _utils.getTokensPropType)('CarouselTabsPanelItem'),
145
+ variant: _utils.variantProp.propType
146
+ };
147
+ var _default = CarouselTabsPanelItem;
148
+ exports.default = _default;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _CarouselTabs = _interopRequireDefault(require("./CarouselTabs"));
9
+
10
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
+
12
+ var _default = _CarouselTabs.default;
13
+ exports.default = _default;