@telus-uds/components-base 4.0.0-alpha.0 → 4.0.0-alpha.2
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 +62 -6
- package/jest.config.cjs +1 -0
- package/lib/cjs/ActionCard/ActionCard.js +10 -3
- package/lib/cjs/Card/Card.js +3 -3
- package/lib/cjs/Carousel/Carousel.js +6 -1
- package/lib/cjs/Carousel/CarouselThumbnail.js +125 -33
- package/lib/cjs/Carousel/CarouselThumbnailNavigation.js +8 -1
- package/lib/cjs/Footnote/FootnoteLink.js +18 -17
- package/lib/cjs/InputSupports/InputSupports.js +1 -2
- package/lib/cjs/InputSupports/useInputSupports.js +1 -3
- package/lib/cjs/Link/ChevronLink.js +1 -2
- package/lib/cjs/Notification/Notification.js +4 -12
- package/lib/cjs/Progress/Progress.js +30 -5
- package/lib/cjs/Progress/ProgressBar.js +3 -3
- package/lib/cjs/Progress/ProgressBarBackground.js +2 -3
- package/lib/cjs/QuickLinks/QuickLinks.js +7 -0
- package/lib/cjs/Scroll/Scroll.js +472 -0
- package/lib/cjs/Scroll/ScrollContext.js +55 -0
- package/lib/cjs/Scroll/ScrollItem.js +106 -0
- package/lib/cjs/Scroll/ScrollProgress.js +100 -0
- package/lib/cjs/Scroll/dictionary.js +18 -0
- package/lib/cjs/StackView/StackWrapBox.js +9 -1
- package/lib/cjs/StackView/StackWrapGap.js +3 -1
- package/lib/cjs/StackView/getStackedContent.js +20 -10
- package/lib/cjs/index.js +14 -0
- package/lib/cjs/utils/animation/useAnimatedValue.js +46 -0
- package/lib/cjs/utils/children.js +2 -1
- package/lib/esm/ActionCard/ActionCard.js +10 -3
- package/lib/esm/Card/Card.js +3 -3
- package/lib/esm/Carousel/Carousel.js +6 -1
- package/lib/esm/Carousel/CarouselThumbnail.js +126 -34
- package/lib/esm/Carousel/CarouselThumbnailNavigation.js +8 -1
- package/lib/esm/Footnote/FootnoteLink.js +18 -17
- package/lib/esm/InputSupports/InputSupports.js +1 -2
- package/lib/esm/InputSupports/useInputSupports.js +1 -3
- package/lib/esm/Link/ChevronLink.js +1 -2
- package/lib/esm/Notification/Notification.js +4 -12
- package/lib/esm/Progress/Progress.js +30 -5
- package/lib/esm/Progress/ProgressBar.js +3 -3
- package/lib/esm/Progress/ProgressBarBackground.js +2 -3
- package/lib/esm/QuickLinks/QuickLinks.js +7 -0
- package/lib/esm/Scroll/Scroll.js +465 -0
- package/lib/esm/Scroll/ScrollContext.js +46 -0
- package/lib/esm/Scroll/ScrollItem.js +100 -0
- package/lib/esm/Scroll/ScrollProgress.js +93 -0
- package/lib/esm/Scroll/dictionary.js +12 -0
- package/lib/esm/StackView/StackWrapBox.js +9 -1
- package/lib/esm/StackView/StackWrapGap.js +3 -1
- package/lib/esm/StackView/getStackedContent.js +20 -10
- package/lib/esm/index.js +2 -0
- package/lib/esm/utils/animation/useAnimatedValue.js +38 -0
- package/lib/esm/utils/children.js +2 -1
- package/lib/package.json +2 -2
- package/package.json +2 -2
- package/src/ActionCard/ActionCard.jsx +13 -4
- package/src/Card/Card.jsx +3 -3
- package/src/Carousel/Carousel.jsx +6 -1
- package/src/Carousel/CarouselThumbnail.jsx +117 -30
- package/src/Carousel/CarouselThumbnailNavigation.jsx +8 -2
- package/src/Footnote/FootnoteLink.jsx +17 -12
- package/src/InputSupports/InputSupports.jsx +1 -6
- package/src/InputSupports/useInputSupports.js +1 -1
- package/src/Link/ChevronLink.jsx +1 -2
- package/src/Notification/Notification.jsx +5 -21
- package/src/Progress/Progress.jsx +22 -3
- package/src/Progress/ProgressBar.jsx +3 -3
- package/src/Progress/ProgressBarBackground.jsx +2 -3
- package/src/QuickLinks/QuickLinks.jsx +8 -0
- package/src/Scroll/Scroll.jsx +483 -0
- package/src/Scroll/ScrollContext.jsx +39 -0
- package/src/Scroll/ScrollItem.jsx +87 -0
- package/src/Scroll/ScrollProgress.jsx +74 -0
- package/src/Scroll/dictionary.js +12 -0
- package/src/StackView/StackWrapBox.jsx +13 -1
- package/src/StackView/StackWrapGap.jsx +2 -1
- package/src/StackView/getStackedContent.jsx +22 -8
- package/src/index.js +2 -0
- package/src/utils/animation/useAnimatedValue.js +35 -0
- package/src/utils/children.jsx +4 -1
- package/types/Link.d.ts +1 -2
- package/types/Scroll.d.ts +66 -0
- package/types/index.d.ts +9 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ScrollProgress = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
9
|
+
var _View = _interopRequireDefault(require("react-native-web/dist/cjs/exports/View"));
|
|
10
|
+
var _pressability = require("../utils/pressability");
|
|
11
|
+
var _useAnimatedValue = require("../utils/animation/useAnimatedValue");
|
|
12
|
+
var _Progress = require("../Progress/Progress");
|
|
13
|
+
var _ProgressBar = require("../Progress/ProgressBar");
|
|
14
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
|
+
const MAX_PERCENTAGE = 100;
|
|
17
|
+
const BORDER_RADIUS_DIVISOR = 2;
|
|
18
|
+
const staticProgressTokens = {
|
|
19
|
+
borderWidth: 0,
|
|
20
|
+
borderColor: 'transparent'
|
|
21
|
+
};
|
|
22
|
+
const staticProgressBarTokens = {
|
|
23
|
+
gradient: null,
|
|
24
|
+
outlineWidth: 0
|
|
25
|
+
};
|
|
26
|
+
const selectProgressTokens = _ref => {
|
|
27
|
+
let {
|
|
28
|
+
progressTrackHeight,
|
|
29
|
+
progressBarHeight,
|
|
30
|
+
progressTrackColor
|
|
31
|
+
} = _ref;
|
|
32
|
+
return {
|
|
33
|
+
height: progressTrackHeight,
|
|
34
|
+
barHeight: progressBarHeight,
|
|
35
|
+
backgroundColor: progressTrackColor,
|
|
36
|
+
borderRadius: progressTrackHeight / BORDER_RADIUS_DIVISOR
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
const selectBarTokens = _ref2 => {
|
|
40
|
+
let {
|
|
41
|
+
progressBarColor,
|
|
42
|
+
progressBarHeight
|
|
43
|
+
} = _ref2;
|
|
44
|
+
return {
|
|
45
|
+
backgroundColor: progressBarColor,
|
|
46
|
+
borderRadius: progressBarHeight / BORDER_RADIUS_DIVISOR
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const ScrollProgress = exports.ScrollProgress = /*#__PURE__*/_react.default.forwardRef((_ref3, ref) => {
|
|
50
|
+
let {
|
|
51
|
+
pressableState,
|
|
52
|
+
getTokens,
|
|
53
|
+
thumbWrapperStyle,
|
|
54
|
+
getCopy
|
|
55
|
+
} = _ref3;
|
|
56
|
+
const state = (0, _pressability.resolvePressableState)(pressableState);
|
|
57
|
+
const themeTokens = getTokens(state);
|
|
58
|
+
const animatedBarHeight = (0, _useAnimatedValue.useAnimatedValue)(themeTokens.progressBarHeight);
|
|
59
|
+
const animatedTokens = {
|
|
60
|
+
...themeTokens,
|
|
61
|
+
progressBarHeight: animatedBarHeight
|
|
62
|
+
};
|
|
63
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Progress.Progress, {
|
|
64
|
+
tokens: {
|
|
65
|
+
...staticProgressTokens,
|
|
66
|
+
...selectProgressTokens(animatedTokens)
|
|
67
|
+
},
|
|
68
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
69
|
+
ref: ref,
|
|
70
|
+
style: thumbWrapperStyle,
|
|
71
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ProgressBar.ProgressBar, {
|
|
72
|
+
percentage: MAX_PERCENTAGE,
|
|
73
|
+
tokens: {
|
|
74
|
+
...staticProgressBarTokens,
|
|
75
|
+
...selectBarTokens(animatedTokens)
|
|
76
|
+
},
|
|
77
|
+
accessibilityLabel: getCopy('progressBarLabel')
|
|
78
|
+
})
|
|
79
|
+
})
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
ScrollProgress.displayName = 'ScrollProgress';
|
|
83
|
+
ScrollProgress.propTypes = {
|
|
84
|
+
/**
|
|
85
|
+
* State object from Pressable's render callback containing hovered, pressed, and focused states
|
|
86
|
+
*/
|
|
87
|
+
pressableState: _propTypes.default.object.isRequired,
|
|
88
|
+
/**
|
|
89
|
+
* Theme token resolver callback from useThemeTokensCallback that accepts appearance state
|
|
90
|
+
*/
|
|
91
|
+
getTokens: _propTypes.default.func.isRequired,
|
|
92
|
+
/**
|
|
93
|
+
* Style array for the thumb wrapper containing static and dynamic position styles
|
|
94
|
+
*/
|
|
95
|
+
thumbWrapperStyle: _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.array]).isRequired,
|
|
96
|
+
/**
|
|
97
|
+
* Copy resolver function from useCopy for retrieving localized strings
|
|
98
|
+
*/
|
|
99
|
+
getCopy: _propTypes.default.func.isRequired
|
|
100
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.dictionary = void 0;
|
|
7
|
+
const dictionary = exports.dictionary = {
|
|
8
|
+
en: {
|
|
9
|
+
accessibilityLabel: 'Scrollable content',
|
|
10
|
+
instructionText: 'Use Tab, arrow keys, or space bar to navigate',
|
|
11
|
+
progressBarLabel: 'Scroll position'
|
|
12
|
+
},
|
|
13
|
+
fr: {
|
|
14
|
+
accessibilityLabel: 'Contenu défilable',
|
|
15
|
+
instructionText: "Utilisez Tab, les touches fléchées ou la barre d'espace pour naviguer",
|
|
16
|
+
progressBarLabel: 'Position de défilement'
|
|
17
|
+
}
|
|
18
|
+
};
|
|
@@ -58,6 +58,7 @@ const StackWrapBox = exports.StackWrapBox = /*#__PURE__*/_react.default.forwardR
|
|
|
58
58
|
variant,
|
|
59
59
|
tag,
|
|
60
60
|
accessibilityRole,
|
|
61
|
+
itemAccessibilityRole,
|
|
61
62
|
...rest
|
|
62
63
|
} = _ref;
|
|
63
64
|
const viewport = (0, _useViewport.useViewport)();
|
|
@@ -84,7 +85,8 @@ const StackWrapBox = exports.StackWrapBox = /*#__PURE__*/_react.default.forwardR
|
|
|
84
85
|
const content = (0, _getStackedContent.getStackedContent)(children, {
|
|
85
86
|
direction,
|
|
86
87
|
space: 0,
|
|
87
|
-
box: boxProps
|
|
88
|
+
box: boxProps,
|
|
89
|
+
itemAccessibilityRole
|
|
88
90
|
});
|
|
89
91
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
90
92
|
ref: ref,
|
|
@@ -120,6 +122,12 @@ StackWrapBox.propTypes = {
|
|
|
120
122
|
* is not defined, the accessibilityRole will default to "heading".
|
|
121
123
|
*/
|
|
122
124
|
tag: _propTypes.default.oneOf(_semantics.layoutTags),
|
|
125
|
+
/**
|
|
126
|
+
* Optional accessibility role to apply to each item in the stack.
|
|
127
|
+
* On web, items are wrapped (or cloned) with this role, enabling correct list semantics
|
|
128
|
+
* when the container tag is "ul" or "ol".
|
|
129
|
+
*/
|
|
130
|
+
itemAccessibilityRole: _propTypes.default.string,
|
|
123
131
|
/**
|
|
124
132
|
* A StackWrap may take any children, but will have no effect if it is only passed one child or is passed children
|
|
125
133
|
* wrapped in a component. If necessary, children may be wrapped in one React Fragment.
|
|
@@ -40,6 +40,7 @@ const StackWrapGap = exports.StackWrapGap = /*#__PURE__*/_react.default.forwardR
|
|
|
40
40
|
children,
|
|
41
41
|
tag,
|
|
42
42
|
accessibilityRole,
|
|
43
|
+
itemAccessibilityRole,
|
|
43
44
|
...rest
|
|
44
45
|
} = _ref;
|
|
45
46
|
const viewport = (0, _useViewport.useViewport)();
|
|
@@ -59,7 +60,8 @@ const StackWrapGap = exports.StackWrapGap = /*#__PURE__*/_react.default.forwardR
|
|
|
59
60
|
};
|
|
60
61
|
const content = (0, _getStackedContent.getStackedContent)(children, {
|
|
61
62
|
direction,
|
|
62
|
-
space: 0
|
|
63
|
+
space: 0,
|
|
64
|
+
itemAccessibilityRole
|
|
63
65
|
});
|
|
64
66
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_View.default, {
|
|
65
67
|
ref: ref,
|
|
@@ -42,7 +42,8 @@ const getStackedContent = (children, _ref) => {
|
|
|
42
42
|
space,
|
|
43
43
|
direction = 'column',
|
|
44
44
|
box,
|
|
45
|
-
preserveFragments = false
|
|
45
|
+
preserveFragments = false,
|
|
46
|
+
itemAccessibilityRole
|
|
46
47
|
} = _ref;
|
|
47
48
|
const boxProps = box && typeof box === 'object' ? box : {
|
|
48
49
|
space
|
|
@@ -54,15 +55,24 @@ const getStackedContent = (children, _ref) => {
|
|
|
54
55
|
const validChildren = _react.default.Children.toArray(topLevelChildren).filter(Boolean);
|
|
55
56
|
const content = validChildren.reduce((newChildren, child, index) => {
|
|
56
57
|
const boxID = `Stack-Box-${index}`;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
let item;
|
|
59
|
+
if (box) {
|
|
60
|
+
// If wrapped in Box, that Box needs a key.
|
|
61
|
+
// If possible, use an existing content key; use an index-based key only if necessary.
|
|
62
|
+
item = /*#__PURE__*/(0, _react.createElement)(_Box.Box, {
|
|
63
|
+
...boxProps,
|
|
64
|
+
accessibilityRole: itemAccessibilityRole,
|
|
65
|
+
key: child.key || boxID,
|
|
66
|
+
testID: boxID
|
|
67
|
+
}, child);
|
|
68
|
+
} else if (itemAccessibilityRole) {
|
|
69
|
+
item = /*#__PURE__*/_react.default.cloneElement(child, {
|
|
70
|
+
accessibilityRole: itemAccessibilityRole,
|
|
71
|
+
key: child.key || boxID
|
|
72
|
+
});
|
|
73
|
+
} else {
|
|
74
|
+
item = child;
|
|
75
|
+
}
|
|
66
76
|
if (!index || !space && !divider) return [...newChildren, item];
|
|
67
77
|
const testID = `Stack-${divider ? 'Divider' : 'Spacer'}-${index}`;
|
|
68
78
|
const commonProps = {
|
package/lib/cjs/index.js
CHANGED
|
@@ -471,6 +471,18 @@ Object.defineProperty(exports, "Responsive", {
|
|
|
471
471
|
return _Responsive.Responsive;
|
|
472
472
|
}
|
|
473
473
|
});
|
|
474
|
+
Object.defineProperty(exports, "Scroll", {
|
|
475
|
+
enumerable: true,
|
|
476
|
+
get: function () {
|
|
477
|
+
return _Scroll.Scroll;
|
|
478
|
+
}
|
|
479
|
+
});
|
|
480
|
+
Object.defineProperty(exports, "ScrollItem", {
|
|
481
|
+
enumerable: true,
|
|
482
|
+
get: function () {
|
|
483
|
+
return _ScrollItem.ScrollItem;
|
|
484
|
+
}
|
|
485
|
+
});
|
|
474
486
|
Object.defineProperty(exports, "Search", {
|
|
475
487
|
enumerable: true,
|
|
476
488
|
get: function () {
|
|
@@ -1272,6 +1284,8 @@ var _RadioGroup = require("./Radio/RadioGroup");
|
|
|
1272
1284
|
var _RadioCard = require("./RadioCard/RadioCard");
|
|
1273
1285
|
var _RadioCardGroup = require("./RadioCard/RadioCardGroup");
|
|
1274
1286
|
var _Responsive = require("./Responsive/Responsive");
|
|
1287
|
+
var _Scroll = require("./Scroll/Scroll");
|
|
1288
|
+
var _ScrollItem = require("./Scroll/ScrollItem");
|
|
1275
1289
|
var _Search = require("./Search/Search");
|
|
1276
1290
|
var _Select = require("./Select/Select");
|
|
1277
1291
|
var _SelectItem = require("./Select/SelectItem");
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useAnimatedValue = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _Animated = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Animated"));
|
|
9
|
+
var _Easing = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Easing"));
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
const ANIMATION_DURATION = 200;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Smoothly animates a numeric value to a new target using a quadratic ease-in-out
|
|
15
|
+
* curve. Returns the current interpolated value as a plain number so
|
|
16
|
+
* consumers can use it in non-Animated style props.
|
|
17
|
+
*
|
|
18
|
+
* @param {number} targetValue - The value to animate towards.
|
|
19
|
+
* @param {number} [duration=ANIMATION_DURATION] - Animation duration in ms.
|
|
20
|
+
*/
|
|
21
|
+
const useAnimatedValue = function (targetValue) {
|
|
22
|
+
let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ANIMATION_DURATION;
|
|
23
|
+
const [currentValue, setCurrentValue] = _react.default.useState(targetValue);
|
|
24
|
+
const animatedValue = _react.default.useRef(new _Animated.default.Value(targetValue)).current;
|
|
25
|
+
_react.default.useEffect(() => {
|
|
26
|
+
const id = animatedValue.addListener(_ref => {
|
|
27
|
+
let {
|
|
28
|
+
value
|
|
29
|
+
} = _ref;
|
|
30
|
+
return setCurrentValue(value);
|
|
31
|
+
});
|
|
32
|
+
return () => animatedValue.removeListener(id);
|
|
33
|
+
}, [animatedValue]);
|
|
34
|
+
_react.default.useEffect(() => {
|
|
35
|
+
const animation = _Animated.default.timing(animatedValue, {
|
|
36
|
+
toValue: targetValue,
|
|
37
|
+
duration,
|
|
38
|
+
easing: _Easing.default.inOut(_Easing.default.quad),
|
|
39
|
+
useNativeDriver: false
|
|
40
|
+
});
|
|
41
|
+
animation.start();
|
|
42
|
+
return () => animation.stop();
|
|
43
|
+
}, [targetValue, animatedValue, duration]);
|
|
44
|
+
return currentValue;
|
|
45
|
+
};
|
|
46
|
+
exports.useAnimatedValue = useAnimatedValue;
|
|
@@ -54,7 +54,8 @@ const unpackFragment = child => {
|
|
|
54
54
|
exports.unpackFragment = unpackFragment;
|
|
55
55
|
const isStringOrNumber = child => typeof child === 'string' || typeof child === 'number';
|
|
56
56
|
// Wrap an A11yText with neighouring text strings so it doesn't split them into multiple <Text>s
|
|
57
|
-
|
|
57
|
+
// Check displayName first as it is explicitly set and reliable regardless of export style (named vs default)
|
|
58
|
+
const isWrapable = child => isStringOrNumber(child) || child.type === _A11yText.A11yText || child.type?.__UDS_COMPONENT_NAME__ === 'FootnoteLink';
|
|
58
59
|
const combineKeys = childrenArray => childrenArray.reduce((newKey, child) => `${newKey}${child.key || ''}`, '');
|
|
59
60
|
|
|
60
61
|
// Group wrappable children for one `<Text>` parent, merging adjacent text nodes
|
|
@@ -2,7 +2,6 @@ import React from 'react';
|
|
|
2
2
|
import Animated from "react-native-web/dist/exports/Animated";
|
|
3
3
|
import View from "react-native-web/dist/exports/View";
|
|
4
4
|
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
|
-
import Text from "react-native-web/dist/exports/Text";
|
|
6
5
|
import PropTypes from 'prop-types';
|
|
7
6
|
import { a11yProps } from '../utils/props/a11yProps';
|
|
8
7
|
import { getTokensPropType } from '../utils/props/tokens';
|
|
@@ -253,9 +252,10 @@ export const ActionCard = /*#__PURE__*/React.forwardRef((_ref1, ref) => {
|
|
|
253
252
|
style: staticStyles.header,
|
|
254
253
|
children: [/*#__PURE__*/_jsx(View, {
|
|
255
254
|
style: [selectTitleStyles(themeTokens), staticStyles.title],
|
|
256
|
-
children: /*#__PURE__*/_jsxs(
|
|
255
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
256
|
+
style: staticStyles.titleRow,
|
|
257
257
|
children: [wrapStringsInText(title, {
|
|
258
|
-
style: selectTitleTextStyles(themeTokens)
|
|
258
|
+
style: [selectTitleTextStyles(themeTokens), staticStyles.titleText]
|
|
259
259
|
}), themeTokens.statusIcon && /*#__PURE__*/_jsx(View, {
|
|
260
260
|
style: staticStyles.statusIcon,
|
|
261
261
|
children: /*#__PURE__*/_jsx(Icon, {
|
|
@@ -344,6 +344,13 @@ const staticStyles = StyleSheet.create({
|
|
|
344
344
|
title: {
|
|
345
345
|
flexShrink: 1
|
|
346
346
|
},
|
|
347
|
+
titleRow: {
|
|
348
|
+
flexDirection: 'row',
|
|
349
|
+
alignItems: 'center'
|
|
350
|
+
},
|
|
351
|
+
titleText: {
|
|
352
|
+
flexShrink: 1
|
|
353
|
+
},
|
|
347
354
|
statusIcon: {
|
|
348
355
|
marginLeft: 4
|
|
349
356
|
}
|
package/lib/esm/Card/Card.js
CHANGED
|
@@ -80,10 +80,10 @@ const getInputProps = _ref3 => {
|
|
|
80
80
|
*
|
|
81
81
|
* ## Component API
|
|
82
82
|
*
|
|
83
|
-
* ###
|
|
83
|
+
* ### Style
|
|
84
84
|
*
|
|
85
|
-
* In order to control the
|
|
86
|
-
* supported:
|
|
85
|
+
* In order to control the style of a card, use the `style` variant.
|
|
86
|
+
* The following tokens are supported:
|
|
87
87
|
*
|
|
88
88
|
* - `backgroundColor`
|
|
89
89
|
*
|
|
@@ -1180,9 +1180,14 @@ Carousel.propTypes = {
|
|
|
1180
1180
|
* An array of objects containing information on the thumbnails to be rendered as navigation panel
|
|
1181
1181
|
*/
|
|
1182
1182
|
thumbnails: PropTypes.arrayOf(PropTypes.shape({
|
|
1183
|
+
/** Accessibility label for the thumbnail image, used by assistive technologies. */
|
|
1183
1184
|
accessibilityLabel: PropTypes.string,
|
|
1185
|
+
/** Alternative text for the thumbnail image, displayed when the image cannot be rendered. */
|
|
1184
1186
|
alt: PropTypes.string,
|
|
1185
|
-
|
|
1187
|
+
/** When true, renders a play icon overlay on the thumbnail to indicate that the slide contains a video. */
|
|
1188
|
+
isVideo: PropTypes.bool,
|
|
1189
|
+
/** URL or path of the thumbnail image. When used with `isVideo`, this should be the video's poster/preview image. */
|
|
1190
|
+
src: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
|
1186
1191
|
})),
|
|
1187
1192
|
/**
|
|
1188
1193
|
* Minimal part of slide width must be swiped for changing index.
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
3
4
|
import Pressable from "react-native-web/dist/exports/Pressable";
|
|
4
5
|
import Image from "react-native-web/dist/exports/Image";
|
|
6
|
+
import View from "react-native-web/dist/exports/View";
|
|
5
7
|
import { useCarousel } from './CarouselContext';
|
|
6
8
|
import { useThemeTokensCallback } from '../ThemeProvider/useThemeTokens';
|
|
7
9
|
import { useViewport } from '../ViewportProvider/useViewport';
|
|
8
|
-
import {
|
|
10
|
+
import { Icon } from '../Icon/Icon';
|
|
11
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
9
12
|
const selectPressableTokens = _ref => {
|
|
10
13
|
let {
|
|
11
14
|
borderColor,
|
|
@@ -23,17 +26,64 @@ const selectPressableTokens = _ref => {
|
|
|
23
26
|
};
|
|
24
27
|
};
|
|
25
28
|
|
|
29
|
+
// Play icon overlay appearance is consistent across all brands and is not theme-configurable.
|
|
30
|
+
// The circle occupies 55% of the thumbnail size, and the icon occupies 55% of the circle diameter.
|
|
31
|
+
const PLAY_ICON_RATIO = 0.55;
|
|
32
|
+
const PLAY_ICON_BORDER_RADIUS_DIVISOR = 2;
|
|
33
|
+
const selectImageStyles = size => ({
|
|
34
|
+
width: size,
|
|
35
|
+
height: size
|
|
36
|
+
});
|
|
37
|
+
const selectSelectedStyles = _ref2 => {
|
|
38
|
+
let {
|
|
39
|
+
selectedBorderColor,
|
|
40
|
+
selectedBorderWidth,
|
|
41
|
+
padding,
|
|
42
|
+
margin
|
|
43
|
+
} = _ref2;
|
|
44
|
+
return {
|
|
45
|
+
borderColor: selectedBorderColor,
|
|
46
|
+
borderWidth: selectedBorderWidth,
|
|
47
|
+
padding: padding - selectedBorderWidth,
|
|
48
|
+
marginBottom: margin + selectedBorderWidth
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const selectNonSelectedStyles = _ref3 => {
|
|
52
|
+
let {
|
|
53
|
+
borderWidth,
|
|
54
|
+
padding,
|
|
55
|
+
margin,
|
|
56
|
+
selectedBorderWidth
|
|
57
|
+
} = _ref3;
|
|
58
|
+
return {
|
|
59
|
+
padding: padding - borderWidth,
|
|
60
|
+
marginBottom: margin + selectedBorderWidth
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
const selectPlayIconCircleStyles = thumbnailSize => {
|
|
64
|
+
const diameter = thumbnailSize * PLAY_ICON_RATIO;
|
|
65
|
+
return {
|
|
66
|
+
width: diameter,
|
|
67
|
+
height: diameter,
|
|
68
|
+
borderRadius: diameter / PLAY_ICON_BORDER_RADIUS_DIVISOR
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
const selectPlayIconTokens = thumbnailSize => ({
|
|
72
|
+
size: thumbnailSize * PLAY_ICON_RATIO * PLAY_ICON_RATIO
|
|
73
|
+
});
|
|
74
|
+
|
|
26
75
|
/**
|
|
27
|
-
* `
|
|
76
|
+
* `CarouselThumbnail` is used to wrap the content of an individual slide and is suppsoed to be the
|
|
28
77
|
* only top-level component passed to the `Carousel`
|
|
29
78
|
*/
|
|
30
|
-
export const CarouselThumbnail = /*#__PURE__*/React.forwardRef((
|
|
79
|
+
export const CarouselThumbnail = /*#__PURE__*/React.forwardRef((_ref4, ref) => {
|
|
31
80
|
let {
|
|
32
81
|
accessibilityLabel,
|
|
33
82
|
alt,
|
|
34
83
|
index,
|
|
84
|
+
isVideo,
|
|
35
85
|
src
|
|
36
|
-
} =
|
|
86
|
+
} = _ref4;
|
|
37
87
|
const {
|
|
38
88
|
activeIndex,
|
|
39
89
|
itemLabel,
|
|
@@ -55,58 +105,100 @@ export const CarouselThumbnail = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
55
105
|
selectedBorderColor,
|
|
56
106
|
selectedBorderWidth,
|
|
57
107
|
size,
|
|
58
|
-
margin
|
|
108
|
+
margin,
|
|
109
|
+
playIcon
|
|
59
110
|
} = getThumbnailTokens({
|
|
60
111
|
viewport
|
|
61
112
|
});
|
|
62
|
-
const styles = {
|
|
63
|
-
image: {
|
|
64
|
-
height: size,
|
|
65
|
-
width: size
|
|
66
|
-
},
|
|
67
|
-
selected: {
|
|
68
|
-
borderColor: selectedBorderColor,
|
|
69
|
-
borderWidth: selectedBorderWidth,
|
|
70
|
-
padding: padding - selectedBorderWidth,
|
|
71
|
-
marginBottom: margin + selectedBorderWidth
|
|
72
|
-
},
|
|
73
|
-
nonSelected: {
|
|
74
|
-
padding: padding - borderWidth,
|
|
75
|
-
marginBottom: margin + selectedBorderWidth
|
|
76
|
-
}
|
|
77
|
-
};
|
|
78
113
|
return /*#__PURE__*/_jsx(Pressable, {
|
|
79
114
|
onKeyDown: handleKeyDown,
|
|
80
115
|
onPress: handlePress,
|
|
81
|
-
style:
|
|
116
|
+
style: _ref5 => {
|
|
82
117
|
let {
|
|
83
118
|
hovered,
|
|
84
119
|
pressed,
|
|
85
120
|
focused
|
|
86
|
-
} =
|
|
121
|
+
} = _ref5;
|
|
87
122
|
const pressableStyles = selectPressableTokens(getThumbnailTokens({
|
|
88
123
|
hover: hovered,
|
|
89
124
|
pressed,
|
|
90
125
|
focus: focused
|
|
91
126
|
}));
|
|
92
|
-
return [pressableStyles, index === activeIndex ? [
|
|
93
|
-
|
|
94
|
-
|
|
127
|
+
return [pressableStyles, index === activeIndex ? [selectSelectedStyles({
|
|
128
|
+
selectedBorderColor,
|
|
129
|
+
selectedBorderWidth,
|
|
130
|
+
padding,
|
|
131
|
+
margin
|
|
132
|
+
}), staticStyles.selectedPressableOutline] : selectNonSelectedStyles({
|
|
133
|
+
borderWidth,
|
|
134
|
+
padding,
|
|
135
|
+
margin,
|
|
136
|
+
selectedBorderWidth
|
|
137
|
+
})];
|
|
95
138
|
},
|
|
96
139
|
ref: ref,
|
|
97
|
-
children: /*#__PURE__*/
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
140
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
141
|
+
style: [staticStyles.imageContainer, selectImageStyles(size)],
|
|
142
|
+
children: [/*#__PURE__*/_jsx(Image, {
|
|
143
|
+
accessibilityIgnoresInvertColors: true,
|
|
144
|
+
accessibilityLabel: accessibilityLabel ?? alt,
|
|
145
|
+
source: src,
|
|
146
|
+
style: selectImageStyles(size),
|
|
147
|
+
title: thumbnailTitle
|
|
148
|
+
}), isVideo && playIcon && /*#__PURE__*/_jsx(View, {
|
|
149
|
+
style: staticStyles.playIconOverlayContainer,
|
|
150
|
+
testID: `play-icon-overlay-${index}`,
|
|
151
|
+
children: /*#__PURE__*/_jsx(View, {
|
|
152
|
+
style: [selectPlayIconCircleStyles(size), staticStyles.playIconCircleBackground],
|
|
153
|
+
children: /*#__PURE__*/_jsx(Icon, {
|
|
154
|
+
icon: playIcon,
|
|
155
|
+
tokens: {
|
|
156
|
+
...selectPlayIconTokens(size),
|
|
157
|
+
color: staticStyles.playIconSymbol.color
|
|
158
|
+
}
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
})]
|
|
103
162
|
})
|
|
104
163
|
}, src);
|
|
105
164
|
});
|
|
106
165
|
CarouselThumbnail.displayName = 'CarouselThumbnail';
|
|
107
166
|
CarouselThumbnail.propTypes = {
|
|
167
|
+
/** Accessibility label for screen readers, overrides the alt text */
|
|
108
168
|
accessibilityLabel: PropTypes.string,
|
|
169
|
+
/** Alt text for the thumbnail image */
|
|
109
170
|
alt: PropTypes.string,
|
|
171
|
+
/** Zero-based index of this thumbnail within the carousel */
|
|
110
172
|
index: PropTypes.number,
|
|
111
|
-
|
|
112
|
-
|
|
173
|
+
/**
|
|
174
|
+
* When true, renders a play icon overlay on the thumbnail to indicate that the slide contains a video.
|
|
175
|
+
*/
|
|
176
|
+
isVideo: PropTypes.bool,
|
|
177
|
+
/** Image source URI (web) or local asset require() (native) */
|
|
178
|
+
src: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
|
179
|
+
};
|
|
180
|
+
const staticStyles = StyleSheet.create({
|
|
181
|
+
imageContainer: {
|
|
182
|
+
position: 'relative'
|
|
183
|
+
},
|
|
184
|
+
playIconOverlayContainer: {
|
|
185
|
+
position: 'absolute',
|
|
186
|
+
top: 0,
|
|
187
|
+
left: 0,
|
|
188
|
+
right: 0,
|
|
189
|
+
bottom: 0,
|
|
190
|
+
justifyContent: 'center',
|
|
191
|
+
alignItems: 'center'
|
|
192
|
+
},
|
|
193
|
+
selectedPressableOutline: {
|
|
194
|
+
outlineStyle: 'none'
|
|
195
|
+
},
|
|
196
|
+
playIconCircleBackground: {
|
|
197
|
+
backgroundColor: 'rgba(0, 0, 0, 0.6)',
|
|
198
|
+
justifyContent: 'center',
|
|
199
|
+
alignItems: 'center'
|
|
200
|
+
},
|
|
201
|
+
playIconSymbol: {
|
|
202
|
+
color: 'rgb(255, 255, 255)'
|
|
203
|
+
}
|
|
204
|
+
});
|
|
@@ -45,12 +45,14 @@ export const CarouselThumbnailNavigation = /*#__PURE__*/React.forwardRef((_ref,
|
|
|
45
45
|
let {
|
|
46
46
|
accessibilityLabel,
|
|
47
47
|
alt,
|
|
48
|
+
isVideo,
|
|
48
49
|
src
|
|
49
50
|
} = _ref2;
|
|
50
51
|
return /*#__PURE__*/_jsx(CarouselThumbnail, {
|
|
51
52
|
accessibilityLabel: accessibilityLabel,
|
|
52
53
|
alt: alt,
|
|
53
54
|
index: index,
|
|
55
|
+
isVideo: isVideo,
|
|
54
56
|
src: src
|
|
55
57
|
}, src);
|
|
56
58
|
})
|
|
@@ -63,8 +65,13 @@ CarouselThumbnailNavigation.propTypes = {
|
|
|
63
65
|
* An array of objects containing information on the thumbnail images.
|
|
64
66
|
*/
|
|
65
67
|
thumbnails: PropTypes.arrayOf(PropTypes.shape({
|
|
68
|
+
/** Accessibility label for the thumbnail image, used by assistive technologies. */
|
|
66
69
|
accessibilityLabel: PropTypes.string,
|
|
70
|
+
/** Alternative text for the thumbnail image, displayed when the image cannot be rendered. */
|
|
67
71
|
alt: PropTypes.string,
|
|
68
|
-
|
|
72
|
+
/** When true, renders a play icon overlay on the thumbnail to indicate that the slide contains a video. */
|
|
73
|
+
isVideo: PropTypes.bool,
|
|
74
|
+
/** URL or path of the thumbnail image. When used with `isVideo`, this should be the video's poster/preview image. */
|
|
75
|
+
src: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
|
|
69
76
|
})).isRequired
|
|
70
77
|
};
|
|
@@ -15,28 +15,28 @@ import { applyTextStyles } from '../ThemeProvider/utils/styles';
|
|
|
15
15
|
import { useThemeTokens } from '../ThemeProvider/useThemeTokens';
|
|
16
16
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
17
17
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs, viewProps]);
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const HALF_FONT_SIZE = 2;
|
|
19
|
+
const QUARTER_FONT_SIZE = 4;
|
|
20
|
+
const DEFAULT_LINE_HEIGHT = 1;
|
|
21
|
+
const LINE_HEIGHT_MULTIPLIER = 2;
|
|
20
22
|
const selectTextStyle = _ref => {
|
|
21
23
|
let {
|
|
22
24
|
fontSize,
|
|
23
25
|
lineHeight
|
|
24
26
|
} = _ref;
|
|
25
|
-
return {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
})
|
|
39
|
-
};
|
|
27
|
+
return Platform.select({
|
|
28
|
+
native: {
|
|
29
|
+
fontSize: fontSize / HALF_FONT_SIZE,
|
|
30
|
+
lineHeight: fontSize,
|
|
31
|
+
position: 'relative',
|
|
32
|
+
top: -(fontSize * lineHeight) / HALF_FONT_SIZE
|
|
33
|
+
},
|
|
34
|
+
web: {
|
|
35
|
+
fontSize,
|
|
36
|
+
lineHeight: lineHeight !== DEFAULT_LINE_HEIGHT ? lineHeight : fontSize * LINE_HEIGHT_MULTIPLIER,
|
|
37
|
+
top: -fontSize / QUARTER_FONT_SIZE
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
40
|
};
|
|
41
41
|
export const FootnoteLink = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
42
42
|
let {
|
|
@@ -80,6 +80,7 @@ export const FootnoteLink = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
|
|
|
80
80
|
});
|
|
81
81
|
});
|
|
82
82
|
FootnoteLink.displayName = 'FootnoteLink';
|
|
83
|
+
FootnoteLink.__UDS_COMPONENT_NAME__ = 'FootnoteLink';
|
|
83
84
|
const copyShape = PropTypes.shape({
|
|
84
85
|
a11yLabel: PropTypes.string.isRequired
|
|
85
86
|
});
|
|
@@ -66,8 +66,7 @@ export const InputSupports = /*#__PURE__*/React.forwardRef((_ref, ref) => {
|
|
|
66
66
|
}), typeof children === 'function' ? children({
|
|
67
67
|
inputId,
|
|
68
68
|
...a11yProps,
|
|
69
|
-
validation: feedbackValidation
|
|
70
|
-
accessibilityDescribedBy: feedbackId
|
|
69
|
+
validation: feedbackValidation
|
|
71
70
|
}) : children, feedback || maxCharsReachedErrorMessage ? /*#__PURE__*/_jsx(Feedback, {
|
|
72
71
|
id: feedbackId,
|
|
73
72
|
title: feedback || maxCharsReachedErrorMessage,
|