@telus-uds/components-base 1.8.4 → 1.10.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 (51) hide show
  1. package/CHANGELOG.md +38 -2
  2. package/component-docs.json +344 -0
  3. package/lib/Card/Card.js +9 -4
  4. package/lib/Carousel/Carousel.js +619 -0
  5. package/lib/Carousel/CarouselContext.js +59 -0
  6. package/lib/Carousel/CarouselItem/CarouselItem.js +77 -0
  7. package/lib/Carousel/CarouselItem/index.js +13 -0
  8. package/lib/Carousel/index.js +32 -0
  9. package/lib/Checkbox/Checkbox.js +4 -2
  10. package/lib/ExpandCollapse/Panel.js +10 -1
  11. package/lib/Link/InlinePressable.js +5 -1
  12. package/lib/Link/LinkBase.js +5 -2
  13. package/lib/StepTracker/StepTracker.js +5 -2
  14. package/lib/TextInput/TextInput.js +0 -11
  15. package/lib/TextInput/TextInputBase.js +9 -0
  16. package/lib/TextInput/propTypes.js +3 -8
  17. package/lib/index.js +14 -0
  18. package/lib/utils/props/textInputProps.js +8 -1
  19. package/lib-module/Card/Card.js +5 -4
  20. package/lib-module/Carousel/Carousel.js +570 -0
  21. package/lib-module/Carousel/CarouselContext.js +43 -0
  22. package/lib-module/Carousel/CarouselItem/CarouselItem.js +60 -0
  23. package/lib-module/Carousel/CarouselItem/index.js +2 -0
  24. package/lib-module/Carousel/index.js +2 -0
  25. package/lib-module/Checkbox/Checkbox.js +4 -2
  26. package/lib-module/ExpandCollapse/Panel.js +9 -1
  27. package/lib-module/Link/InlinePressable.js +5 -1
  28. package/lib-module/Link/LinkBase.js +5 -2
  29. package/lib-module/StepTracker/StepTracker.js +5 -2
  30. package/lib-module/TextInput/TextInput.js +0 -8
  31. package/lib-module/TextInput/TextInputBase.js +10 -1
  32. package/lib-module/TextInput/propTypes.js +4 -8
  33. package/lib-module/index.js +1 -0
  34. package/lib-module/utils/props/textInputProps.js +8 -1
  35. package/package.json +3 -3
  36. package/src/Card/Card.jsx +6 -4
  37. package/src/Carousel/Carousel.jsx +586 -0
  38. package/src/Carousel/CarouselContext.jsx +30 -0
  39. package/src/Carousel/CarouselItem/CarouselItem.jsx +48 -0
  40. package/src/Carousel/CarouselItem/index.js +3 -0
  41. package/src/Carousel/index.js +2 -0
  42. package/src/Checkbox/Checkbox.jsx +3 -1
  43. package/src/ExpandCollapse/Panel.jsx +8 -1
  44. package/src/Link/InlinePressable.jsx +5 -2
  45. package/src/Link/LinkBase.jsx +4 -1
  46. package/src/StepTracker/StepTracker.jsx +12 -5
  47. package/src/TextInput/TextInput.jsx +1 -8
  48. package/src/TextInput/TextInputBase.jsx +11 -1
  49. package/src/TextInput/propTypes.js +3 -7
  50. package/src/index.js +1 -0
  51. package/src/utils/props/textInputProps.js +7 -1
