@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
@@ -14,7 +14,9 @@ const CarouselProvider = ({
14
14
  themeTokens,
15
15
  totalItems,
16
16
  width,
17
- maximumItemsForSlide
17
+ maximumItemsForSlide,
18
+ maxWidth,
19
+ viewportWidth
18
20
  }) => {
19
21
  const value = React.useMemo(
20
22
  () => ({
@@ -26,7 +28,9 @@ const CarouselProvider = ({
26
28
  themeTokens,
27
29
  totalItems,
28
30
  width,
29
- maximumItemsForSlide
31
+ maximumItemsForSlide,
32
+ maxWidth,
33
+ viewportWidth
30
34
  }),
31
35
  [
32
36
  activeIndex,
@@ -37,7 +41,9 @@ const CarouselProvider = ({
37
41
  totalItems,
38
42
  themeTokens,
39
43
  width,
40
- maximumItemsForSlide
44
+ maximumItemsForSlide,
45
+ maxWidth,
46
+ viewportWidth
41
47
  ]
42
48
  )
43
49
  return <CarouselContext.Provider value={value}>{children}</CarouselContext.Provider>
@@ -61,7 +67,9 @@ CarouselProvider.propTypes = {
61
67
  themeTokens: getTokensPropType('Carousel'),
62
68
  totalItems: PropTypes.number.isRequired,
63
69
  width: PropTypes.number.isRequired,
64
- maximumItemsForSlide: PropTypes.number
70
+ maximumItemsForSlide: PropTypes.number,
71
+ maxWidth: PropTypes.number,
72
+ viewportWidth: PropTypes.number
65
73
  }
66
74
 
67
75
  export { CarouselProvider, useCarousel }
@@ -18,27 +18,28 @@ const selectContainerStyle = ({
18
18
  width,
19
19
  elementIndex,
20
20
  enablePeeking,
21
- peekingMarginLeft,
22
21
  peekingGap,
23
22
  hidden,
24
23
  enableDisplayMultipleItemsPerSlide,
25
24
  viewport,
26
- peekingMiddleSpace
25
+ peekingMiddleSpace,
26
+ maxWidth,
27
+ viewportWidth
27
28
  }) => {
28
29
  let adjustedWidth = width
29
30
  let marginLeft = 0
30
31
 
31
32
  if (enablePeeking) {
32
33
  const isFirst = elementIndex === 0
33
- adjustedWidth = width - (peekingMiddleSpace * 2 + peekingGap * 2)
34
+ const baseWidth = maxWidth || width
35
+ adjustedWidth = baseWidth - peekingMiddleSpace * 2
34
36
  if (isFirst) {
35
- marginLeft = peekingMarginLeft
37
+ marginLeft = peekingMiddleSpace + (viewportWidth - maxWidth) / 2
36
38
  } else {
37
39
  marginLeft = peekingGap
38
40
  }
39
41
  }
40
42
 
41
- // Adjust width and margins for multiple items per slide.
42
43
  if (enableDisplayMultipleItemsPerSlide) {
43
44
  switch (viewport) {
44
45
  case 'xs':
@@ -102,7 +103,8 @@ const CarouselItem = React.forwardRef(
102
103
  },
103
104
  ref
104
105
  ) => {
105
- const { width, activeIndex, goTo, maximumItemsForSlide } = useCarousel()
106
+ const { width, activeIndex, goTo, maximumItemsForSlide, maxWidth, viewportWidth } =
107
+ useCarousel()
106
108
 
107
109
  const selectedProps = selectProps({
108
110
  ...rest,
@@ -162,6 +164,8 @@ const CarouselItem = React.forwardRef(
162
164
  enablePeeking,
163
165
  enableDisplayMultipleItemsPerSlide,
164
166
  viewport,
167
+ maxWidth,
168
+ viewportWidth,
165
169
  ...peekingProps
166
170
  })}
167
171
  {...selectedProps}
@@ -23,3 +23,13 @@ export const SWIPE_RELEASE_STYLES = {
23
23
 
24
24
  export const INSTANT_ANIMATION_DURATION = 1
25
25
  export const DEFAULT_SWIPE_RELEASE_DURATION = 500
26
+ export const POSITION_VARIANTS = {
27
+ EDGE: 'edge',
28
+ INSIDE: 'inside',
29
+ OUTSIDE: 'outside'
30
+ }
31
+
32
+ export const POSITION_PROPERTIES = {
33
+ LEFT: 'left',
34
+ RIGHT: 'right'
35
+ }
@@ -109,6 +109,25 @@ const selectFeedbackTokens = ({ feedbackMarginBottom, feedbackMarginTop, feedbac
109
109
  feedbackMarginTop
110
110
  })
111
111
 
112
+ const selectPressableStyles = ({
113
+ padding,
114
+ paddingLeft,
115
+ paddingRight,
116
+ paddingTop,
117
+ paddingBottom
118
+ }) => ({
119
+ padding,
120
+ paddingLeft,
121
+ paddingRight,
122
+ paddingTop,
123
+ paddingBottom
124
+ })
125
+
126
+ const selectContainerStyles = ({ iconContainerHeight, iconContainerWidth }) => ({
127
+ height: iconContainerHeight,
128
+ width: iconContainerWidth
129
+ })
130
+
112
131
  /**
113
132
  * Basic Checkbox component.
114
133
  *
@@ -160,6 +179,7 @@ const Checkbox = React.forwardRef(
160
179
  tokens,
161
180
  value,
162
181
  variant,
182
+ testID,
163
183
  ...rest
164
184
  },
165
185
  ref
@@ -211,24 +231,22 @@ const Checkbox = React.forwardRef(
211
231
  <View style={staticStyles.wrapper} ref={ref}>
212
232
  <StackView direction={feedbackPosition === 'top' ? 'column-reverse' : 'column'} space={0}>
213
233
  <Pressable
234
+ testID={testID && `${testID}-pressable`}
214
235
  disabled={inactive}
215
236
  onKeyDown={handleKeyDown}
216
237
  onPress={handleChange}
217
238
  {...selectedProps}
218
- style={staticStyles.removeOutline}
239
+ style={[staticStyles.removeOutline, selectPressableStyles(defaultTokens)]}
219
240
  >
220
241
  {({ focused: focus, hovered: hover, pressed }) => {
221
242
  const { icon: IconComponent, ...stateTokens } = getTokens({ focus, hover, pressed })
222
243
  const iconTokens = selectIconTokens(stateTokens)
223
244
  const labelStyles = selectLabelStyles(stateTokens, themeOptions)
224
- const alignWithLabel = label
225
- ? [staticStyles.alignWithLabel, { height: labelStyles.lineHeight }]
226
- : null
227
245
 
228
246
  return (
229
247
  <StackView space={0}>
230
248
  <View style={staticStyles.container}>
231
- <View style={alignWithLabel}>
249
+ <View style={[staticStyles.iconContainer, selectContainerStyles(stateTokens)]}>
232
250
  <View
233
251
  style={[
234
252
  staticStyles.defaultInputStyles,
@@ -335,7 +353,11 @@ Checkbox.propTypes = {
335
353
  /**
336
354
  * An optional Checkbox description.
337
355
  */
338
- description: PropTypes.string
356
+ description: PropTypes.string,
357
+ /**
358
+ * A identifier for testing purposes.
359
+ */
360
+ testID: PropTypes.string
339
361
  }
340
362
 
341
363
  export default Checkbox
@@ -344,6 +366,6 @@ const staticStyles = StyleSheet.create({
344
366
  wrapper: { backgroundColor: 'transparent' },
345
367
  container: { flexDirection: 'row', alignItems: 'center' },
346
368
  defaultInputStyles: { alignItems: 'center', justifyContent: 'center' },
347
- alignWithLabel: { alignSelf: 'flex-start', justifyContent: 'center' },
369
+ iconContainer: { display: 'flex', justifyContent: 'center', alignItems: 'center' },
348
370
  removeOutline: { outlineStyle: 'none' }
349
371
  })
package/src/List/List.jsx CHANGED
@@ -5,10 +5,22 @@ import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps
5
5
 
6
6
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
7
7
 
8
+ const LIST_ITEM_TYPE = 'ListItem'
9
+ const LINKS_ITEM_TYPE = 'LinksItem'
10
+
8
11
  const isListItem = (element) => {
9
- const elementName = element?.type?.displayName || element?.type?.name
10
- // Match our own ListItem, and also, custom list items
11
- return Boolean(elementName.match(/Item/))
12
+ if (!element?.type) return false
13
+
14
+ if (element.type.__UDS_COMPONENT_TYPE__ === LIST_ITEM_TYPE) {
15
+ return true
16
+ }
17
+
18
+ const elementName = element.type.displayName || element.type.name || ''
19
+ return (
20
+ elementName === LIST_ITEM_TYPE ||
21
+ elementName.includes(LIST_ITEM_TYPE) ||
22
+ elementName.includes(LINKS_ITEM_TYPE)
23
+ )
12
24
  }
13
25
 
14
26
  /**
@@ -22,6 +34,7 @@ const List = React.forwardRef(
22
34
  showDivider,
23
35
  tokens,
24
36
  variant,
37
+ iconVerticalAlign,
25
38
  accessibilityRole = Platform.select({ web: 'list', default: undefined }),
26
39
  ...rest
27
40
  },
@@ -30,13 +43,19 @@ const List = React.forwardRef(
30
43
  const items = React.Children.map(children, (child, index) => {
31
44
  // Pass ListItem-specific props to children (by name so teams can add their own ListItems)
32
45
  if (isListItem(child)) {
33
- return React.cloneElement(child, {
34
- showDivider,
35
- isLastItem: index + 1 === React.Children.count(children),
46
+ const childProps = {
36
47
  tokens,
37
48
  variant,
38
- ...child.props
39
- })
49
+ ...child.props,
50
+ showDivider,
51
+ isLastItem: index + 1 === React.Children.count(children)
52
+ }
53
+
54
+ if (!child.props.iconVerticalAlign && iconVerticalAlign) {
55
+ childProps.iconVerticalAlign = iconVerticalAlign
56
+ }
57
+
58
+ return React.cloneElement(child, childProps)
40
59
  }
41
60
  return child
42
61
  })
@@ -76,7 +95,12 @@ List.propTypes = {
76
95
  /**
77
96
  * In case it is not the last item allow display divider
78
97
  */
79
- showDivider: PropTypes.bool
98
+ showDivider: PropTypes.bool,
99
+ /**
100
+ * The vertical alignment of the icon in ListItems.
101
+ * This prop is passed down to ListItem components and can be overridden in individual List.Item components.
102
+ */
103
+ iconVerticalAlign: PropTypes.oneOf(['top', 'center', 'bottom'])
80
104
  }
81
105
 
82
106
  export default List
@@ -1,25 +1,47 @@
1
1
  import React from 'react'
2
-
2
+ import PropTypes from 'prop-types'
3
3
  import ListItemBase from './ListItemBase'
4
4
  import { useThemeTokens } from '../ThemeProvider'
5
- import { variantProp } from '../utils'
5
+ import { getTokensPropType, variantProp } from '../utils'
6
6
 
7
7
  /**
8
8
  * ListItem is responsible for rendering icon or a bullet as side item
9
9
  */
10
- const ListItem = React.forwardRef(({ tokens, variant, children, title, ...listItemProps }, ref) => {
11
- const themeTokens = useThemeTokens('List', tokens, variant)
12
- return (
13
- <ListItemBase tokens={themeTokens} ref={ref} {...listItemProps} title={title}>
14
- {children}
15
- </ListItemBase>
16
- )
17
- })
10
+ const ListItem = React.forwardRef(
11
+ ({ tokens, variant, children, title, iconVerticalAlign = 'top', ...listItemProps }, ref) => {
12
+ const themeTokens = useThemeTokens('List', tokens, variant)
13
+ return (
14
+ <ListItemBase
15
+ tokens={themeTokens}
16
+ ref={ref}
17
+ {...listItemProps}
18
+ title={title}
19
+ iconVerticalAlign={iconVerticalAlign}
20
+ >
21
+ {children}
22
+ </ListItemBase>
23
+ )
24
+ }
25
+ )
18
26
  ListItem.displayName = 'ListItem'
19
27
 
20
28
  ListItem.propTypes = {
29
+ /** Theme tokens for styling */
30
+ tokens: getTokensPropType('List'),
31
+ /** Variant configuration for the component */
21
32
  variant: variantProp.propType,
22
- ...ListItemBase.propTypes
33
+ /** Content to be rendered within the list item */
34
+ children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
35
+ /** Title of the list item */
36
+ title: PropTypes.node,
37
+ /** Controls the vertical alignment of the icon */
38
+ iconVerticalAlign: PropTypes.oneOf(['top', 'center', 'bottom']),
39
+ /** Icon to be displayed */
40
+ icon: PropTypes.elementType,
41
+ /** Color of the icon */
42
+ iconColor: PropTypes.string,
43
+ /** Size of the icon */
44
+ iconSize: PropTypes.number
23
45
  }
24
46
 
25
47
  export default ListItem
@@ -2,7 +2,6 @@ import React from 'react'
2
2
  import { View, Platform, StyleSheet } from 'react-native'
3
3
  import PropTypes from 'prop-types'
4
4
  import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps } from '../utils'
5
-
6
5
  import ListItemContent from './ListItemContent'
7
6
  import ListItemMark from './ListItemMark'
8
7
  import Typography from '../Typography'
@@ -10,6 +9,14 @@ import { useThemeTokens } from '../ThemeProvider'
10
9
 
11
10
  const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
12
11
 
12
+ const VERTICAL_CENTERING_DIVISOR = 2
13
+
14
+ const alignmentMap = {
15
+ top: 'flex-start',
16
+ center: 'center',
17
+ bottom: 'flex-end'
18
+ }
19
+
13
20
  const selectItemBlockStyles = ({ interItemMargin }) => ({
14
21
  marginBottom: interItemMargin
15
22
  })
@@ -21,9 +28,17 @@ const selectDividerStyles = ({ dividerColor, dividerSize, interItemMarginWithDiv
21
28
  paddingBottom: interItemMarginWithDivider
22
29
  })
23
30
 
31
+ const selectAlignmentStyles = (iconVerticalAlign) => ({
32
+ alignItems: alignmentMap[iconVerticalAlign]
33
+ })
34
+
24
35
  /**
25
36
  * ListItem is responsible for rendering icon or a bullet as side item
26
37
  */
38
+ const calculateIconMarginTop = (itemIconSize, fontSize, lineHeightRatio) => {
39
+ return (fontSize * lineHeightRatio - itemIconSize) / VERTICAL_CENTERING_DIVISOR
40
+ }
41
+
27
42
  const ListItemBase = React.forwardRef(
28
43
  (
29
44
  {
@@ -35,6 +50,7 @@ const ListItemBase = React.forwardRef(
35
50
  children,
36
51
  title,
37
52
  isLastItem,
53
+ iconVerticalAlign = 'top',
38
54
  accessibilityRole = Platform.select({ web: 'listitem', default: undefined }),
39
55
  ...rest
40
56
  },
@@ -45,15 +61,15 @@ const ListItemBase = React.forwardRef(
45
61
  const itemBlockStyles = selectItemBlockStyles(themeTokens)
46
62
  const dividerStyles = selectDividerStyles(themeTokens)
47
63
  const { iconMarginTop, itemIconSize } = themeTokens
48
- let adjustedIconMarginTop = iconMarginTop
49
64
  const { fontSize, lineHeight: lineHeightRatio } = useThemeTokens(
50
65
  'Typography',
51
66
  {},
52
67
  { size: 'h4', bold: true }
53
68
  )
54
- if (title) {
55
- adjustedIconMarginTop = (fontSize * lineHeightRatio - itemIconSize) / 2
56
- }
69
+ const adjustedIconMarginTop = title
70
+ ? calculateIconMarginTop(itemIconSize, fontSize, lineHeightRatio)
71
+ : iconMarginTop
72
+
57
73
  /**
58
74
  * Function responsible returning styling, in case the item is the last shouldn't
59
75
  * add extra margin on the bottom, if "showDivider" is true it should add a divider
@@ -81,14 +97,14 @@ const ListItemBase = React.forwardRef(
81
97
  {typeof children === 'function' ? (
82
98
  children({ tokens, icon, iconColor, iconSize, isLastItem })
83
99
  ) : (
84
- <View style={staticStyles.container}>
100
+ <View style={[staticStyles.innerContainer, selectAlignmentStyles(iconVerticalAlign)]}>
85
101
  <ListItemMark
86
102
  tokens={{ ...tokens, iconMarginTop: adjustedIconMarginTop }}
87
103
  icon={icon}
88
104
  iconColor={iconColor}
89
105
  iconSize={iconSize}
90
106
  />
91
- <View style={staticStyles.titleAndContentContainer}>
107
+ <View style={[staticStyles.titleAndContentContainer]}>
92
108
  {Boolean(title) && (
93
109
  <Typography variant={{ size: 'h4', bold: true }}>{title}</Typography>
94
110
  )}
@@ -101,16 +117,22 @@ const ListItemBase = React.forwardRef(
101
117
  }
102
118
  )
103
119
  ListItemBase.displayName = 'ListItem'
120
+ ListItemBase.__UDS_COMPONENT_TYPE__ = 'ListItem'
104
121
 
105
122
  const staticStyles = StyleSheet.create({
106
123
  container: {
124
+ flexDirection: 'row',
125
+ width: '100%'
126
+ },
127
+ innerContainer: {
107
128
  flex: 1,
108
129
  flexDirection: 'row'
109
130
  },
110
131
  titleAndContentContainer: {
111
132
  flexDirection: 'column',
112
- flexShrink: 1,
113
- flexGrow: 1
133
+ flex: 1,
134
+ flexGrow: 1,
135
+ flexShrink: 1
114
136
  }
115
137
  })
116
138
 
@@ -119,6 +141,8 @@ ListItemBase.propTypes = {
119
141
  tokens: getTokensPropType('List'),
120
142
  variant: variantProp.propType,
121
143
  children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
144
+ /** Controls the vertical alignment of the icon */
145
+ iconVerticalAlign: PropTypes.oneOf(['top', 'center', 'bottom']),
122
146
  /**
123
147
  * Renders side item icon
124
148
  */
@@ -1,7 +1,6 @@
1
1
  import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
-
4
- import { View, StyleSheet } from 'react-native'
3
+ import { View } from 'react-native'
5
4
  import Icon from '../Icon'
6
5
  import { useVariants } from '../utils'
7
6
 
@@ -9,33 +8,21 @@ 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
14
 
15
- const selectItemIconTokens = ({ itemIconSize, itemIconColor }) => ({
16
- size: itemIconSize,
17
- color: itemIconColor
18
- })
19
-
20
- const selectSideItemContainerStyles = ({ listGutter, iconMarginTop }) => ({
21
- marginTop: iconMarginTop,
22
- marginRight: listGutter
15
+ const selectContainerStyles = ({ listGutter }) => ({
16
+ marginInlineEnd: listGutter,
17
+ display: 'flex',
18
+ alignItems: 'flex-start'
23
19
  })
24
-
25
- // Align bullets with the top line of text the same way icons are aligned
26
- const selectBulletPositioningStyles = ({ itemIconSize }) => ({
20
+ const selectBulletStyles = ({ itemIconSize }) => ({
27
21
  width: itemIconSize,
28
- height: itemIconSize
29
- })
30
-
31
- const selectBulletContainerStyles = ({
32
- itemBulletContainerWidth,
33
- itemBulletContainerHeight,
34
- itemBulletContainerAlign
35
- }) => ({
36
- width: itemBulletContainerWidth,
37
- height: itemBulletContainerHeight,
38
- alignItems: itemBulletContainerAlign
22
+ height: itemIconSize,
23
+ alignItems: 'center',
24
+ justifyContent: 'center',
25
+ flexShrink: 0
39
26
  })
40
27
 
41
28
  const getIconColorVariants = (iconVariants) =>
@@ -50,26 +37,24 @@ const getIconColorVariants = (iconVariants) =>
50
37
  */
51
38
  const ListItemMark = React.forwardRef(({ icon, iconColor, iconSize, tokens = {} }, ref) => {
52
39
  const themeTokens = typeof tokens === 'function' ? tokens() : tokens
40
+ const containerStyles = selectContainerStyles(themeTokens)
53
41
 
54
- const sideItemContainerStyles = selectSideItemContainerStyles(themeTokens)
55
- const bulletContainerStyles = selectBulletContainerStyles(themeTokens)
56
-
57
- // TODO: Remove it when iconColor custom colors are deprecated.
58
42
  const iconVariants = useVariants('Icon')
59
43
  const iconColorVariants = getIconColorVariants(iconVariants)
60
44
 
61
45
  if (icon) {
62
- const iconTokens = selectItemIconTokens(themeTokens)
46
+ const { itemIconSize, itemIconColor } = themeTokens
47
+ const finalIconSize = iconSize ?? itemIconSize
48
+ const finalIconColor =
49
+ iconColor && !iconColorVariants?.includes(iconColor) ? iconColor : itemIconColor
50
+
63
51
  return (
64
- <View style={[sideItemContainerStyles, bulletContainerStyles]}>
52
+ <View style={containerStyles}>
65
53
  <Icon
66
54
  icon={icon}
67
55
  tokens={{
68
- size: iconSize ?? iconTokens.size,
69
- ...(((iconColor && !iconColorVariants?.includes(iconColor)) || !iconColor) && {
70
- color:
71
- iconColor && !iconColorVariants?.includes(iconColor) ? iconColor : iconTokens.color
72
- })
56
+ size: finalIconSize,
57
+ color: finalIconColor
73
58
  }}
74
59
  variant={{
75
60
  ...(iconColorVariants?.includes(iconColor) && { color: iconColor })
@@ -79,18 +64,19 @@ const ListItemMark = React.forwardRef(({ icon, iconColor, iconSize, tokens = {}
79
64
  )
80
65
  }
81
66
 
82
- const bulletColor = themeTokens.itemBulletColor
83
- const { bulletIcon } = themeTokens
84
- const itemBulletContainerStyles = selectBulletContainerStyles(themeTokens)
85
- const itemBulletPositioningStyles = selectBulletPositioningStyles(themeTokens)
67
+ const { itemIconSize, itemIconColor } = themeTokens
68
+ const bulletStyles = selectBulletStyles(themeTokens)
86
69
 
87
70
  return (
88
- <View style={[sideItemContainerStyles, itemBulletContainerStyles]} ref={ref}>
89
- <View
90
- style={[staticStyles.bulletPositioning, itemBulletPositioningStyles]}
91
- testID="unordered-item-bullet"
92
- >
93
- <Icon icon={bulletIcon} tokens={{ color: bulletColor, size: themeTokens.itemIconSize }} />
71
+ <View style={containerStyles} ref={ref}>
72
+ <View style={bulletStyles}>
73
+ <Icon
74
+ icon={themeTokens.bulletIcon}
75
+ tokens={{
76
+ color: itemIconColor,
77
+ size: itemIconSize
78
+ }}
79
+ />
94
80
  </View>
95
81
  </View>
96
82
  )
@@ -114,11 +100,4 @@ ListItemMark.propTypes = {
114
100
  iconSize: PropTypes.number
115
101
  }
116
102
 
117
- const staticStyles = StyleSheet.create({
118
- bulletPositioning: {
119
- alignItems: 'center',
120
- justifyContent: 'center'
121
- }
122
- })
123
-
124
103
  export default ListItemMark
@@ -81,6 +81,7 @@ const PressableListItemBase = React.forwardRef(
81
81
  )
82
82
 
83
83
  PressableListItemBase.displayName = 'PressableListItemBase'
84
+ PressableListItemBase.__UDS_COMPONENT_TYPE__ = 'ListItem'
84
85
 
85
86
  const staticStyles = StyleSheet.create({
86
87
  itemContainer: {