@telus-uds/components-base 1.10.0 → 1.11.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.
- package/CHANGELOG.md +21 -3
- package/component-docs.json +346 -51
- package/lib/Carousel/Carousel.js +81 -28
- package/lib/Carousel/CarouselItem/CarouselItem.js +24 -9
- package/lib/Carousel/dictionary.js +23 -0
- package/lib/InputSupports/InputSupports.js +10 -3
- package/lib/InputSupports/useInputSupports.js +3 -2
- package/lib/Modal/Modal.js +4 -0
- package/lib/Skeleton/Skeleton.js +1 -0
- package/lib/StepTracker/StepTracker.js +10 -10
- package/lib/TextInput/TextInput.js +3 -1
- package/lib/index.js +9 -0
- package/lib/utils/props/clickProps.js +2 -2
- package/lib/utils/props/handlerProps.js +77 -31
- package/lib/utils/useScrollBlocking.js +66 -0
- package/lib/utils/useScrollBlocking.native.js +11 -0
- package/lib-module/Carousel/Carousel.js +76 -29
- package/lib-module/Carousel/CarouselItem/CarouselItem.js +25 -10
- package/lib-module/Carousel/dictionary.js +16 -0
- package/lib-module/InputSupports/InputSupports.js +10 -3
- package/lib-module/InputSupports/useInputSupports.js +3 -2
- package/lib-module/Modal/Modal.js +3 -0
- package/lib-module/Skeleton/Skeleton.js +1 -0
- package/lib-module/StepTracker/StepTracker.js +9 -10
- package/lib-module/TextInput/TextInput.js +3 -1
- package/lib-module/index.js +1 -0
- package/lib-module/utils/props/clickProps.js +2 -2
- package/lib-module/utils/props/handlerProps.js +78 -31
- package/lib-module/utils/useScrollBlocking.js +58 -0
- package/lib-module/utils/useScrollBlocking.native.js +2 -0
- package/package.json +3 -3
- package/src/Carousel/Carousel.jsx +93 -30
- package/src/Carousel/CarouselItem/CarouselItem.jsx +26 -8
- package/src/Carousel/dictionary.js +16 -0
- package/src/InputSupports/InputSupports.jsx +18 -3
- package/src/InputSupports/useInputSupports.js +2 -2
- package/src/Modal/Modal.jsx +3 -1
- package/src/Skeleton/Skeleton.jsx +1 -0
- package/src/StepTracker/StepTracker.jsx +9 -3
- package/src/TextInput/TextInput.jsx +1 -1
- package/src/index.js +1 -0
- package/src/utils/props/clickProps.js +2 -2
- package/src/utils/props/handlerProps.js +64 -16
- package/src/utils/useScrollBlocking.js +57 -0
- package/src/utils/useScrollBlocking.native.js +2 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = require("react");
|
|
9
|
+
|
|
10
|
+
const addScrollBlocking = (preventScrolling, stopPropagation, ref) => {
|
|
11
|
+
var _ref$current;
|
|
12
|
+
|
|
13
|
+
document.body.addEventListener('touchmove', preventScrolling, {
|
|
14
|
+
passive: false
|
|
15
|
+
});
|
|
16
|
+
(_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.addEventListener('touchmove', stopPropagation);
|
|
17
|
+
document.body.style.overflow = 'hidden';
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const removeScrollBlocking = (preventScrolling, stopPropagation, ref) => {
|
|
21
|
+
var _ref$current2;
|
|
22
|
+
|
|
23
|
+
document.body.removeEventListener('touchmove', preventScrolling);
|
|
24
|
+
(_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.removeEventListener('touchmove', stopPropagation);
|
|
25
|
+
document.body.style.overflow = 'inherit';
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Disables scrolling when passed `true` or an array where all items are `true`.
|
|
29
|
+
*
|
|
30
|
+
* Returns an optional callback ref. Pass this to an element if it or its children
|
|
31
|
+
* should allow touch-based scrolling within that element's bounds.
|
|
32
|
+
*
|
|
33
|
+
* @param {boolean | boolean[]} conditionProps
|
|
34
|
+
* @returns
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
const useScrollBlocking = conditionProps => {
|
|
39
|
+
// useRef refs are null on first render and don't trigger a re-render when they get their
|
|
40
|
+
// element. Force re-run when ref mounts to ensure the stopPropagation listener is attached.
|
|
41
|
+
const ref = (0, _react.useRef)();
|
|
42
|
+
const [refIsMounted, setRefIsMounted] = (0, _react.useState)(false);
|
|
43
|
+
const callbackRef = (0, _react.useCallback)(element => {
|
|
44
|
+
ref.current = element;
|
|
45
|
+
setRefIsMounted(Boolean(element));
|
|
46
|
+
}, []);
|
|
47
|
+
const conditionsMet = Array.isArray(conditionProps) ? conditionProps.every(condition => condition) : Boolean(conditionProps);
|
|
48
|
+
const preventScrolling = (0, _react.useCallback)(event => event.preventDefault(), []);
|
|
49
|
+
const stopPropagation = (0, _react.useCallback)(event => event.stopPropagation(), []);
|
|
50
|
+
(0, _react.useEffect)(() => {
|
|
51
|
+
const cleanup = () => removeScrollBlocking(preventScrolling, stopPropagation, ref);
|
|
52
|
+
|
|
53
|
+
if (conditionsMet) {
|
|
54
|
+
addScrollBlocking(preventScrolling, stopPropagation, ref);
|
|
55
|
+
} else {
|
|
56
|
+
cleanup();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return cleanup; // preventScrolling and stopPropagation are stable callbacks with no deps, so this
|
|
60
|
+
// will re-run when conditionsMet or refIsMounted flip between true and false.
|
|
61
|
+
}, [preventScrolling, conditionsMet, stopPropagation, refIsMounted]);
|
|
62
|
+
return callbackRef;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
var _default = useScrollBlocking;
|
|
66
|
+
exports.default = _default;
|
|
@@ -7,13 +7,14 @@ import Platform from "react-native-web/dist/exports/Platform";
|
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import { useThemeTokens } from '../ThemeProvider';
|
|
9
9
|
import { useViewport } from '../ViewportProvider';
|
|
10
|
-
import { getTokensPropType, variantProp, selectSystemProps, a11yProps, viewProps } from '../utils';
|
|
10
|
+
import { getTokensPropType, getA11yPropsFromHtmlTag, layoutTags, variantProp, selectSystemProps, a11yProps, viewProps, useCopy } from '../utils';
|
|
11
11
|
import { useA11yInfo } from '../A11yInfoProvider';
|
|
12
12
|
import { CarouselProvider } from './CarouselContext';
|
|
13
13
|
import CarouselItem from './CarouselItem';
|
|
14
14
|
import StepTracker from '../StepTracker';
|
|
15
15
|
import StackView from '../StackView';
|
|
16
16
|
import IconButton from '../IconButton';
|
|
17
|
+
import dictionary from './dictionary';
|
|
17
18
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
18
19
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
19
20
|
const staticStyles = StyleSheet.create({
|
|
@@ -77,14 +78,6 @@ const selectPreviousNextNavigationButtonStyles = (previousNextNavigationButtonWi
|
|
|
77
78
|
return styles;
|
|
78
79
|
};
|
|
79
80
|
|
|
80
|
-
const defaultPanelNavigationDictionary = {
|
|
81
|
-
en: {
|
|
82
|
-
stepTrackerLabel: 'Showing %{stepNumber} of %{stepCount}'
|
|
83
|
-
},
|
|
84
|
-
fr: {
|
|
85
|
-
stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
81
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
89
82
|
/**
|
|
90
83
|
* Carousel is a general-purpose content slider that can be used to render content in terms of slides.
|
|
@@ -146,6 +139,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
146
139
|
tokens,
|
|
147
140
|
variant,
|
|
148
141
|
children,
|
|
142
|
+
itemLabel = 'item',
|
|
149
143
|
previousNextNavigationPosition = 'inside',
|
|
150
144
|
previousNextIconSize = 'default',
|
|
151
145
|
minDistanceToCapture = 5,
|
|
@@ -155,9 +149,10 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
155
149
|
onIndexChanged,
|
|
156
150
|
springConfig = undefined,
|
|
157
151
|
onRenderPanelNavigation,
|
|
158
|
-
|
|
152
|
+
tag = 'ul',
|
|
159
153
|
accessibilityRole = 'adjustable',
|
|
160
154
|
accessibilityLabel = 'carousel',
|
|
155
|
+
copy,
|
|
161
156
|
...rest
|
|
162
157
|
} = _ref;
|
|
163
158
|
const viewport = useViewport();
|
|
@@ -172,6 +167,19 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
172
167
|
viewport
|
|
173
168
|
});
|
|
174
169
|
const [activeIndex, setActiveIndex] = React.useState(0);
|
|
170
|
+
const [isAnimating, setIsAnimating] = React.useState(false);
|
|
171
|
+
const handleAnimationStart = React.useCallback(function () {
|
|
172
|
+
if (typeof onAnimationStart === 'function') onAnimationStart(...arguments);
|
|
173
|
+
setIsAnimating(true);
|
|
174
|
+
}, [onAnimationStart]);
|
|
175
|
+
const handleAnimationEnd = React.useCallback(function () {
|
|
176
|
+
if (typeof onAnimationEnd === 'function') onAnimationEnd(...arguments);
|
|
177
|
+
setIsAnimating(false);
|
|
178
|
+
}, [onAnimationEnd]);
|
|
179
|
+
const getCopy = useCopy({
|
|
180
|
+
dictionary,
|
|
181
|
+
copy
|
|
182
|
+
});
|
|
175
183
|
const childrenArray = React.Children.toArray(children);
|
|
176
184
|
const systemProps = selectProps({ ...rest,
|
|
177
185
|
accessibilityRole,
|
|
@@ -240,20 +248,28 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
240
248
|
y: 0
|
|
241
249
|
});
|
|
242
250
|
}, [activeIndex, containerLayout.width, pan, animatedX]);
|
|
243
|
-
const animate = React.useCallback(toValue => {
|
|
251
|
+
const animate = React.useCallback((toValue, toIndex) => {
|
|
252
|
+
const handleAnimationEndToIndex = function () {
|
|
253
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
254
|
+
args[_key] = arguments[_key];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return handleAnimationEnd(toIndex, ...args);
|
|
258
|
+
};
|
|
259
|
+
|
|
244
260
|
if (reduceMotionEnabled) {
|
|
245
261
|
Animated.timing(pan, {
|
|
246
262
|
toValue,
|
|
247
263
|
duration: 1,
|
|
248
264
|
useNativeDriver: false
|
|
249
|
-
}).start();
|
|
265
|
+
}).start(handleAnimationEndToIndex);
|
|
250
266
|
} else {
|
|
251
267
|
Animated.spring(pan, { ...springConfig,
|
|
252
268
|
toValue,
|
|
253
269
|
useNativeDriver: false
|
|
254
|
-
}).start();
|
|
270
|
+
}).start(handleAnimationEndToIndex);
|
|
255
271
|
}
|
|
256
|
-
}, [pan, springConfig, reduceMotionEnabled]);
|
|
272
|
+
}, [pan, springConfig, reduceMotionEnabled, handleAnimationEnd]);
|
|
257
273
|
const updateIndex = React.useCallback(function () {
|
|
258
274
|
let delta = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
|
|
259
275
|
const toValue = {
|
|
@@ -271,24 +287,24 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
271
287
|
calcDelta = -1 * activeIndex + delta - 1;
|
|
272
288
|
}
|
|
273
289
|
|
|
290
|
+
const index = activeIndex + calcDelta;
|
|
291
|
+
|
|
274
292
|
if (skipChanges) {
|
|
275
|
-
animate(toValue);
|
|
293
|
+
animate(toValue, index);
|
|
276
294
|
return calcDelta;
|
|
277
295
|
}
|
|
278
296
|
|
|
279
|
-
const index = activeIndex + calcDelta;
|
|
280
297
|
setActiveIndex(index);
|
|
281
298
|
toValue.x = containerLayout.width * -1 * calcDelta;
|
|
282
|
-
animate(toValue);
|
|
299
|
+
animate(toValue, index);
|
|
283
300
|
if (onIndexChanged) onIndexChanged(calcDelta);
|
|
284
|
-
if (onAnimationEnd) onAnimationEnd(index);
|
|
285
301
|
return calcDelta;
|
|
286
|
-
}, [containerLayout.width, activeIndex, animate, children.length, onIndexChanged
|
|
302
|
+
}, [containerLayout.width, activeIndex, animate, children.length, onIndexChanged]);
|
|
287
303
|
const fixOffsetAndGo = React.useCallback(delta => {
|
|
288
304
|
updateOffset();
|
|
289
|
-
|
|
305
|
+
handleAnimationStart(activeIndex);
|
|
290
306
|
updateIndex(delta);
|
|
291
|
-
}, [updateIndex, updateOffset, activeIndex,
|
|
307
|
+
}, [updateIndex, updateOffset, activeIndex, handleAnimationStart]);
|
|
292
308
|
const goToNeighboring = React.useCallback(function () {
|
|
293
309
|
let toPrev = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
294
310
|
fixOffsetAndGo(toPrev ? -1 : 1);
|
|
@@ -308,7 +324,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
308
324
|
return false;
|
|
309
325
|
}
|
|
310
326
|
|
|
311
|
-
|
|
327
|
+
handleAnimationStart(activeIndex);
|
|
312
328
|
return Math.abs(gestureState.dx) > minDistanceToCapture;
|
|
313
329
|
},
|
|
314
330
|
onPanResponderGrant: () => updateOffset(),
|
|
@@ -324,13 +340,13 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
324
340
|
animate({
|
|
325
341
|
x: 0,
|
|
326
342
|
y: 0
|
|
327
|
-
});
|
|
343
|
+
}, 0);
|
|
328
344
|
} else {
|
|
329
345
|
const delta = correction > 0 ? -1 : 1;
|
|
330
346
|
updateIndex(delta);
|
|
331
347
|
}
|
|
332
348
|
}
|
|
333
|
-
}), [containerLayout.width, updateIndex, updateOffset, animate, isSwipeAllowed, activeIndex, minDistanceForAction,
|
|
349
|
+
}), [containerLayout.width, updateIndex, updateOffset, animate, isSwipeAllowed, activeIndex, minDistanceForAction, handleAnimationStart, minDistanceToCapture, pan.x]);
|
|
334
350
|
React.useEffect(() => {
|
|
335
351
|
pan.x.addListener(_ref4 => {
|
|
336
352
|
let {
|
|
@@ -370,6 +386,13 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
370
386
|
size: previousNextIconSize,
|
|
371
387
|
raised: true
|
|
372
388
|
};
|
|
389
|
+
|
|
390
|
+
const getCopyWithPlaceholders = copyKey => {
|
|
391
|
+
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
|
|
392
|
+
|
|
393
|
+
return "".concat(copyText[0].toUpperCase()).concat(copyText.slice(1));
|
|
394
|
+
};
|
|
395
|
+
|
|
373
396
|
return /*#__PURE__*/_jsxs(CarouselProvider, {
|
|
374
397
|
activeIndex: activeIndex,
|
|
375
398
|
totalItems: childrenArray.length,
|
|
@@ -388,7 +411,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
388
411
|
icon: previousIcon,
|
|
389
412
|
onPress: goToPrev,
|
|
390
413
|
variant: previousNextIconButtonVariants,
|
|
391
|
-
accessibilityLabel:
|
|
414
|
+
accessibilityLabel: getCopyWithPlaceholders('iconButtonLabel').replace('%{targetStep}', activeIndex)
|
|
392
415
|
})
|
|
393
416
|
}), /*#__PURE__*/_jsx(View, {
|
|
394
417
|
style: selectContainerStyles(containerLayout.width),
|
|
@@ -401,9 +424,12 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
401
424
|
}]
|
|
402
425
|
}]),
|
|
403
426
|
...panResponder.panHandlers,
|
|
427
|
+
...getA11yPropsFromHtmlTag(tag),
|
|
404
428
|
children: childrenArray.map((element, index) => {
|
|
429
|
+
const hidden = !isAnimating && index !== activeIndex;
|
|
405
430
|
const clonedElement = /*#__PURE__*/React.cloneElement(element, {
|
|
406
|
-
elementIndex: index
|
|
431
|
+
elementIndex: index,
|
|
432
|
+
hidden
|
|
407
433
|
});
|
|
408
434
|
return /*#__PURE__*/_jsx(React.Fragment, {
|
|
409
435
|
children: clonedElement
|
|
@@ -418,7 +444,7 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
418
444
|
icon: nextIcon,
|
|
419
445
|
onPress: goToNext,
|
|
420
446
|
variant: previousNextIconButtonVariants,
|
|
421
|
-
accessibilityLabel:
|
|
447
|
+
accessibilityLabel: getCopyWithPlaceholders('iconButtonLabel').replace('%{targetStep}', activeIndex + 2)
|
|
422
448
|
})
|
|
423
449
|
})]
|
|
424
450
|
}), showPanelNavigation ? /*#__PURE__*/_jsx(StackView, {
|
|
@@ -430,7 +456,11 @@ const Carousel = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
430
456
|
}) : /*#__PURE__*/_jsx(StepTracker, {
|
|
431
457
|
current: activeIndex,
|
|
432
458
|
steps: childrenArray.map((_, index) => String(index)),
|
|
433
|
-
|
|
459
|
+
copy: {
|
|
460
|
+
// Give StepTracker copy from Carousel's language and dictionary
|
|
461
|
+
stepLabel: getCopyWithPlaceholders('stepLabel'),
|
|
462
|
+
stepTrackerLabel: getCopyWithPlaceholders('stepTrackerLabel')
|
|
463
|
+
},
|
|
434
464
|
tokens: panelNavigationTokens
|
|
435
465
|
})
|
|
436
466
|
}) : null]
|
|
@@ -445,6 +475,14 @@ Carousel.propTypes = { ...selectedSystemPropTypes,
|
|
|
445
475
|
*/
|
|
446
476
|
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
|
|
447
477
|
|
|
478
|
+
/**
|
|
479
|
+
* Lowercase language-appropriate user-facing description of what each Carousel slide represents.
|
|
480
|
+
* This is used when generating item labels. For example, if a carousel contains offers,
|
|
481
|
+
* pass itemLabel="summer offer" (or copy="fr" and an appropriate French translation) to genereate
|
|
482
|
+
* accessible labels such as "Summer offer 1 of 3" and "Show summer offer 2 of 3".
|
|
483
|
+
*/
|
|
484
|
+
itemLabel: PropTypes.string,
|
|
485
|
+
|
|
448
486
|
/**
|
|
449
487
|
* `inside` renders the previous and next buttons inside the slide
|
|
450
488
|
* `outside` renders the previous and next buttons outside the slide
|
|
@@ -563,7 +601,16 @@ Carousel.propTypes = { ...selectedSystemPropTypes,
|
|
|
563
601
|
/**
|
|
564
602
|
* Provide custom accessibilityLabel for Carousel container
|
|
565
603
|
*/
|
|
566
|
-
accessibilityLabel: PropTypes.string
|
|
604
|
+
accessibilityLabel: PropTypes.string,
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* HTML tag to use for the Carousel item's immediate parent. Defaults to `'ul'` so that
|
|
608
|
+
* assistive technology tools know to intepret the carousel as a list.
|
|
609
|
+
*
|
|
610
|
+
* Note that if the immediate Carousel children do not all render as `'li'` elements,
|
|
611
|
+
* this should be changed (e.g. pass tag="div") because only 'li' is a valid child of 'ul'.
|
|
612
|
+
*/
|
|
613
|
+
tag: PropTypes.oneOf(layoutTags)
|
|
567
614
|
};
|
|
568
615
|
Carousel.Item = CarouselItem;
|
|
569
616
|
Carousel.displayName = 'Carousel';
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
import View from "react-native-web/dist/exports/View";
|
|
4
4
|
import Platform from "react-native-web/dist/exports/Platform";
|
|
5
|
-
import { selectSystemProps, a11yProps, viewProps } from '../../utils';
|
|
5
|
+
import { layoutTags, getA11yPropsFromHtmlTag, selectSystemProps, a11yProps, viewProps } from '../../utils';
|
|
6
6
|
import { useCarousel } from '../CarouselContext';
|
|
7
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
8
8
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
@@ -15,23 +15,29 @@ const CarouselItem = _ref => {
|
|
|
15
15
|
let {
|
|
16
16
|
children,
|
|
17
17
|
elementIndex,
|
|
18
|
+
tag = 'li',
|
|
19
|
+
hidden,
|
|
18
20
|
...rest
|
|
19
21
|
} = _ref;
|
|
20
22
|
const {
|
|
21
23
|
width,
|
|
22
|
-
activeIndex
|
|
23
|
-
totalItems
|
|
24
|
+
activeIndex
|
|
24
25
|
} = useCarousel();
|
|
25
26
|
const selectedProps = selectProps({ ...rest,
|
|
26
|
-
|
|
27
|
-
accessibilityRole: Platform.OS === 'android' ? 'none' : 'group',
|
|
28
|
-
accessibilityLabel: "Showing ".concat(elementIndex + 1, " of ").concat(totalItems)
|
|
27
|
+
...getA11yPropsFromHtmlTag(tag, rest.accessibilityRole)
|
|
29
28
|
});
|
|
30
29
|
const focusabilityProps = activeIndex === elementIndex ? {} : a11yProps.nonFocusableProps;
|
|
30
|
+
const style = {
|
|
31
|
+
width
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
if (hidden && Platform.OS === 'web') {
|
|
35
|
+
// On web, visibility: hidden makes all children non-focusable. It doesn't exist on native.
|
|
36
|
+
style.visibility = 'hidden';
|
|
37
|
+
}
|
|
38
|
+
|
|
31
39
|
return /*#__PURE__*/_jsx(View, {
|
|
32
|
-
style:
|
|
33
|
-
width
|
|
34
|
-
},
|
|
40
|
+
style: style,
|
|
35
41
|
...selectedProps,
|
|
36
42
|
...focusabilityProps,
|
|
37
43
|
children: children
|
|
@@ -54,7 +60,16 @@ CarouselItem.propTypes = { ...selectedSystemPropTypes,
|
|
|
54
60
|
/**
|
|
55
61
|
* Content of the slide
|
|
56
62
|
*/
|
|
57
|
-
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired
|
|
63
|
+
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Sets the HTML tag of the outer container. By default `'li'` so that assistive technology sees
|
|
67
|
+
* the Carousel as a list of items.
|
|
68
|
+
*
|
|
69
|
+
* Carousel's innermost container defaults to `'ul'` which can be overridden. If the tag of either
|
|
70
|
+
* `Carousel` or `Carousel.Item` is overriden, the other should be too, to avoid producing invalid HTML.
|
|
71
|
+
*/
|
|
72
|
+
tag: PropTypes.oneOf(layoutTags)
|
|
58
73
|
};
|
|
59
74
|
CarouselItem.displayName = 'Carousel.Item';
|
|
60
75
|
export default CarouselItem;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// 'stepLabel' and 'stepTrackerLabel' are passed down to StepTracker
|
|
2
|
+
export default {
|
|
3
|
+
en: {
|
|
4
|
+
carouselLabel: '%{stepCount} items',
|
|
5
|
+
iconButtonLabel: 'Show %{itemLabel} %{targetStep} of %{stepCount}',
|
|
6
|
+
stepLabel: '%{itemLabel} %{stepNumber}',
|
|
7
|
+
stepTrackerLabel: '%{itemLabel} %{stepNumber} of %{stepCount}'
|
|
8
|
+
},
|
|
9
|
+
fr: {
|
|
10
|
+
// TODO: French translations here
|
|
11
|
+
carouselLabel: '(fr) %{stepCount} items',
|
|
12
|
+
iconButtonLabel: '(fr) Show %{itemLabel} %{targetStep} of %{stepCount}',
|
|
13
|
+
stepLabel: '(fr) %{itemLabel} %{stepNumber}',
|
|
14
|
+
stepTrackerLabel: '(fr) %{itemLabel} %{stepNumber} of %{stepCount}'
|
|
15
|
+
}
|
|
16
|
+
};
|
|
@@ -16,7 +16,8 @@ const InputSupports = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
16
16
|
hintPosition = 'inline',
|
|
17
17
|
feedback,
|
|
18
18
|
tooltip,
|
|
19
|
-
validation
|
|
19
|
+
validation,
|
|
20
|
+
nativeID
|
|
20
21
|
} = _ref;
|
|
21
22
|
const {
|
|
22
23
|
space
|
|
@@ -30,7 +31,8 @@ const InputSupports = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
30
31
|
feedback,
|
|
31
32
|
hint,
|
|
32
33
|
label,
|
|
33
|
-
validation
|
|
34
|
+
validation,
|
|
35
|
+
nativeID
|
|
34
36
|
});
|
|
35
37
|
return /*#__PURE__*/_jsxs(StackView, {
|
|
36
38
|
space: space,
|
|
@@ -91,6 +93,11 @@ InputSupports.propTypes = {
|
|
|
91
93
|
/**
|
|
92
94
|
* Use to visually mark an input as valid or invalid.
|
|
93
95
|
*/
|
|
94
|
-
validation: PropTypes.oneOf(['error', 'success'])
|
|
96
|
+
validation: PropTypes.oneOf(['error', 'success']),
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* ID for DOM element on web
|
|
100
|
+
*/
|
|
101
|
+
nativeID: PropTypes.string
|
|
95
102
|
};
|
|
96
103
|
export default InputSupports;
|
|
@@ -7,7 +7,8 @@ const useInputSupports = _ref => {
|
|
|
7
7
|
label,
|
|
8
8
|
feedback,
|
|
9
9
|
validation,
|
|
10
|
-
hint
|
|
10
|
+
hint,
|
|
11
|
+
nativeID
|
|
11
12
|
} = _ref;
|
|
12
13
|
const hasValidationError = validation === 'error';
|
|
13
14
|
const inputId = useUniqueId('input');
|
|
@@ -22,7 +23,7 @@ const useInputSupports = _ref => {
|
|
|
22
23
|
accessibilityInvalid: hasValidationError
|
|
23
24
|
};
|
|
24
25
|
return {
|
|
25
|
-
inputId,
|
|
26
|
+
inputId: nativeID || inputId,
|
|
26
27
|
hintId,
|
|
27
28
|
feedbackId,
|
|
28
29
|
a11yProps
|
|
@@ -10,6 +10,7 @@ import { a11yProps, copyPropTypes, getTokensPropType, selectSystemProps, useCopy
|
|
|
10
10
|
import { useViewport } from '../ViewportProvider';
|
|
11
11
|
import IconButton from '../IconButton';
|
|
12
12
|
import dictionary from './dictionary';
|
|
13
|
+
import useScrollBlocking from '../utils/useScrollBlocking';
|
|
13
14
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
14
15
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
15
16
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
@@ -110,6 +111,7 @@ const Modal = /*#__PURE__*/forwardRef((_ref5, ref) => {
|
|
|
110
111
|
viewport,
|
|
111
112
|
maxWidth
|
|
112
113
|
});
|
|
114
|
+
const modalRef = useScrollBlocking(isOpen);
|
|
113
115
|
const {
|
|
114
116
|
closeIcon: CloseIconComponent
|
|
115
117
|
} = themeTokens;
|
|
@@ -140,6 +142,7 @@ const Modal = /*#__PURE__*/forwardRef((_ref5, ref) => {
|
|
|
140
142
|
...selectProps(rest),
|
|
141
143
|
children: /*#__PURE__*/_jsxs(View, {
|
|
142
144
|
style: [staticStyles.positioningContainer],
|
|
145
|
+
ref: modalRef,
|
|
143
146
|
children: [/*#__PURE__*/_jsx(View, {
|
|
144
147
|
style: [staticStyles.sizingContainer, selectContainerStyles(themeTokens)],
|
|
145
148
|
pointerEvents: "box-none" // don't capture backdrop press events
|
|
@@ -154,19 +154,18 @@ const StepTracker = /*#__PURE__*/forwardRef((_ref4, ref) => {
|
|
|
154
154
|
})
|
|
155
155
|
});
|
|
156
156
|
});
|
|
157
|
-
StepTracker.displayName = 'StepTracker';
|
|
157
|
+
StepTracker.displayName = 'StepTracker'; // If a language dictionary entry is provided, it must contain every key
|
|
158
|
+
|
|
159
|
+
const dictionaryContentShape = PropTypes.shape({
|
|
160
|
+
stepLabel: PropTypes.string.isRequired,
|
|
161
|
+
stepTrackerLabel: PropTypes.string.isRequired
|
|
162
|
+
});
|
|
158
163
|
StepTracker.propTypes = { ...selectedSystemPropTypes,
|
|
159
164
|
current: PropTypes.number,
|
|
160
|
-
copy: PropTypes.oneOf(['en', 'fr']),
|
|
165
|
+
copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), dictionaryContentShape]),
|
|
161
166
|
dictionary: PropTypes.shape({
|
|
162
|
-
en:
|
|
163
|
-
|
|
164
|
-
stepTrackerLabel: PropTypes.string
|
|
165
|
-
}),
|
|
166
|
-
fr: PropTypes.shape({
|
|
167
|
-
stepLabel: PropTypes.string,
|
|
168
|
-
stepTrackerLabel: PropTypes.string
|
|
169
|
-
})
|
|
167
|
+
en: dictionaryContentShape,
|
|
168
|
+
fr: dictionaryContentShape
|
|
170
169
|
}),
|
|
171
170
|
steps: PropTypes.arrayOf(PropTypes.string),
|
|
172
171
|
tokens: getTokensPropType('StepTracker'),
|
|
@@ -40,7 +40,9 @@ const TextInput = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
40
40
|
validation: supportsProps.validation
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
|
-
return /*#__PURE__*/_jsx(InputSupports, {
|
|
43
|
+
return /*#__PURE__*/_jsx(InputSupports, {
|
|
44
|
+
nativeID: selectedProps.nativeID,
|
|
45
|
+
...supportsProps,
|
|
44
46
|
children: _ref2 => {
|
|
45
47
|
let {
|
|
46
48
|
inputId,
|
package/lib-module/index.js
CHANGED
|
@@ -17,6 +17,7 @@ export { default as Icon } from './Icon';
|
|
|
17
17
|
export * from './Icon';
|
|
18
18
|
export { default as IconButton } from './IconButton';
|
|
19
19
|
export { default as InputLabel } from './InputLabel';
|
|
20
|
+
export { default as InputSupports } from './InputSupports';
|
|
20
21
|
export * from './Link';
|
|
21
22
|
export { default as List, ListItem, ListBase } from './List';
|
|
22
23
|
export { default as Modal } from './Modal';
|