@@ -0,0 +1,619 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = _interopRequireDefault(require("react"));
9
+
10
+ var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
11
+
12
+ var _Animated = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Animated"));
13
+
14
+ var _PanResponder = _interopRequireDefault(require("react-native-web/dist/cjs/exports/PanResponder"));
15
+
16
+ var _StyleSheet = _interopRequireDefault(require("react-native-web/dist/cjs/exports/StyleSheet"));
17
+
18
+ var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
19
+
20
+ var _propTypes = _interopRequireDefault(require("prop-types"));
21
+
22
+ var _ThemeProvider = require("../ThemeProvider");
23
+
24
+ var _ViewportProvider = require("../ViewportProvider");
25
+
26
+ var _utils = require("../utils");
27
+
28
+ var _A11yInfoProvider = require("../A11yInfoProvider");
29
+
30
+ var _CarouselContext = require("./CarouselContext");
31
+
32
+ var _CarouselItem = _interopRequireDefault(require("./CarouselItem"));
33
+
34
+ var _StepTracker = _interopRequireDefault(require("../StepTracker"));
35
+
36
+ var _StackView = _interopRequireDefault(require("../StackView"));
37
+
38
+ var _IconButton = _interopRequireDefault(require("../IconButton"));
39
+
40
+ var _jsxRuntime = require("react/jsx-runtime");
41
+
42
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
43
+
44
+ const staticStyles = _StyleSheet.default.create({
45
+ root: {
46
+ backgroundColor: 'transparent',
47
+ justifyContent: 'center',
48
+ alignItems: 'center',
49
+ position: 'relative',
50
+ top: 0,
51
+ left: 0
52
+ }
53
+ });
54
+
55
+ const staticTokens = {
56
+ stackView: {
57
+ justifyContent: 'center'
58
+ },
59
+ stepTracker: {
60
+ showStepLabel: false,
61
+ showStepTrackerLabel: true,
62
+ knobCompletedBackgroundColor: 'none',
63
+ connectorCompletedColor: 'none',
64
+ connectorColor: 'none'
65
+ }
66
+ };
67
+
68
+ const selectContainerStyles = width => ({
69
+ backgroundColor: 'transparent',
70
+ overflow: 'hidden',
71
+ width
72
+ });
73
+
74
+ const selectSwipeAreaStyles = (count, width) => ({
75
+ width: width * count,
76
+ justifyContent: 'space-between',
77
+ flexDirection: 'row'
78
+ });
79
+
80
+ const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, areStylesAppliedOnPreviousButton) => {
81
+ const styles = {
82
+ zIndex: 1,
83
+ position: 'absolute'
84
+ };
85
+ const dynamicPositionProperty = areStylesAppliedOnPreviousButton ? 'left' : 'right';
86
+
87
+ if (isFirstSlide) {
88
+ styles.visibility = areStylesAppliedOnPreviousButton ? 'hidden' : 'visible';
89
+ } else if (isLastSlide) {
90
+ styles.visibility = areStylesAppliedOnPreviousButton ? 'visible' : 'hidden';
91
+ } else {
92
+ styles.visibility = 'visible';
93
+ }
94
+
95
+ if (previousNextNavigationPosition === 'edge') {
96
+ styles[dynamicPositionProperty] = -1 * (previousNextNavigationButtonWidth / 2);
97
+ } else if (previousNextNavigationPosition === 'inside') {
98
+ styles[dynamicPositionProperty] = 0;
99
+ } else if (previousNextNavigationPosition === 'outside') {
100
+ styles[dynamicPositionProperty] = -1 * (spaceBetweenSlideAndPreviousNextNavigation + previousNextNavigationButtonWidth);
101
+ }
102
+
103
+ return styles;
104
+ };
105
+
106
+ const defaultPanelNavigationDictionary = {
107
+ en: {
108
+ stepTrackerLabel: 'Showing %{stepNumber} of %{stepCount}'
109
+ },
110
+ fr: {
111
+ stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
112
+ }
113
+ };
114
+ const [selectProps, selectedSystemPropTypes] = (0, _utils.selectSystemProps)([_utils.a11yProps, _utils.viewProps]);
115
+ /**
116
+ * Carousel is a general-purpose content slider that can be used to render content in terms of slides.
117
+
118
+ ## Usage
119
+ - `Carousel` is a top-level export from `@telus-uds/components-base` which is used to render a Carousel
120
+ - Immediately within `Carousel`, individual slides are wrapped in `Carousel.Item` for the top-level `Carousel` to know how to identify an individual slide
121
+ - You can use any UDS component or other platform-specific component, (based on the platform you're rendering) to achieve any desired layout
122
+ - By default, Carousel takea all the `width` available to it and the `height` is determined based on the content in the slide with more content
123
+ - You may want to wrap Carousel in other layout components like `Box`, `FlexGrid` etc, to achieve a responsive layout of your need
124
+
125
+ ## `useCarousel` custom hook
126
+
127
+ ```jsx
128
+ import { useCarousel } from '@telus-uds/components-base'
129
+
130
+ const SomeComponentWithinCarouselItem = () => {
131
+ const {
132
+ activeIndex,
133
+ totalItems,
134
+ width,
135
+ goTo
136
+ } = useCarousel()
137
+ return <Text>Hi!</Text>
138
+ }
139
+ ```
140
+
141
+ You can use `useCarousel` to hook into internal state of the Carousel component like:
142
+ - `activeIndex`: Index of the current slide
143
+ - `totalItems`: Total number of items/slides passed to the Carousel
144
+ - `width`: Width of the individual carousel slide
145
+ - `goTo`: A function to go to a particular slide by passing the index of that slide, e.g: goTo(0) where `0` is the index of the first slide
146
+
147
+ ## Accessibility
148
+
149
+ - Top-level `Carousel` and `Carousel.Item` can take all possible React Native's `View` and `a11y` props
150
+ - If your slide contains input elements like buttons, you may want to configure them to be only focusable when `activeIndex` is equal to the current slide index in order to avoid tabbing going between slides
151
+
152
+ ## Platform considerations
153
+ The component is available on both native platforms and web.
154
+
155
+ ## Other considerations
156
+ - You may want to use the same kind of layout in all your slides to avoid visual and height differences
157
+ - `previous` and `next` navigation buttons are automatically removed in `sm` and `xs` viewports, as these smaller viewports offers swipe functionality
158
+
159
+ ## Tokens
160
+
161
+ You can override the following tokens in exceptional circumstances:
162
+ - `previousIcon` - Icon of the previous button
163
+ - `nextIcon` - Icon of the next button
164
+ - `showPreviousNextNavigation` - If you want to show/hide the previous/next navigation
165
+ - `showPanelNavigation` - If you want to show/hide the panel navigation
166
+ - `spaceBetweenSlideAndPreviousNextNavigation` - Horizontal space between slide and previous/next navigational buttons
167
+ - `spaceBetweenSlideAndPanelNavigation` - Vertical space between slide area and panel navigation area
168
+ */
169
+
170
+ const Carousel = /*#__PURE__*/_react.default.forwardRef((_ref, ref) => {
171
+ let {
172
+ tokens,
173
+ variant,
174
+ children,
175
+ previousNextNavigationPosition = 'inside',
176
+ previousNextIconSize = 'default',
177
+ minDistanceToCapture = 5,
178
+ minDistanceForAction = 0.2,
179
+ onAnimationStart,
180
+ onAnimationEnd,
181
+ onIndexChanged,
182
+ springConfig = undefined,
183
+ onRenderPanelNavigation,
184
+ panelNavigationTextDictionary = defaultPanelNavigationDictionary,
185
+ accessibilityRole = 'adjustable',
186
+ accessibilityLabel = 'carousel',
187
+ ...rest
188
+ } = _ref;
189
+ const viewport = (0, _ViewportProvider.useViewport)();
190
+ const {
191
+ previousIcon,
192
+ nextIcon,
193
+ showPreviousNextNavigation,
194
+ showPanelNavigation,
195
+ spaceBetweenSlideAndPreviousNextNavigation,
196
+ spaceBetweenSlideAndPanelNavigation
197
+ } = (0, _ThemeProvider.useThemeTokens)('Carousel', tokens, variant, {
198
+ viewport
199
+ });
200
+
201
+ const [activeIndex, setActiveIndex] = _react.default.useState(0);
202
+
203
+ const childrenArray = _react.default.Children.toArray(children);
204
+
205
+ const systemProps = selectProps({ ...rest,
206
+ accessibilityRole,
207
+ accessibilityLabel,
208
+ accessibilityValue: {
209
+ min: 1,
210
+ max: childrenArray.length,
211
+ now: activeIndex + 1
212
+ }
213
+ });
214
+ const {
215
+ reduceMotionEnabled
216
+ } = (0, _A11yInfoProvider.useA11yInfo)();
217
+
218
+ const [containerLayout, setContainerLayout] = _react.default.useState({
219
+ x: 0,
220
+ y: 0,
221
+ width: 0
222
+ });
223
+
224
+ const [previousNextNavigationButtonWidth, setPreviousNextNavigationButtonWidth] = _react.default.useState(0);
225
+
226
+ const pan = _react.default.useRef(new _Animated.default.ValueXY()).current;
227
+
228
+ const animatedX = _react.default.useRef(0);
229
+
230
+ const animatedY = _react.default.useRef(0);
231
+
232
+ const isFirstSlide = !activeIndex;
233
+ const isLastSlide = activeIndex + 1 >= children.length;
234
+ const panelNavigationTokens = { ...staticTokens.stepTracker,
235
+ containerPaddingTop: spaceBetweenSlideAndPanelNavigation
236
+ };
237
+
238
+ const onContainerLayout = _ref2 => {
239
+ let {
240
+ nativeEvent: {
241
+ layout: {
242
+ x,
243
+ y,
244
+ width
245
+ }
246
+ }
247
+ } = _ref2;
248
+ return setContainerLayout(prevState => ({ ...prevState,
249
+ x,
250
+ y,
251
+ width
252
+ }));
253
+ };
254
+
255
+ const onPreviousNextNavigationButtonLayout = _ref3 => {
256
+ let {
257
+ nativeEvent: {
258
+ layout: {
259
+ width
260
+ }
261
+ }
262
+ } = _ref3;
263
+ return setPreviousNextNavigationButtonWidth(width);
264
+ };
265
+
266
+ const updateOffset = _react.default.useCallback(() => {
267
+ animatedX.current = containerLayout.width * activeIndex * -1;
268
+ animatedY.current = 0;
269
+ pan.setOffset({
270
+ x: animatedX.current,
271
+ y: animatedY.current
272
+ });
273
+ pan.setValue({
274
+ x: 0,
275
+ y: 0
276
+ });
277
+ }, [activeIndex, containerLayout.width, pan, animatedX]);
278
+
279
+ const animate = _react.default.useCallback(toValue => {
280
+ if (reduceMotionEnabled) {
281
+ _Animated.default.timing(pan, {
282
+ toValue,
283
+ duration: 1,
284
+ useNativeDriver: false
285
+ }).start();
286
+ } else {
287
+ _Animated.default.spring(pan, { ...springConfig,
288
+ toValue,
289
+ useNativeDriver: false
290
+ }).start();
291
+ }
292
+ }, [pan, springConfig, reduceMotionEnabled]);
293
+
294
+ const updateIndex = _react.default.useCallback(function () {
295
+ let delta = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
296
+ const toValue = {
297
+ x: 0,
298
+ y: 0
299
+ };
300
+ let skipChanges = !delta;
301
+ let calcDelta = delta;
302
+
303
+ if (activeIndex <= 0 && delta < 0) {
304
+ skipChanges = true;
305
+ calcDelta = children.length + delta;
306
+ } else if (activeIndex + 1 >= children.length && delta > 0) {
307
+ skipChanges = true;
308
+ calcDelta = -1 * activeIndex + delta - 1;
309
+ }
310
+
311
+ if (skipChanges) {
312
+ animate(toValue);
313
+ return calcDelta;
314
+ }
315
+
316
+ const index = activeIndex + calcDelta;
317
+ setActiveIndex(index);
318
+ toValue.x = containerLayout.width * -1 * calcDelta;
319
+ animate(toValue);
320
+ if (onIndexChanged) onIndexChanged(calcDelta);
321
+ if (onAnimationEnd) onAnimationEnd(index);
322
+ return calcDelta;
323
+ }, [containerLayout.width, activeIndex, animate, children.length, onIndexChanged, onAnimationEnd]);
324
+
325
+ const fixOffsetAndGo = _react.default.useCallback(delta => {
326
+ updateOffset();
327
+ if (onAnimationStart) onAnimationStart(activeIndex);
328
+ updateIndex(delta);
329
+ }, [updateIndex, updateOffset, activeIndex, onAnimationStart]);
330
+
331
+ const goToNeighboring = _react.default.useCallback(function () {
332
+ let toPrev = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
333
+ fixOffsetAndGo(toPrev ? -1 : 1);
334
+ }, [fixOffsetAndGo]);
335
+
336
+ const isSwipeAllowed = _react.default.useCallback(() => {
337
+ if (_Platform.default.OS === 'web') {
338
+ return !!(viewport === 'xs' || viewport === 'sm');
339
+ }
340
+
341
+ return true;
342
+ }, [viewport]);
343
+
344
+ const panResponder = _react.default.useMemo(() => _PanResponder.default.create({
345
+ onPanResponderTerminationRequest: () => false,
346
+ onMoveShouldSetResponderCapture: () => true,
347
+ onMoveShouldSetPanResponderCapture: (_, gestureState) => {
348
+ if (!isSwipeAllowed()) {
349
+ return false;
350
+ }
351
+
352
+ if (onAnimationStart) onAnimationStart(activeIndex);
353
+ return Math.abs(gestureState.dx) > minDistanceToCapture;
354
+ },
355
+ onPanResponderGrant: () => updateOffset(),
356
+ onPanResponderMove: _Animated.default.event([null, {
357
+ dx: pan.x
358
+ }], {
359
+ useNativeDriver: false
360
+ }),
361
+ onPanResponderRelease: (_, gesture) => {
362
+ const correction = gesture.moveX - gesture.x0;
363
+
364
+ if (Math.abs(correction) < containerLayout.width * minDistanceForAction) {
365
+ animate({
366
+ x: 0,
367
+ y: 0
368
+ });
369
+ } else {
370
+ const delta = correction > 0 ? -1 : 1;
371
+ updateIndex(delta);
372
+ }
373
+ }
374
+ }), [containerLayout.width, updateIndex, updateOffset, animate, isSwipeAllowed, activeIndex, minDistanceForAction, onAnimationStart, minDistanceToCapture, pan.x]);
375
+
376
+ _react.default.useEffect(() => {
377
+ pan.x.addListener(_ref4 => {
378
+ let {
379
+ value
380
+ } = _ref4;
381
+ animatedX.current = value;
382
+ });
383
+ pan.y.addListener(_ref5 => {
384
+ let {
385
+ value
386
+ } = _ref5;
387
+ animatedY.current = value;
388
+ });
389
+ return () => {
390
+ pan.x.removeAllListeners();
391
+ pan.y.removeAllListeners();
392
+ };
393
+ }, [pan.x, pan.y]);
394
+
395
+ const goToNext = _react.default.useCallback(() => {
396
+ goToNeighboring();
397
+ }, [goToNeighboring]);
398
+
399
+ const goToPrev = _react.default.useCallback(() => {
400
+ goToNeighboring(true);
401
+ }, [goToNeighboring]);
402
+
403
+ const goTo = _react.default.useCallback(function () {
404
+ let index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
405
+ const delta = index - activeIndex;
406
+
407
+ if (delta) {
408
+ fixOffsetAndGo(delta);
409
+ }
410
+ }, [fixOffsetAndGo, activeIndex]); // @TODO: - these are Allium-theme variants and won't have any effect in themes that don't implement them.
411
+ // Normally we avoid setting variants of subcomponents, however this could be re-considered.
412
+ // Related discussion - https://github.com/telus/universal-design-system/issues/1549
413
+
414
+
415
+ const previousNextIconButtonVariants = {
416
+ size: previousNextIconSize,
417
+ raised: true
418
+ };
419
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_CarouselContext.CarouselProvider, {
420
+ activeIndex: activeIndex,
421
+ totalItems: childrenArray.length,
422
+ width: containerLayout.width,
423
+ goTo: goTo,
424
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_View.default, {
425
+ style: staticStyles.root,
426
+ onLayout: onContainerLayout,
427
+ ref: ref,
428
+ ...systemProps,
429
+ children: [showPreviousNextNavigation && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
430
+ style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, true),
431
+ testID: "previous-button-container",
432
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
433
+ onLayout: onPreviousNextNavigationButtonLayout,
434
+ icon: previousIcon,
435
+ onPress: goToPrev,
436
+ variant: previousNextIconButtonVariants,
437
+ accessibilityLabel: "previous-button"
438
+ })
439
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
440
+ style: selectContainerStyles(containerLayout.width),
441
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Animated.default.View, {
442
+ style: _StyleSheet.default.flatten([selectSwipeAreaStyles(children.length, containerLayout.width), {
443
+ transform: [{
444
+ translateX: pan.x
445
+ }, {
446
+ translateY: pan.y
447
+ }]
448
+ }]),
449
+ ...panResponder.panHandlers,
450
+ children: childrenArray.map((element, index) => {
451
+ const clonedElement = /*#__PURE__*/_react.default.cloneElement(element, {
452
+ elementIndex: index
453
+ });
454
+
455
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_react.default.Fragment, {
456
+ children: clonedElement
457
+ }, index.toFixed(2));
458
+ })
459
+ })
460
+ }), showPreviousNextNavigation && /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
461
+ style: selectPreviousNextNavigationButtonStyles(previousNextNavigationButtonWidth, previousNextNavigationPosition, spaceBetweenSlideAndPreviousNextNavigation, isFirstSlide, isLastSlide, false),
462
+ testID: "next-button-container",
463
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
464
+ onLayout: onPreviousNextNavigationButtonLayout,
465
+ icon: nextIcon,
466
+ onPress: goToNext,
467
+ variant: previousNextIconButtonVariants,
468
+ accessibilityLabel: "next-button"
469
+ })
470
+ })]
471
+ }), showPanelNavigation ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_StackView.default, {
472
+ direction: "row",
473
+ tokens: staticTokens.stackView,
474
+ children: onRenderPanelNavigation ? onRenderPanelNavigation({
475
+ activeIndex,
476
+ totalItems: childrenArray.length
477
+ }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_StepTracker.default, {
478
+ current: activeIndex,
479
+ steps: childrenArray.map((_, index) => String(index)),
480
+ dictionary: panelNavigationTextDictionary,
481
+ tokens: panelNavigationTokens
482
+ })
483
+ }) : null]
484
+ });
485
+ });
486
+
487
+ Carousel.propTypes = { ...selectedSystemPropTypes,
488
+ tokens: (0, _utils.getTokensPropType)('Carousel'),
489
+ variant: _utils.variantProp.propType,
490
+
491
+ /**
492
+ * Slides to render in Carousel. Wrap individual slides in `Carousel.Item`
493
+ */
494
+ children: _propTypes.default.oneOfType([_propTypes.default.arrayOf(_propTypes.default.node), _propTypes.default.node]).isRequired,
495
+
496
+ /**
497
+ * `inside` renders the previous and next buttons inside the slide
498
+ * `outside` renders the previous and next buttons outside the slide
499
+ * `edge` renders the previous and next buttons at the edge of the slide
500
+ */
501
+ previousNextNavigationPosition: _propTypes.default.oneOf(['inside', 'outside', 'edge']),
502
+
503
+ /**
504
+ * Defines the size of the `IconButton` which is being used to render next and previous buttons
505
+ */
506
+ previousNextIconSize: _propTypes.default.oneOf(['default', 'small', 'large']),
507
+
508
+ /**
509
+ * Carousel uses `Animated.spring` to animate slide changes, use this option to pass custom animation configuration
510
+ */
511
+ springConfig: _propTypes.default.object,
512
+
513
+ /**
514
+ * Minimal part of slide width must be swiped for changing index.
515
+ * Otherwise animation restore current slide. Default value 0.2 means that 20% must be swiped for change index
516
+ */
517
+ minDistanceForAction: _propTypes.default.number,
518
+
519
+ /**
520
+ * Initiate animation after swipe this distance.
521
+ */
522
+ minDistanceToCapture: _propTypes.default.number,
523
+
524
+ /**
525
+ * Called when active index changed
526
+ * This function is also provided with a parameter indicating changed index (either 1, or -1)
527
+ * Use it as follows:
528
+ * ```js
529
+ * const onIndexChangedCallback = React.useCallback((changedIndex) => {
530
+ * console.log(changedIndex)
531
+ * }, []) // pass local dependencies as per your component
532
+ * <Carousel
533
+ * onIndexChanged={onIndexChangedCallback}
534
+ * >
535
+ * <Carousel.Item>First Slide</Carousel.Item>
536
+ * </Carousel>
537
+ * ```
538
+ * Caution: Always consider wrapping your callback for `onIndexChanged` in `useCallback` in order to avoid bugs and performance issues
539
+ */
540
+ onIndexChanged: _propTypes.default.func,
541
+
542
+ /**
543
+ * Use this to render a custom panel navigation element instead of dots navigation
544
+ * This function is also provided with an object with the following properties
545
+ * activeIndex: index of current slide
546
+ * totalItems: total number of slides
547
+ * Use it as follows:
548
+ * ```js
549
+ * <Carousel
550
+ * onRenderPanelNavigation={({ totalItems, activeIndex }) => <Text>Showing {activeIndex + 1}</Text>}
551
+ * >
552
+ * <Carousel.Item>First Slide</Carousel.Item>
553
+ * </Carousel>
554
+ * ```
555
+ */
556
+ onRenderPanelNavigation: _propTypes.default.func,
557
+
558
+ /**
559
+ * When slide animation start
560
+ * This function is also provided with a parameter indicating the current slide index before animation starts
561
+ * Use it as follows:
562
+ * ```js
563
+ * const onAnimationStartCallback = React.useCallback((currentIndex) => {
564
+ * console.log(currentIndex)
565
+ * }, []) // pass local dependencies as per your component
566
+ * <Carousel
567
+ * onAnimationStart={onAnimationStartCallback}
568
+ * >
569
+ * <Carousel.Item>First Slide</Carousel.Item>
570
+ * </Carousel>
571
+ * ```
572
+ * Caution: Always consider wrapping your callback for `onAnimationStart` in `useCallback` in order to avoid bugs and performance issues
573
+ */
574
+ onAnimationStart: _propTypes.default.func,
575
+
576
+ /**
577
+ * When slide animation end with parameter of current index (after animation ends)
578
+ * This function is also provided with a parameter indicating the updated slide index after animation ends
579
+ * Use it as follows:
580
+ * ```js
581
+ * const onAnimationEndCallback = React.useCallback((changedIndex) => {
582
+ * console.log(changedIndex)
583
+ * }, []) // pass local dependencies as per your component
584
+ * <Carousel
585
+ * onAnimationEnd={onAnimationEndCallback}
586
+ * >
587
+ * <Carousel.Item>First Slide</Carousel.Item>
588
+ * </Carousel>
589
+ * ```
590
+ * Caution: Always consider wrapping your callback for `onAnimationEnd` in `useCallback` in order to avoid bugs and performance issues
591
+ */
592
+ onAnimationEnd: _propTypes.default.func,
593
+
594
+ /**
595
+ * Use this to override the default text for panel navigation
596
+ */
597
+ panelNavigationTextDictionary: _propTypes.default.shape({
598
+ en: _propTypes.default.shape({
599
+ stepTrackerLabel: _propTypes.default.string.isRequired
600
+ }),
601
+ fr: _propTypes.default.shape({
602
+ stepTrackerLabel: _propTypes.default.string.isRequired
603
+ })
604
+ }),
605
+
606
+ /**
607
+ * Provide custom accessibilityRole for Carousel container
608
+ */
609
+ accessibilityRole: _propTypes.default.string,
610
+
611
+ /**
612
+ * Provide custom accessibilityLabel for Carousel container
613
+ */
614
+ accessibilityLabel: _propTypes.default.string
615
+ };
616
+ Carousel.Item = _CarouselItem.default;
617
+ Carousel.displayName = 'Carousel';
618
+ var _default = Carousel;
619
+ exports.default = _default;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.CarouselProvider = void 0;
7
+ exports.useCarousel = useCarousel;
8
+
9
+ var _react = _interopRequireDefault(require("react"));
10
+
11
+ var _propTypes = _interopRequireDefault(require("prop-types"));
12
+
13
+ var _jsxRuntime = require("react/jsx-runtime");
14
+
15
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16
+
17
+ const CarouselContext = /*#__PURE__*/_react.default.createContext();
18
+
19
+ const CarouselProvider = _ref => {
20
+ let {
21
+ children,
22
+ activeIndex,
23
+ totalItems,
24
+ width,
25
+ goTo
26
+ } = _ref;
27
+
28
+ const value = _react.default.useMemo(() => ({
29
+ activeIndex,
30
+ totalItems,
31
+ width,
32
+ goTo
33
+ }), [activeIndex, totalItems, width, goTo]);
34
+
35
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(CarouselContext.Provider, {
36
+ value: value,
37
+ children: children
38
+ });
39
+ };
40
+
41
+ exports.CarouselProvider = CarouselProvider;
42
+
43
+ function useCarousel() {
44
+ const context = _react.default.useContext(CarouselContext);
45
+
46
+ if (context === undefined) {
47
+ throw new Error("'useCarousel' must be used within a 'CarouselProvider'");
48
+ }
49
+
50
+ return context;
51
+ }
52
+
53
+ CarouselProvider.propTypes = {
54
+ children: _propTypes.default.arrayOf(_propTypes.default.element).isRequired,
55
+ activeIndex: _propTypes.default.number.isRequired,
56
+ totalItems: _propTypes.default.number.isRequired,
57
+ width: _propTypes.default.number.isRequired,
58
+ goTo: _propTypes.default.func.isRequired
59
+ };