@telus-uds/components-base 3.26.0 → 3.27.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 (42) hide show
  1. package/CHANGELOG.md +19 -2
  2. package/lib/cjs/Card/Card.js +34 -13
  3. package/lib/cjs/Card/CardBase.js +78 -11
  4. package/lib/cjs/Card/PressableCardBase.js +147 -8
  5. package/lib/cjs/Carousel/Carousel.js +105 -50
  6. package/lib/cjs/Carousel/CarouselContext.js +10 -4
  7. package/lib/cjs/Carousel/CarouselItem/CarouselItem.js +11 -7
  8. package/lib/cjs/Carousel/Constants.js +11 -2
  9. package/lib/cjs/Checkbox/Checkbox.js +43 -13
  10. package/lib/cjs/List/List.js +24 -9
  11. package/lib/cjs/List/ListItem.js +18 -1
  12. package/lib/cjs/List/ListItemBase.js +27 -8
  13. package/lib/cjs/List/ListItemMark.js +33 -62
  14. package/lib/cjs/List/PressableListItemBase.js +1 -0
  15. package/lib/esm/Card/Card.js +34 -13
  16. package/lib/esm/Card/CardBase.js +78 -11
  17. package/lib/esm/Card/PressableCardBase.js +148 -9
  18. package/lib/esm/Carousel/Carousel.js +106 -51
  19. package/lib/esm/Carousel/CarouselContext.js +10 -4
  20. package/lib/esm/Carousel/CarouselItem/CarouselItem.js +11 -7
  21. package/lib/esm/Carousel/Constants.js +10 -1
  22. package/lib/esm/Checkbox/Checkbox.js +43 -13
  23. package/lib/esm/List/List.js +24 -9
  24. package/lib/esm/List/ListItem.js +19 -2
  25. package/lib/esm/List/ListItemBase.js +27 -8
  26. package/lib/esm/List/ListItemMark.js +33 -62
  27. package/lib/esm/List/PressableListItemBase.js +1 -0
  28. package/lib/package.json +2 -2
  29. package/package.json +2 -2
  30. package/src/Card/Card.jsx +29 -7
  31. package/src/Card/CardBase.jsx +88 -8
  32. package/src/Card/PressableCardBase.jsx +135 -9
  33. package/src/Carousel/Carousel.jsx +119 -64
  34. package/src/Carousel/CarouselContext.jsx +12 -4
  35. package/src/Carousel/CarouselItem/CarouselItem.jsx +10 -6
  36. package/src/Carousel/Constants.js +10 -0
  37. package/src/Checkbox/Checkbox.jsx +29 -7
  38. package/src/List/List.jsx +33 -9
  39. package/src/List/ListItem.jsx +33 -11
  40. package/src/List/ListItemBase.jsx +33 -9
  41. package/src/List/ListItemMark.jsx +32 -53
  42. package/src/List/PressableListItemBase.jsx +1 -0
@@ -114,6 +114,32 @@ const selectFeedbackTokens = _ref5 => {
114
114
  feedbackMarginTop
115
115
  };
116
116
  };
117
+ const selectPressableStyles = _ref6 => {
118
+ let {
119
+ padding,
120
+ paddingLeft,
121
+ paddingRight,
122
+ paddingTop,
123
+ paddingBottom
124
+ } = _ref6;
125
+ return {
126
+ padding,
127
+ paddingLeft,
128
+ paddingRight,
129
+ paddingTop,
130
+ paddingBottom
131
+ };
132
+ };
133
+ const selectContainerStyles = _ref7 => {
134
+ let {
135
+ iconContainerHeight,
136
+ iconContainerWidth
137
+ } = _ref7;
138
+ return {
139
+ height: iconContainerHeight,
140
+ width: iconContainerWidth
141
+ };
142
+ };
117
143
 
118
144
  /**
119
145
  * Basic Checkbox component.
@@ -150,7 +176,7 @@ const selectFeedbackTokens = _ref5 => {
150
176
  * or the internal state in case of uncontrolled checkbox.
151
177
  *
152
178
  */
