@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.
- package/CHANGELOG.md +41 -2
- package/component-docs.json +888 -66
- package/lib/Button/ButtonBase.js +36 -7
- package/lib/Button/ButtonGroup.js +7 -0
- package/lib/Button/propTypes.js +18 -0
- package/lib/Carousel/Carousel.js +69 -12
- package/lib/Carousel/CarouselContext.js +17 -11
- package/lib/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +73 -0
- package/lib/Carousel/CarouselTabs/CarouselTabs.js +70 -0
- package/lib/Carousel/CarouselTabs/CarouselTabsPanel.js +95 -0
- package/lib/Carousel/CarouselTabs/CarouselTabsPanelItem.js +148 -0
- package/lib/Carousel/CarouselTabs/index.js +13 -0
- package/lib/Carousel/CarouselThumbnail.js +99 -0
- package/lib/Carousel/CarouselThumbnailNavigation.js +87 -0
- package/lib/Carousel/dictionary.js +4 -2
- package/lib/Carousel/index.js +10 -1
- package/lib/Checkbox/CheckboxGroup.js +7 -0
- package/lib/Icon/IconText.js +1 -1
- package/lib/Link/InlinePressable.js +1 -8
- package/lib/Link/LinkBase.js +6 -7
- package/lib/List/ListItem.js +1 -1
- package/lib/Notification/Notification.js +37 -22
- package/lib/Radio/RadioGroup.js +8 -0
- package/lib/RadioCard/RadioCardGroup.js +7 -0
- package/lib/SkipLink/SkipLink.js +216 -0
- package/lib/SkipLink/index.js +13 -0
- package/lib/ThemeProvider/ThemeProvider.js +6 -1
- package/lib/ToggleSwitch/ToggleSwitchGroup.js +7 -0
- package/lib/index.js +9 -0
- package/lib-module/Button/ButtonBase.js +35 -7
- package/lib-module/Button/ButtonGroup.js +7 -0
- package/lib-module/Button/propTypes.js +17 -0
- package/lib-module/Carousel/Carousel.js +66 -11
- package/lib-module/Carousel/CarouselContext.js +17 -11
- package/lib-module/Carousel/CarouselFirstFocus/CarouselFirstFocus.js +51 -0
- package/lib-module/Carousel/CarouselTabs/CarouselTabs.js +50 -0
- package/lib-module/Carousel/CarouselTabs/CarouselTabsPanel.js +76 -0
- package/lib-module/Carousel/CarouselTabs/CarouselTabsPanelItem.js +126 -0
- package/lib-module/Carousel/CarouselTabs/index.js +2 -0
- package/lib-module/Carousel/CarouselThumbnail.js +85 -0
- package/lib-module/Carousel/CarouselThumbnailNavigation.js +66 -0
- package/lib-module/Carousel/dictionary.js +4 -2
- package/lib-module/Carousel/index.js +2 -1
- package/lib-module/Checkbox/CheckboxGroup.js +7 -0
- package/lib-module/Icon/IconText.js +1 -1
- package/lib-module/Link/InlinePressable.js +1 -8
- package/lib-module/Link/LinkBase.js +6 -7
- package/lib-module/List/ListItem.js +1 -1
- package/lib-module/Notification/Notification.js +38 -23
- package/lib-module/Radio/RadioGroup.js +8 -0
- package/lib-module/RadioCard/RadioCardGroup.js +7 -0
- package/lib-module/SkipLink/SkipLink.js +188 -0
- package/lib-module/SkipLink/index.js +2 -0
- package/lib-module/ThemeProvider/ThemeProvider.js +5 -1
- package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +7 -0
- package/lib-module/index.js +1 -0
- package/package.json +46 -47
- package/src/Button/ButtonBase.jsx +28 -9
- package/src/Button/ButtonGroup.jsx +6 -0
- package/src/Button/propTypes.js +14 -0
- package/src/Carousel/Carousel.jsx +68 -10
- package/src/Carousel/CarouselContext.jsx +22 -9
- package/src/Carousel/CarouselFirstFocus/CarouselFirstFocus.jsx +49 -0
- package/src/Carousel/CarouselTabs/CarouselTabs.jsx +37 -0
- package/src/Carousel/CarouselTabs/CarouselTabsPanel.jsx +69 -0
- package/src/Carousel/CarouselTabs/CarouselTabsPanelItem.jsx +119 -0
- package/src/Carousel/CarouselTabs/index.js +3 -0
- package/src/Carousel/CarouselThumbnail.jsx +77 -0
- package/src/Carousel/CarouselThumbnailNavigation.jsx +53 -0
- package/src/Carousel/dictionary.js +4 -2
- package/src/Carousel/index.js +1 -0
- package/src/Checkbox/CheckboxGroup.jsx +7 -0
- package/src/Icon/IconText.jsx +1 -1
- package/src/Link/InlinePressable.jsx +2 -8
- package/src/Link/LinkBase.jsx +8 -17
- package/src/List/ListItem.jsx +1 -1
- package/src/Notification/Notification.jsx +35 -20
- package/src/Radio/RadioGroup.jsx +7 -0
- package/src/RadioCard/RadioCardGroup.jsx +6 -0
- package/src/SkipLink/SkipLink.jsx +179 -0
- package/src/SkipLink/index.js +3 -0
- package/src/ThemeProvider/ThemeProvider.jsx +7 -1
- package/src/ToggleSwitch/ToggleSwitchGroup.jsx +6 -0
- package/src/index.js +1 -0
package/lib/Button/ButtonBase.js
CHANGED
|
@@ -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
|
|
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
|
-
} =
|
|
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];
|
|
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,
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
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
|
*/
|
package/lib/Button/propTypes.js
CHANGED
|
@@ -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;
|
package/lib/Carousel/Carousel.js
CHANGED
|
@@ -33,7 +33,13 @@ var _CarouselItem = _interopRequireDefault(require("./CarouselItem"));
|
|
|
33
33
|
|
|
34
34
|
var _IconButton = _interopRequireDefault(require("../IconButton"));
|
|
35
35
|
|
|
36
|
-
var
|
|
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
|
-
|
|
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
|
|
166
|
-
accessibilityLabel =
|
|
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
|
-
|
|
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
|
-
|
|
26
|
-
width,
|
|
24
|
+
children,
|
|
27
25
|
goTo,
|
|
28
26
|
getCopyWithPlaceholders,
|
|
29
|
-
|
|
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
|
-
|
|
39
|
-
|
|
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
|
-
|
|
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;
|