@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.
Files changed (82) hide show
  1. package/CHANGELOG.md +62 -6
  2. package/jest.config.cjs +1 -0
  3. package/lib/cjs/ActionCard/ActionCard.js +10 -3
  4. package/lib/cjs/Card/Card.js +3 -3
  5. package/lib/cjs/Carousel/Carousel.js +6 -1
  6. package/lib/cjs/Carousel/CarouselThumbnail.js +125 -33
  7. package/lib/cjs/Carousel/CarouselThumbnailNavigation.js +8 -1
  8. package/lib/cjs/Footnote/FootnoteLink.js +18 -17
  9. package/lib/cjs/InputSupports/InputSupports.js +1 -2
  10. package/lib/cjs/InputSupports/useInputSupports.js +1 -3
  11. package/lib/cjs/Link/ChevronLink.js +1 -2
  12. package/lib/cjs/Notification/Notification.js +4 -12
  13. package/lib/cjs/Progress/Progress.js +30 -5
  14. package/lib/cjs/Progress/ProgressBar.js +3 -3
  15. package/lib/cjs/Progress/ProgressBarBackground.js +2 -3
  16. package/lib/cjs/QuickLinks/QuickLinks.js +7 -0
  17. package/lib/cjs/Scroll/Scroll.js +472 -0
  18. package/lib/cjs/Scroll/ScrollContext.js +55 -0
  19. package/lib/cjs/Scroll/ScrollItem.js +106 -0
  20. package/lib/cjs/Scroll/ScrollProgress.js +100 -0
  21. package/lib/cjs/Scroll/dictionary.js +18 -0
  22. package/lib/cjs/StackView/StackWrapBox.js +9 -1
  23. package/lib/cjs/StackView/StackWrapGap.js +3 -1
  24. package/lib/cjs/StackView/getStackedContent.js +20 -10
  25. package/lib/cjs/index.js +14 -0
  26. package/lib/cjs/utils/animation/useAnimatedValue.js +46 -0
  27. package/lib/cjs/utils/children.js +2 -1
  28. package/lib/esm/ActionCard/ActionCard.js +10 -3
  29. package/lib/esm/Card/Card.js +3 -3
  30. package/lib/esm/Carousel/Carousel.js +6 -1
  31. package/lib/esm/Carousel/CarouselThumbnail.js +126 -34
  32. package/lib/esm/Carousel/CarouselThumbnailNavigation.js +8 -1
  33. package/lib/esm/Footnote/FootnoteLink.js +18 -17
  34. package/lib/esm/InputSupports/InputSupports.js +1 -2
  35. package/lib/esm/InputSupports/useInputSupports.js +1 -3
  36. package/lib/esm/Link/ChevronLink.js +1 -2
  37. package/lib/esm/Notification/Notification.js +4 -12
  38. package/lib/esm/Progress/Progress.js +30 -5
  39. package/lib/esm/Progress/ProgressBar.js +3 -3
  40. package/lib/esm/Progress/ProgressBarBackground.js +2 -3
  41. package/lib/esm/QuickLinks/QuickLinks.js +7 -0
  42. package/lib/esm/Scroll/Scroll.js +465 -0
  43. package/lib/esm/Scroll/ScrollContext.js +46 -0
  44. package/lib/esm/Scroll/ScrollItem.js +100 -0
  45. package/lib/esm/Scroll/ScrollProgress.js +93 -0
  46. package/lib/esm/Scroll/dictionary.js +12 -0
  47. package/lib/esm/StackView/StackWrapBox.js +9 -1
  48. package/lib/esm/StackView/StackWrapGap.js +3 -1
  49. package/lib/esm/StackView/getStackedContent.js +20 -10
  50. package/lib/esm/index.js +2 -0
  51. package/lib/esm/utils/animation/useAnimatedValue.js +38 -0
  52. package/lib/esm/utils/children.js +2 -1
  53. package/lib/package.json +2 -2
  54. package/package.json +2 -2
  55. package/src/ActionCard/ActionCard.jsx +13 -4
  56. package/src/Card/Card.jsx +3 -3
  57. package/src/Carousel/Carousel.jsx +6 -1
  58. package/src/Carousel/CarouselThumbnail.jsx +117 -30
  59. package/src/Carousel/CarouselThumbnailNavigation.jsx +8 -2
  60. package/src/Footnote/FootnoteLink.jsx +17 -12
  61. package/src/InputSupports/InputSupports.jsx +1 -6
  62. package/src/InputSupports/useInputSupports.js +1 -1
  63. package/src/Link/ChevronLink.jsx +1 -2
  64. package/src/Notification/Notification.jsx +5 -21
  65. package/src/Progress/Progress.jsx +22 -3
  66. package/src/Progress/ProgressBar.jsx +3 -3
  67. package/src/Progress/ProgressBarBackground.jsx +2 -3
  68. package/src/QuickLinks/QuickLinks.jsx +8 -0
  69. package/src/Scroll/Scroll.jsx +483 -0
  70. package/src/Scroll/ScrollContext.jsx +39 -0
  71. package/src/Scroll/ScrollItem.jsx +87 -0
  72. package/src/Scroll/ScrollProgress.jsx +74 -0
  73. package/src/Scroll/dictionary.js +12 -0
  74. package/src/StackView/StackWrapBox.jsx +13 -1
  75. package/src/StackView/StackWrapGap.jsx +2 -1
  76. package/src/StackView/getStackedContent.jsx +22 -8
  77. package/src/index.js +2 -0
  78. package/src/utils/animation/useAnimatedValue.js +35 -0
  79. package/src/utils/children.jsx +4 -1
  80. package/types/Link.d.ts +1 -2
  81. package/types/Scroll.d.ts +66 -0
  82. package/types/index.d.ts +9 -0