153
- const Checkbox = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
179
+ const Checkbox = /*#__PURE__*/React.forwardRef((_ref8, ref) => {
154
180
  let {
155
181
  checked,
156
182
  defaultChecked,
@@ -165,8 +191,9 @@ const Checkbox = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
165
191
  tokens,
166
192
  value,
167
193
  variant,
194
+ testID,
168
195
  ...rest
169
- } = _ref6;
196
+ } = _ref8;
170
197
  const {
171
198
  currentValue: isChecked,
172
199
  setValue: setIsChecked,
@@ -223,17 +250,18 @@ const Checkbox = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
223
250
  direction: feedbackPosition === 'top' ? 'column-reverse' : 'column',
224
251
  space: 0,
225
252
  children: [/*#__PURE__*/_jsx(Pressable, {
253
+ testID: testID && `${testID}-pressable`,
226
254
  disabled: inactive,
227
255
  onKeyDown: handleKeyDown,
228
256
  onPress: handleChange,
229
257
  ...selectedProps,
230
- style: staticStyles.removeOutline,
231
- children: _ref7 => {
258
+ style: [staticStyles.removeOutline, selectPressableStyles(defaultTokens)],
259
+ children: _ref9 => {
232
260
  let {
233
261
  focused: focus,
234
262
  hovered: hover,
235
263
  pressed
236
- } = _ref7;
264
+ } = _ref9;
237
265
  const {
238
266
  icon: IconComponent,
239
267
  ...stateTokens
@@ -244,15 +272,12 @@ const Checkbox = /*#__PURE__*/React.forwardRef((_ref6, ref) => {
244
272
  });
245
273
  const iconTokens = selectIconTokens(stateTokens);
246
274
  const labelStyles = selectLabelStyles(stateTokens, themeOptions);
247
- const alignWithLabel = label ? [staticStyles.alignWithLabel, {
248
- height: labelStyles.lineHeight
249
- }] : null;
250
275
  return /*#__PURE__*/_jsxs(StackView, {
251
276
  space: 0,
252
277
  children: [/*#__PURE__*/_jsxs(View, {
253
278
  style: staticStyles.container,
254
279
  children: [/*#__PURE__*/_jsx(View, {
255
- style: alignWithLabel,
280
+ style: [staticStyles.iconContainer, selectContainerStyles(stateTokens)],
256
281
  children: /*#__PURE__*/_jsxs(View, {
257
282
  style: [staticStyles.defaultInputStyles, selectInputStyles(stateTokens, isChecked)],
258
283
  testID: "Checkbox-Input",
@@ -351,7 +376,11 @@ Checkbox.propTypes = {
351
376
  /**
352
377
  * An optional Checkbox description.
353
378
  */
354
- description: PropTypes.string
379
+ description: PropTypes.string,
380
+ /**
381
+ * A identifier for testing purposes.
382
+ */
383
+ testID: PropTypes.string
355
384
  };
356
385
  export default Checkbox;
357
386
  const staticStyles = StyleSheet.create({
@@ -366,9 +395,10 @@ const staticStyles = StyleSheet.create({
366
395
  alignItems: 'center',
367
396
  justifyContent: 'center'
368
397
  },
369
- alignWithLabel: {
370
- alignSelf: 'flex-start',
371
- justifyContent: 'center'
398
+ iconContainer: {
399
+ display: 'flex',
400
+ justifyContent: 'center',
401
+ alignItems: 'center'
372
402
  },
373
403
  removeOutline: {
374
404
  outlineStyle: 'none'
@@ -6,10 +6,15 @@ import PropTypes from 'prop-types';
6
6
  import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps } from '../utils';
7
7
  import { jsx as _jsx } from "react/jsx-runtime";
8
8
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
9
+ const LIST_ITEM_TYPE = 'ListItem';
10
+ const LINKS_ITEM_TYPE = 'LinksItem';
9
11
  const isListItem = element => {
10
- const elementName = element?.type?.displayName || element?.type?.name;
11
- // Match our own ListItem, and also, custom list items
12
- return Boolean(elementName.match(/Item/));
12
+ if (!element?.type) return false;
13
+ if (element.type.__UDS_COMPONENT_TYPE__ === LIST_ITEM_TYPE) {
14
+ return true;
15
+ }
16
+ const elementName = element.type.displayName || element.type.name || '';
17
+ return elementName === LIST_ITEM_TYPE || elementName.includes(LIST_ITEM_TYPE) || elementName.includes(LINKS_ITEM_TYPE);
13
18
  };
14
19
 
15
20
  /**
@@ -22,6 +27,7 @@ const List = /*#__PURE__*/React.forwardRef((_ref, ref) => {
22
27
  showDivider,
23
28
  tokens,
24
29
  variant,
30
+ iconVerticalAlign,
25
31
  accessibilityRole = Platform.select({
26
32
  web: 'list',
27
33
  default: undefined
@@ -31,13 +37,17 @@ const List = /*#__PURE__*/React.forwardRef((_ref, ref) => {
31
37
  const items = React.Children.map(children, (child, index) => {
32
38
  // Pass ListItem-specific props to children (by name so teams can add their own ListItems)
33
39
  if (isListItem(child)) {
34
- return /*#__PURE__*/React.cloneElement(child, {
35
- showDivider,
36
- isLastItem: index + 1 === React.Children.count(children),
40
+ const childProps = {
37
41
  tokens,
38
42
  variant,
39
- ...child.props
40
- });
43
+ ...child.props,
44
+ showDivider,
45
+ isLastItem: index + 1 === React.Children.count(children)
46
+ };
47
+ if (!child.props.iconVerticalAlign && iconVerticalAlign) {
48
+ childProps.iconVerticalAlign = iconVerticalAlign;
49
+ }
50
+ return /*#__PURE__*/React.cloneElement(child, childProps);
41
51
  }
42
52
  return child;
43
53
  });
@@ -71,6 +81,11 @@ List.propTypes = {
71
81
  /**
72
82
  * In case it is not the last item allow display divider
73
83
  */
74
- showDivider: PropTypes.bool
84
+ showDivider: PropTypes.bool,
85
+ /**
86
+ * The vertical alignment of the icon in ListItems.
87
+ * This prop is passed down to ListItem components and can be overridden in individual List.Item components.
88
+ */
89
+ iconVerticalAlign: PropTypes.oneOf(['top', 'center', 'bottom'])
75
90
  };
76
91
  export default List;
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
+ import PropTypes from 'prop-types';
2
3
  import ListItemBase from './ListItemBase';
3
4
  import { useThemeTokens } from '../ThemeProvider';
4
- import { variantProp } from '../utils';
5
+ import { getTokensPropType, variantProp } from '../utils';
5
6
 
6
7
  /**
7
8
  * ListItem is responsible for rendering icon or a bullet as side item
@@ -13,6 +14,7 @@ const ListItem = /*#__PURE__*/React.forwardRef((_ref, ref) => {
13
14
  variant,
14
15
  children,
15
16
  title,
17
+ iconVerticalAlign = 'top',
16
18
  ...listItemProps
17
19
  } = _ref;
18
20
  const themeTokens = useThemeTokens('List', tokens, variant);
@@ -21,12 +23,27 @@ const ListItem = /*#__PURE__*/React.forwardRef((_ref, ref) => {
21
23
  ref: ref,
22
24
  ...listItemProps,
23
25
  title: title,
26
+ iconVerticalAlign: iconVerticalAlign,
24
27
  children: children
25
28
  });
26
29
  });
27
30
  ListItem.displayName = 'ListItem';
28
31
  ListItem.propTypes = {
32
+ /** Theme tokens for styling */
33
+ tokens: getTokensPropType('List'),
34
+ /** Variant configuration for the component */
29
35
  variant: variantProp.propType,
30
- ...ListItemBase.propTypes
36
+ /** Content to be rendered within the list item */
37
+ children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
38
+ /** Title of the list item */
39
+ title: PropTypes.node,
40
+ /** Controls the vertical alignment of the icon */
41
+ iconVerticalAlign: PropTypes.oneOf(['top', 'center', 'bottom']),
42
+ /** Icon to be displayed */
43
+ icon: PropTypes.elementType,
44
+ /** Color of the icon */
45
+ iconColor: PropTypes.string,
46
+ /** Size of the icon */
47
+ iconSize: PropTypes.number
31
48
  };
32
49
  export default ListItem;
@@ -10,6 +10,12 @@ import Typography from '../Typography';
10
10
  import { useThemeTokens } from '../ThemeProvider';
11
11
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
12
12
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
13
+ const VERTICAL_CENTERING_DIVISOR = 2;
14
+ const alignmentMap = {
15
+ top: 'flex-start',
16
+ center: 'center',
17
+ bottom: 'flex-end'
18
+ };
13
19
  const selectItemBlockStyles = _ref => {
14
20
  let {
15
21
  interItemMargin
@@ -31,10 +37,16 @@ const selectDividerStyles = _ref2 => {
31
37
  paddingBottom: interItemMarginWithDivider
32
38
  };
33
39
  };
40
+ const selectAlignmentStyles = iconVerticalAlign => ({
41
+ alignItems: alignmentMap[iconVerticalAlign]
42
+ });
34
43
 
35
44
  /**
36
45
  * ListItem is responsible for rendering icon or a bullet as side item
37
46
  */
47
+ const calculateIconMarginTop = (itemIconSize, fontSize, lineHeightRatio) => {
48
+ return (fontSize * lineHeightRatio - itemIconSize) / VERTICAL_CENTERING_DIVISOR;
49
+ };
38
50
  const ListItemBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
39
51
  let {
40
52
  tokens,
@@ -45,6 +57,7 @@ const ListItemBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
45
57
  children,
46
58
  title,
47
59
  isLastItem,
60
+ iconVerticalAlign = 'top',
48
61
  accessibilityRole = Platform.select({
49
62
  web: 'listitem',
50
63
  default: undefined
@@ -58,7 +71,6 @@ const ListItemBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
58
71
  iconMarginTop,
59
72
  itemIconSize
60
73
  } = themeTokens;
61
- let adjustedIconMarginTop = iconMarginTop;
62
74
  const {
63
75
  fontSize,
64
76
  lineHeight: lineHeightRatio
@@ -66,9 +78,8 @@ const ListItemBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
66
78
  size: 'h4',
67
79
  bold: true
68
80
  });
69
- if (title) {
70
- adjustedIconMarginTop = (fontSize * lineHeightRatio - itemIconSize) / 2;
71
- }
81
+ const adjustedIconMarginTop = title ? calculateIconMarginTop(itemIconSize, fontSize, lineHeightRatio) : iconMarginTop;
82
+
72
83
  /**
73
84
  * Function responsible returning styling, in case the item is the last shouldn't
74
85
  * add extra margin on the bottom, if "showDivider" is true it should add a divider
@@ -95,7 +106,7 @@ const ListItemBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
95
106
  iconSize,
96
107
  isLastItem
97
108
  }) : /*#__PURE__*/_jsxs(View, {
98
- style: staticStyles.container,
109
+ style: [staticStyles.innerContainer, selectAlignmentStyles(iconVerticalAlign)],
99
110
  children: [/*#__PURE__*/_jsx(ListItemMark, {
100
111
  tokens: {
101
112
  ...tokens,
@@ -105,7 +116,7 @@ const ListItemBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
105
116
  iconColor: iconColor,
106
117
  iconSize: iconSize
107
118
  }), /*#__PURE__*/_jsxs(View, {
108
- style: staticStyles.titleAndContentContainer,
119
+ style: [staticStyles.titleAndContentContainer],
109
120
  children: [Boolean(title) && /*#__PURE__*/_jsx(Typography, {
110
121
  variant: {
111
122
  size: 'h4',
@@ -121,15 +132,21 @@ const ListItemBase = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
121
132
  });
122
133
  });
123
134
  ListItemBase.displayName = 'ListItem';
135
+ ListItemBase.__UDS_COMPONENT_TYPE__ = 'ListItem';
124
136
  const staticStyles = StyleSheet.create({
125
137
  container: {
138
+ flexDirection: 'row',
139
+ width: '100%'
140
+ },
141
+ innerContainer: {
126
142
  flex: 1,
127
143
  flexDirection: 'row'
128
144
  },
129
145
  titleAndContentContainer: {
130
146
  flexDirection: 'column',
131
- flexShrink: 1,
132
- flexGrow: 1
147
+ flex: 1,
148
+ flexGrow: 1,
149
+ flexShrink: 1
133
150
  }
134
151
  });
135
152
  ListItemBase.propTypes = {
@@ -137,6 +154,8 @@ ListItemBase.propTypes = {
137
154
  tokens: getTokensPropType('List'),
138
155
  variant: variantProp.propType,
139
156
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
157
+ /** Controls the vertical alignment of the icon */
158
+ iconVerticalAlign: PropTypes.oneOf(['top', 'center', 'bottom']),
140
159
  /**
141
160
  * Renders side item icon
142
161
  */
@@ -1,7 +1,6 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import View from "react-native-web/dist/exports/View";
4
- import StyleSheet from "react-native-web/dist/exports/StyleSheet";
5
4
  import Icon from '../Icon';
6
5
  import { useVariants } from '../utils';
7
6
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -9,49 +8,29 @@ export const tokenTypes = {
9
8
  itemIconSize: PropTypes.number.isRequired,
10
9
  itemIconColor: PropTypes.string.isRequired,
11
10
  listGutter: PropTypes.number.isRequired,
12
- iconMarginTop: PropTypes.number.isRequired
11
+ iconMarginTop: PropTypes.number.isRequired,
12
+ bulletIcon: PropTypes.elementType.isRequired
13
13
  };
14
- const selectItemIconTokens = _ref => {
14
+ const selectContainerStyles = _ref => {
15
15
  let {
16
- itemIconSize,
17
- itemIconColor
16
+ listGutter
18
17
  } = _ref;
19
18
  return {
20
- size: itemIconSize,
21
- color: itemIconColor
22
- };
23
- };
24
- const selectSideItemContainerStyles = _ref2 => {
25
- let {
26
- listGutter,
27
- iconMarginTop
28
- } = _ref2;
29
- return {
30
- marginTop: iconMarginTop,
31
- marginRight: listGutter
19
+ marginInlineEnd: listGutter,
20
+ display: 'flex',
21
+ alignItems: 'flex-start'
32
22
  };
33
23
  };
34
-
35
- // Align bullets with the top line of text the same way icons are aligned
36
- const selectBulletPositioningStyles = _ref3 => {
24
+ const selectBulletStyles = _ref2 => {
37
25
  let {
38
26
  itemIconSize
39
- } = _ref3;
27
+ } = _ref2;
40
28
  return {
41
29
  width: itemIconSize,
42
- height: itemIconSize
43
- };
44
- };
45
- const selectBulletContainerStyles = _ref4 => {
46
- let {
47
- itemBulletContainerWidth,
48
- itemBulletContainerHeight,
49
- itemBulletContainerAlign
50
- } = _ref4;
51
- return {
52
- width: itemBulletContainerWidth,
53
- height: itemBulletContainerHeight,
54
- alignItems: itemBulletContainerAlign
30
+ height: itemIconSize,
31
+ alignItems: 'center',
32
+ justifyContent: 'center',
33
+ flexShrink: 0
55
34
  };
56
35
  };
57
36
  const getIconColorVariants = iconVariants => iconVariants?.filter(variant => variant[0] === 'color').map(variant => variant[1]);
@@ -63,31 +42,31 @@ const getIconColorVariants = iconVariants => iconVariants?.filter(variant => var
63
42
  * It's the responsibility of themes to make sure that the supplied tokens align the
64
43
  * icon or bullet nicely against the first line of text in a ListIconContent.
65
44
  */
66
- const ListItemMark = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
45
+ const ListItemMark = /*#__PURE__*/React.forwardRef((_ref3, ref) => {
67
46
  let {
68
47
  icon,
69
48
  iconColor,
70
49
  iconSize,
71
50
  tokens = {}
72
- } = _ref5;
51
+ } = _ref3;
73
52
  const themeTokens = typeof tokens === 'function' ? tokens() : tokens;
74
- const sideItemContainerStyles = selectSideItemContainerStyles(themeTokens);
75
- const bulletContainerStyles = selectBulletContainerStyles(themeTokens);
76
-
77
- // TODO: Remove it when iconColor custom colors are deprecated.
53
+ const containerStyles = selectContainerStyles(themeTokens);
78
54
  const iconVariants = useVariants('Icon');
79
55
  const iconColorVariants = getIconColorVariants(iconVariants);
80
56
  if (icon) {
81
- const iconTokens = selectItemIconTokens(themeTokens);
57
+ const {
58
+ itemIconSize,
59
+ itemIconColor
60
+ } = themeTokens;
61
+ const finalIconSize = iconSize ?? itemIconSize;
62
+ const finalIconColor = iconColor && !iconColorVariants?.includes(iconColor) ? iconColor : itemIconColor;
82
63
  return /*#__PURE__*/_jsx(View, {
83
- style: [sideItemContainerStyles, bulletContainerStyles],
64
+ style: containerStyles,
84
65
  children: /*#__PURE__*/_jsx(Icon, {
85
66
  icon: icon,
86
67
  tokens: {
87
- size: iconSize ?? iconTokens.size,
88
- ...((iconColor && !iconColorVariants?.includes(iconColor) || !iconColor) && {
89
- color: iconColor && !iconColorVariants?.includes(iconColor) ? iconColor : iconTokens.color
90
- })
68
+ size: finalIconSize,
69
+ color: finalIconColor
91
70
  },
92
71
  variant: {
93
72
  ...(iconColorVariants?.includes(iconColor) && {
@@ -97,23 +76,21 @@ const ListItemMark = /*#__PURE__*/React.forwardRef((_ref5, ref) => {
97
76
  })
98
77
  });
99
78
  }
100
- const bulletColor = themeTokens.itemBulletColor;
101
79
  const {
102
- bulletIcon
80
+ itemIconSize,
81
+ itemIconColor
103
82
  } = themeTokens;
104
- const itemBulletContainerStyles = selectBulletContainerStyles(themeTokens);
105
- const itemBulletPositioningStyles = selectBulletPositioningStyles(themeTokens);
83
+ const bulletStyles = selectBulletStyles(themeTokens);
106
84
  return /*#__PURE__*/_jsx(View, {
107
- style: [sideItemContainerStyles, itemBulletContainerStyles],
85
+ style: containerStyles,
108
86
  ref: ref,
109
87
  children: /*#__PURE__*/_jsx(View, {
110
- style: [staticStyles.bulletPositioning, itemBulletPositioningStyles],
111
- testID: "unordered-item-bullet",
88
+ style: bulletStyles,
112
89
  children: /*#__PURE__*/_jsx(Icon, {
113
- icon: bulletIcon,
90
+ icon: themeTokens.bulletIcon,
114
91
  tokens: {
115
- color: bulletColor,
116
- size: themeTokens.itemIconSize
92
+ color: itemIconColor,
93
+ size: itemIconSize
117
94
  }
118
95
  })
119
96
  })
@@ -135,10 +112,4 @@ ListItemMark.propTypes = {
135
112
  */
136
113
  iconSize: PropTypes.number
137
114
  };
138
- const staticStyles = StyleSheet.create({
139
- bulletPositioning: {
140
- alignItems: 'center',
141
- justifyContent: 'center'
142
- }
143
- });
144
115
  export default ListItemMark;
@@ -91,6 +91,7 @@ const PressableListItemBase = /*#__PURE__*/React.forwardRef((_ref2, ref) => {
91
91
  });
92
92
  });
93
93
  PressableListItemBase.displayName = 'PressableListItemBase';
94
+ PressableListItemBase.__UDS_COMPONENT_TYPE__ = 'ListItem';
94
95
  const staticStyles = StyleSheet.create({
95
96
  itemContainer: {
96
97
  flexDirection: 'row',
package/lib/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@react-native-picker/picker": "^2.9.0",
14
14
  "@telus-uds/system-constants": "^3.0.0",
15
- "@telus-uds/system-theme-tokens": "^4.18.0",
15
+ "@telus-uds/system-theme-tokens": "^4.19.0",
16
16
  "airbnb-prop-types": "^2.16.0",
17
17
  "css-mediaquery": "^0.1.2",
18
18
  "expo-document-picker": "^13.0.1",
@@ -84,6 +84,6 @@
84
84
  "standard-engine": {
85
85
  "skip": true
86
86
  },
87
- "version": "3.26.0",
87
+ "version": "3.27.0",
88
88
  "types": "types/index.d.ts"
89
89
  }
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "@gorhom/portal": "^1.0.14",
13
13
  "@react-native-picker/picker": "^2.9.0",
14
14
  "@telus-uds/system-constants": "^3.0.0",
15
- "@telus-uds/system-theme-tokens": "^4.18.0",
15
+ "@telus-uds/system-theme-tokens": "^4.19.0",
16
16
  "airbnb-prop-types": "^2.16.0",
17
17
  "css-mediaquery": "^0.1.2",
18
18
  "expo-document-picker": "^13.0.1",
@@ -84,6 +84,6 @@
84
84
  "standard-engine": {
85
85
  "skip": true
86
86
  },
87
- "version": "3.26.0",
87
+ "version": "3.27.0",
88
88
  "types": "types/index.d.ts"
89
89
  }
package/src/Card/Card.jsx CHANGED
@@ -30,10 +30,10 @@ const SelectionType = {
30
30
  None: undefined
31
31
  }
32
32
 
33
- const selectInputStyle = ({ paddingTop, paddingRight }) => ({
33
+ const selectInputStyle = ({ paddingTop, paddingRight, paddingLeft }, { inputPositionProp }) => ({
34
34
  position: 'absolute',
35
35
  top: paddingTop,
36
- right: paddingRight
36
+ ...(inputPositionProp === 'left' ? { left: paddingLeft } : { right: paddingRight })
37
37
  })
38
38
 
39
39
  const getInputProps = ({
@@ -108,7 +108,18 @@ const getInputProps = ({
108
108
  */
109
109
  const Card = React.forwardRef(
110
110
  (
111
- { children, tokens, variant, dataSet, onPress, id, interactiveCard, backgroundImage, ...rest },
111
+ {
112
+ children,
113
+ tokens,
114
+ variant,
115
+ dataSet,
116
+ onPress,
117
+ id,
118
+ interactiveCard,
119
+ backgroundImage,
120
+ testID,
121
+ ...rest
122
+ },
112
123
  ref
113
124
  ) => {
114
125
  const viewport = useViewport()
@@ -216,6 +227,11 @@ const Card = React.forwardRef(
216
227
  }
217
228
 
218
229
  const renderInputPerSelectionType = (props) => {
230
+ const containerStyle = selectInputStyle(getThemeTokens(), {
231
+ inputPositionProp: interactiveCard?.inputPosition
232
+ })
233
+ const inputTestID = testID && `${testID}-selection-input`
234
+
219
235
  if (!isControl) {
220
236
  return null
221
237
  }
@@ -223,13 +239,13 @@ const Card = React.forwardRef(
223
239
  switch (selectionType) {
224
240
  case SelectionType.Checkbox:
225
241
  return (
226
- <View style={selectInputStyle(getThemeTokens())}>
242
+ <View style={containerStyle} testID={inputTestID}>
227
243
  <CheckboxButton {...props} tokens={{ ...checkboxTokens, ...props?.tokens }} />
228
244
  </View>
229
245
  )
230
246
  case SelectionType.Radio:
231
247
  return (
232
- <View style={selectInputStyle(getThemeTokens())}>
248
+ <View style={containerStyle} testID={inputTestID}>
233
249
  <RadioButton {...props} tokens={{ ...radioTokens, ...props?.tokens }} />
234
250
  </View>
235
251
  )
@@ -245,6 +261,7 @@ const Card = React.forwardRef(
245
261
  tokens={interactiveCard?.body ? restOfTokens : cardStyles}
246
262
  backgroundImage={backgroundImage}
247
263
  dataSet={mediaIds && { media: mediaIds }}
264
+ testID={testID}
248
265
  {...selectProps(rest)}
249
266
  >
250
267
  {interactiveCard?.body && (
@@ -342,7 +359,8 @@ Card.propTypes = {
342
359
  selectionType: PropTypes.oneOf(Object.values(SelectionType)),
343
360
  variant: variantProp.propType,
344
361
  href: PropTypes.string,
345
- hrefAttrs: PropTypes.shape(hrefAttrsProp.types)
362
+ hrefAttrs: PropTypes.shape(hrefAttrsProp.types),
363
+ inputPosition: PropTypes.oneOf(['left', 'right'])
346
364
  }),
347
365
  /**
348
366
  * Apply background image to the card.
@@ -365,7 +383,11 @@ Card.propTypes = {
365
383
  /**
366
384
  * Data set for the card.
367
385
  */
368
- dataSet: PropTypes.object
386
+ dataSet: PropTypes.object,
387
+ /**
388
+ * Test ID used for e2e testing.
389
+ */
390
+ testID: PropTypes.string
369
391
  }
370
392
 
371
393
  export default Card