@@ -0,0 +1,46 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { jsx as _jsx } from "react/jsx-runtime";
4
+ const ScrollContext = /*#__PURE__*/React.createContext();
5
+ export const ScrollProvider = _ref => {
6
+ let {
7
+ children,
8
+ itemWidth,
9
+ itemHeight,
10
+ onItemLayout
11
+ } = _ref;
12
+ const value = React.useMemo(() => ({
13
+ itemWidth,
14
+ itemHeight,
15
+ onItemLayout
16
+ }), [itemWidth, itemHeight, onItemLayout]);
17
+ return /*#__PURE__*/_jsx(ScrollContext.Provider, {
18
+ value: value,
19
+ children: children
20
+ });
21
+ };
22
+ export function useScroll() {
23
+ const context = React.useContext(ScrollContext);
24
+ if (context === undefined) {
25
+ throw new Error(`'useScroll' must be used within a 'ScrollProvider'`);
26
+ }
27
+ return context;
28
+ }
29
+ ScrollProvider.propTypes = {
30
+ /**
31
+ * Content to be rendered within the scroll context provider.
32
+ */
33
+ children: PropTypes.node.isRequired,
34
+ /**
35
+ * Width of each scroll item in pixels.
36
+ */
37
+ itemWidth: PropTypes.number.isRequired,
38
+ /**
39
+ * Height of each scroll item in pixels.
40
+ */
41
+ itemHeight: PropTypes.number.isRequired,
42
+ /**
43
+ * Callback invoked when a scroll item layout is measured.
44
+ */
45
+ onItemLayout: PropTypes.func.isRequired
46
+ };
@@ -0,0 +1,100 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import Platform from "react-native-web/dist/exports/Platform";
4
+ import View from "react-native-web/dist/exports/View";
5
+ import { a11yProps } from '../utils/props/a11yProps';
6
+ import { selectSystemProps } from '../utils/props/selectSystemProps';
7
+ import { viewProps } from '../utils/props/viewProps';
8
+ import { layoutTags, getA11yPropsFromHtmlTag } from '../utils/a11y/semantics';
9
+ import { useScroll } from './ScrollContext';
10
+ import { jsx as _jsx } from "react/jsx-runtime";
11
+ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
12
+ const DEFAULT_TAG = 'li';
13
+ const DATA_SCROLL_ITEM = 'scrollItem';
14
+ const INITIAL_DIMENSION = 0;
15
+ const TAB_INDEX = 0;
16
+ const selectContainerStyle = _ref => {
17
+ let {
18
+ itemWidth,
19
+ itemHeight
20
+ } = _ref;
21
+ const style = {};
22
+ if (itemWidth > INITIAL_DIMENSION) {
23
+ style.width = itemWidth;
24
+ }
25
+ if (itemHeight > INITIAL_DIMENSION) {
26
+ style.height = itemHeight;
27
+ }
28
+ return style;
29
+ };
30
+
31
+ /**
32
+ * The `ScrollItem` component wraps individual items within a `Scroll` container. Each item
33
+ * is individually focusable and reports its natural dimensions so the parent can apply uniform
34
+ * sizing across all items.
35
+ *
36
+ * ## Props
37
+ *
38
+ * - Use `children` to provide the content of the scroll item
39
+ * - Use `tag` to set the HTML tag of the outer container (defaults to `'li'`)
40
+ *
41
+ */
42
+ const ScrollItem = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
43
+ let {
44
+ children,
45
+ tag = DEFAULT_TAG,
46
+ ...rest
47
+ } = _ref2;
48
+ const {
49
+ itemWidth,
50
+ itemHeight,
51
+ onItemLayout
52
+ } = useScroll();
53
+ const handleLayout = React.useCallback(_ref3 => {
54
+ let {
55
+ nativeEvent: {
56
+ layout: {
57
+ width,
58
+ height
59
+ }
60
+ }
61
+ } = _ref3;
62
+ onItemLayout?.(width, height);
63
+ }, [onItemLayout]);
64
+ const selectedProps = selectProps({
65
+ ...rest,
66
+ ...getA11yPropsFromHtmlTag(tag, rest.accessibilityRole)
67
+ });
68
+ return /*#__PURE__*/_jsx(View, {
69
+ ref: ref,
70
+ style: selectContainerStyle({
71
+ itemWidth,
72
+ itemHeight
73
+ }),
74
+ onLayout: handleLayout,
75
+ dataSet: {
76
+ [DATA_SCROLL_ITEM]: true
77
+ },
78
+ ...(Platform.OS === 'web' ? {
79
+ tabIndex: TAB_INDEX
80
+ } : {
81
+ focusable: true
82
+ }),
83
+ ...selectedProps,
84
+ children: children
85
+ });
86
+ });
87
+ ScrollItem.displayName = 'ScrollItem';
88
+ ScrollItem.propTypes = {
89
+ ...selectedSystemPropTypes,
90
+ /**
91
+ * Content of the scroll item
92
+ */
93
+ children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]).isRequired,
94
+ /**
95
+ * Sets the HTML tag of the outer container. Defaults to `'li'`.
96
+ */
97
+ tag: PropTypes.oneOf(layoutTags)
98
+ };
99
+ const MemoizedScrollItem = /*#__PURE__*/React.memo(ScrollItem);
100
+ export { MemoizedScrollItem as ScrollItem };
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import View from "react-native-web/dist/exports/View";
4
+ import { resolvePressableState } from '../utils/pressability';
5
+ import { useAnimatedValue } from '../utils/animation/useAnimatedValue';
6
+ import { Progress } from '../Progress/Progress';
7
+ import { ProgressBar } from '../Progress/ProgressBar';
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ const MAX_PERCENTAGE = 100;
10
+ const BORDER_RADIUS_DIVISOR = 2;
11
+ const staticProgressTokens = {
12
+ borderWidth: 0,
13
+ borderColor: 'transparent'
14
+ };
15
+ const staticProgressBarTokens = {
16
+ gradient: null,
17
+ outlineWidth: 0
18
+ };
19
+ const selectProgressTokens = _ref => {
20
+ let {
21
+ progressTrackHeight,
22
+ progressBarHeight,
23
+ progressTrackColor
24
+ } = _ref;
25
+ return {
26
+ height: progressTrackHeight,
27
+ barHeight: progressBarHeight,
28
+ backgroundColor: progressTrackColor,
29
+ borderRadius: progressTrackHeight / BORDER_RADIUS_DIVISOR
30
+ };
31
+ };
32
+ const selectBarTokens = _ref2 => {
33
+ let {
34
+ progressBarColor,
35
+ progressBarHeight
36
+ } = _ref2;
37
+ return {
38
+ backgroundColor: progressBarColor,
39
+ borderRadius: progressBarHeight / BORDER_RADIUS_DIVISOR
40
+ };
41
+ };
42
+ export const ScrollProgress = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
43
+ let {
44
+ pressableState,
45
+ getTokens,
46
+ thumbWrapperStyle,
47
+ getCopy
48
+ } = _ref3;
49
+ const state = resolvePressableState(pressableState);
50
+ const themeTokens = getTokens(state);
51
+ const animatedBarHeight = useAnimatedValue(themeTokens.progressBarHeight);
52
+ const animatedTokens = {
53
+ ...themeTokens,
54
+ progressBarHeight: animatedBarHeight
55
+ };
56
+ return /*#__PURE__*/_jsx(Progress, {
57
+ tokens: {
58
+ ...staticProgressTokens,
59
+ ...selectProgressTokens(animatedTokens)
60
+ },
61
+ children: /*#__PURE__*/_jsx(View, {
62
+ ref: ref,
63
+ style: thumbWrapperStyle,
64
+ children: /*#__PURE__*/_jsx(ProgressBar, {
65
+ percentage: MAX_PERCENTAGE,
66
+ tokens: {
67
+ ...staticProgressBarTokens,
68
+ ...selectBarTokens(animatedTokens)
69
+ },
70
+ accessibilityLabel: getCopy('progressBarLabel')
71
+ })
72
+ })
73
+ });
74
+ });
75
+ ScrollProgress.displayName = 'ScrollProgress';
76
+ ScrollProgress.propTypes = {
77
+ /**
78
+ * State object from Pressable's render callback containing hovered, pressed, and focused states
79
+ */
80
+ pressableState: PropTypes.object.isRequired,
81
+ /**
82
+ * Theme token resolver callback from useThemeTokensCallback that accepts appearance state
83
+ */
84
+ getTokens: PropTypes.func.isRequired,
85
+ /**
86
+ * Style array for the thumb wrapper containing static and dynamic position styles
87
+ */
88
+ thumbWrapperStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]).isRequired,
89
+ /**
90
+ * Copy resolver function from useCopy for retrieving localized strings
91
+ */
92
+ getCopy: PropTypes.func.isRequired
93
+ };
@@ -0,0 +1,12 @@
1
+ export const dictionary = {
2
+ en: {
3
+ accessibilityLabel: 'Scrollable content',
4
+ instructionText: 'Use Tab, arrow keys, or space bar to navigate',
5
+ progressBarLabel: 'Scroll position'
6
+ },
7
+ fr: {
8
+ accessibilityLabel: 'Contenu défilable',
9
+ instructionText: "Utilisez Tab, les touches fléchées ou la barre d'espace pour naviguer",
10
+ progressBarLabel: 'Position de défilement'
11
+ }
12
+ };
@@ -51,6 +51,7 @@ export const StackWrapBox = /*#__PURE__*/React.forwardRef((_ref, ref) => {
51
51
  variant,
52
52
  tag,
53
53
  accessibilityRole,
54
+ itemAccessibilityRole,
54
55
  ...rest
55
56
  } = _ref;
56
57
  const viewport = useViewport();
@@ -77,7 +78,8 @@ export const StackWrapBox = /*#__PURE__*/React.forwardRef((_ref, ref) => {
77
78
  const content = getStackedContent(children, {
78
79
  direction,
79
80
  space: 0,
80
- box: boxProps
81
+ box: boxProps,
82
+ itemAccessibilityRole
81
83
  });
82
84
  return /*#__PURE__*/_jsx(View, {
83
85
  ref: ref,
@@ -113,6 +115,12 @@ StackWrapBox.propTypes = {
113
115
  * is not defined, the accessibilityRole will default to "heading".
114
116
  */
115
117
  tag: PropTypes.oneOf(layoutTags),
118
+ /**
119
+ * Optional accessibility role to apply to each item in the stack.
120
+ * On web, items are wrapped (or cloned) with this role, enabling correct list semantics
121
+ * when the container tag is "ul" or "ol".
122
+ */
123
+ itemAccessibilityRole: PropTypes.string,
116
124
  /**
117
125
  * A StackWrap may take any children, but will have no effect if it is only passed one child or is passed children
118
126
  * wrapped in a component. If necessary, children may be wrapped in one React Fragment.
@@ -33,6 +33,7 @@ export const StackWrapGap = /*#__PURE__*/React.forwardRef((_ref, ref) => {
33
33
  children,
34
34
  tag,
35
35
  accessibilityRole,
36
+ itemAccessibilityRole,
36
37
  ...rest
37
38
  } = _ref;
38
39
  const viewport = useViewport();
@@ -52,7 +53,8 @@ export const StackWrapGap = /*#__PURE__*/React.forwardRef((_ref, ref) => {
52
53
  };
53
54
  const content = getStackedContent(children, {
54
55
  direction,
55
- space: 0
56
+ space: 0,
57
+ itemAccessibilityRole
56
58
  });
57
59
  return /*#__PURE__*/_jsx(View, {
58
60
  ref: ref,
@@ -36,7 +36,8 @@ export const getStackedContent = (children, _ref) => {
36
36
  space,
37
37
  direction = 'column',
38
38
  box,
39
- preserveFragments = false
39
+ preserveFragments = false,
40
+ itemAccessibilityRole
40
41
  } = _ref;
41
42
  const boxProps = box && typeof box === 'object' ? box : {
42
43
  space
@@ -48,15 +49,24 @@ export const getStackedContent = (children, _ref) => {
48
49
  const validChildren = React.Children.toArray(topLevelChildren).filter(Boolean);
49
50
  const content = validChildren.reduce((newChildren, child, index) => {
50
51
  const boxID = `Stack-Box-${index}`;
51
- const item = box ?
52
- /*#__PURE__*/
53
- // If wrapped in Box, that Box needs a key.
54
- // If possible, use an existing content key; use an index-based key only if necessary.
55
- _createElement(Box, {
56
- ...boxProps,
57
- key: child.key || boxID,
58
- testID: boxID
59
- }, child) : child;
52
+ let item;
53
+ if (box) {
54
+ // If wrapped in Box, that Box needs a key.
55
+ // If possible, use an existing content key; use an index-based key only if necessary.
56
+ item = /*#__PURE__*/_createElement(Box, {
57
+ ...boxProps,
58
+ accessibilityRole: itemAccessibilityRole,
59
+ key: child.key || boxID,
60
+ testID: boxID
61
+ }, child);
62
+ } else if (itemAccessibilityRole) {
63
+ item = /*#__PURE__*/React.cloneElement(child, {
64
+ accessibilityRole: itemAccessibilityRole,
65
+ key: child.key || boxID
66
+ });
67
+ } else {
68
+ item = child;
69
+ }
60
70
  if (!index || !space && !divider) return [...newChildren, item];
61
71
  const testID = `Stack-${divider ? 'Divider' : 'Spacer'}-${index}`;
62
72
  const commonProps = {
package/lib/esm/index.js CHANGED
@@ -73,6 +73,8 @@ export { RadioGroup } from './Radio/RadioGroup';
73
73
  export { RadioCard } from './RadioCard/RadioCard';
74
74
  export { RadioCardGroup } from './RadioCard/RadioCardGroup';
75
75
  export { Responsive } from './Responsive/Responsive';
76
+ export { Scroll } from './Scroll/Scroll';
77
+ export { ScrollItem } from './Scroll/ScrollItem';
76
78
  export { Search } from './Search/Search';
77
79
  export { Select } from './Select/Select';
78
80
  export { SelectItem } from './Select/SelectItem';
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import Animated from "react-native-web/dist/exports/Animated";
3
+ import Easing from "react-native-web/dist/exports/Easing";
4
+ const ANIMATION_DURATION = 200;
5
+
6
+ /**
7
+ * Smoothly animates a numeric value to a new target using a quadratic ease-in-out
8
+ * curve. Returns the current interpolated value as a plain number so
9
+ * consumers can use it in non-Animated style props.
10
+ *
11
+ * @param {number} targetValue - The value to animate towards.
12
+ * @param {number} [duration=ANIMATION_DURATION] - Animation duration in ms.
13
+ */
14
+ export const useAnimatedValue = function (targetValue) {
15
+ let duration = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ANIMATION_DURATION;
16
+ const [currentValue, setCurrentValue] = React.useState(targetValue);
17
+ const animatedValue = React.useRef(new Animated.Value(targetValue)).current;
18
+ React.useEffect(() => {
19
+ const id = animatedValue.addListener(_ref => {
20
+ let {
21
+ value
22
+ } = _ref;
23
+ return setCurrentValue(value);
24
+ });
25
+ return () => animatedValue.removeListener(id);
26
+ }, [animatedValue]);
27
+ React.useEffect(() => {
28
+ const animation = Animated.timing(animatedValue, {
29
+ toValue: targetValue,
30
+ duration,
31
+ easing: Easing.inOut(Easing.quad),
32
+ useNativeDriver: false
33
+ });
34
+ animation.start();
35
+ return () => animation.stop();
36
+ }, [targetValue, animatedValue, duration]);
37
+ return currentValue;
38
+ };
@@ -47,7 +47,8 @@ export const unpackFragment = child => {
47
47
  };
48
48
  const isStringOrNumber = child => typeof child === 'string' || typeof child === 'number';
49
49
  // Wrap an A11yText with neighouring text strings so it doesn't split them into multiple <Text>s
50
- const isWrapable = child => isStringOrNumber(child) || child.type === A11yText || child.type?.name === 'FootnoteLink';
50
+ // Check displayName first as it is explicitly set and reliable regardless of export style (named vs default)
51
+ const isWrapable = child => isStringOrNumber(child) || child.type === A11yText || child.type?.__UDS_COMPONENT_NAME__ === 'FootnoteLink';
51
52
  const combineKeys = childrenArray => childrenArray.reduce((newKey, child) => `${newKey}${child.key || ''}`, '');
52
53
 
53
54
  // Group wrappable children for one `<Text>` parent, merging adjacent text nodes
package/lib/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@react-native-picker/picker": "^2.11.4",
14
14
  "@telus-uds/system-constants": "^4.0.0-alpha.0",
15
- "@telus-uds/system-theme-tokens": "^5.0.0-alpha.0",
15
+ "@telus-uds/system-theme-tokens": "^5.0.0-alpha.2",
16
16
  "css-mediaquery": "^0.1.2",
17
17
  "expo-document-picker": "^14.0.8",
18
18
  "expo-linear-gradient": "^15.0.8",
@@ -81,6 +81,6 @@
81
81
  "standard-engine": {
82
82
  "skip": true
83
83
  },
84
- "version": "4.0.0-alpha.0",
84
+ "version": "4.0.0-alpha.2",
85
85
  "types": "types/index.d.ts"
86
86
  }
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@react-native-picker/picker": "^2.11.4",
14
14
  "@telus-uds/system-constants": "^4.0.0-alpha.0",
15
- "@telus-uds/system-theme-tokens": "^5.0.0-alpha.0",
15
+ "@telus-uds/system-theme-tokens": "^5.0.0-alpha.2",
16
16
  "css-mediaquery": "^0.1.2",
17
17
  "expo-document-picker": "^14.0.8",
18
18
  "expo-linear-gradient": "^15.0.8",
@@ -81,6 +81,6 @@
81
81
  "standard-engine": {
82
82
  "skip": true
83
83
  },
84
- "version": "4.0.0-alpha.0",
84
+ "version": "4.0.0-alpha.2",
85
85
  "types": "types/index.d.ts"
86
86
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react'
2
- import { Animated, View, StyleSheet, Text } from 'react-native'
2
+ import { Animated, View, StyleSheet } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
4
 
5
5
  import { a11yProps } from '../utils/props/a11yProps'
@@ -200,14 +200,16 @@ export const ActionCard = React.forwardRef(
200
200
  <View style={staticStyles.content}>
201
201
  <View style={staticStyles.header}>
202
202
  <View style={[selectTitleStyles(themeTokens), staticStyles.title]}>
203
- <Text>
204
- {wrapStringsInText(title, { style: selectTitleTextStyles(themeTokens) })}
203
+ <View style={staticStyles.titleRow}>
204
+ {wrapStringsInText(title, {
205
+ style: [selectTitleTextStyles(themeTokens), staticStyles.titleText]
206
+ })}
205
207
  {themeTokens.statusIcon && (
206
208
  <View style={staticStyles.statusIcon}>
207
209
  <Icon {...selectStatusIconProps(themeTokens)} />
208
210
  </View>
209
211
  )}
210
- </Text>
212
+ </View>
211
213
  </View>
212
214
  <View style={staticStyles.icons}>
213
215
  {direction && (
@@ -297,6 +299,13 @@ const staticStyles = StyleSheet.create({
297
299
  title: {
298
300
  flexShrink: 1
299
301
  },
302
+ titleRow: {
303
+ flexDirection: 'row',
304
+ alignItems: 'center'
305
+ },
306
+ titleText: {
307
+ flexShrink: 1
308
+ },
300
309
  statusIcon: {
301
310
  marginLeft: 4
302
311
  }
package/src/Card/Card.jsx CHANGED
@@ -67,10 +67,10 @@ const getInputProps = ({
67
67
  *
68
68
  * ## Component API
69
69
  *
70
- * ### Background
70
+ * ### Style
71
71
  *
72
- * In order to control the background of a card, the following tokens are currently
73
- * supported:
72
+ * In order to control the style of a card, use the `style` variant.
73
+ * The following tokens are supported:
74
74
  *
75
75
  * - `backgroundColor`
76
76
  *
@@ -1400,9 +1400,14 @@ Carousel.propTypes = {
1400
1400
  */
1401
1401
  thumbnails: PropTypes.arrayOf(
1402
1402
  PropTypes.shape({
1403
+ /** Accessibility label for the thumbnail image, used by assistive technologies. */
1403
1404
  accessibilityLabel: PropTypes.string,
1405
+ /** Alternative text for the thumbnail image, displayed when the image cannot be rendered. */
1404
1406
  alt: PropTypes.string,
1405
- src: PropTypes.string
1407
+ /** When true, renders a play icon overlay on the thumbnail to indicate that the slide contains a video. */
1408
+ isVideo: PropTypes.bool,
1409
+ /** URL or path of the thumbnail image. When used with `isVideo`, this should be the video's poster/preview image. */
1410
+ src: PropTypes.oneOfType([PropTypes.string, PropTypes.number])
1406
1411
  })
1407
1412
  ),
1408
1413
  /**