@telus-uds/components-base 1.14.1 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -2
- package/__tests17__/A11yText/A11yText.test.jsx +34 -0
- package/__tests17__/ActivityIndicator/ActivityIndicator.test.jsx +68 -0
- package/__tests17__/ActivityIndicator/__snapshots__/ActivityIndicator.test.jsx.snap +299 -0
- package/__tests17__/Box/Box.test.jsx +111 -0
- package/__tests17__/Button/Button.test.jsx +86 -0
- package/__tests17__/Button/ButtonBase.test.jsx +82 -0
- package/__tests17__/Button/ButtonGroup.test.jsx +347 -0
- package/__tests17__/Button/ButtonLink.test.jsx +61 -0
- package/__tests17__/Card/Card.test.jsx +63 -0
- package/__tests17__/Carousel/Carousel.test.jsx +128 -0
- package/__tests17__/Carousel/CarouselTabs.test.jsx +142 -0
- package/__tests17__/Checkbox/Checkbox.test.jsx +94 -0
- package/__tests17__/Checkbox/CheckboxGroup.test.jsx +246 -0
- package/__tests17__/Divider/Divider.test.jsx +91 -0
- package/__tests17__/ExpandCollapse/ExpandCollapse.test.jsx +109 -0
- package/__tests17__/Feedback/Feedback.test.jsx +42 -0
- package/__tests17__/FlexGrid/Col.test.jsx +261 -0
- package/__tests17__/FlexGrid/FlexGrid.test.jsx +136 -0
- package/__tests17__/FlexGrid/Row.test.jsx +273 -0
- package/__tests17__/HorizontalScroll/HorizontalScroll.test.jsx +165 -0
- package/__tests17__/Icon/Icon.test.jsx +61 -0
- package/__tests17__/IconButton/IconButton.test.jsx +52 -0
- package/__tests17__/InputLabel/InputLabel.test.jsx +28 -0
- package/__tests17__/InputLabel/__snapshots__/InputLabel.test.jsx.snap +3 -0
- package/__tests17__/InputSupports/InputSupports.test.jsx +60 -0
- package/__tests17__/Link/Link.test.jsx +63 -0
- package/__tests17__/Link/TextButton.test.jsx +35 -0
- package/__tests17__/List/List.test.jsx +82 -0
- package/__tests17__/Modal/Modal.test.jsx +47 -0
- package/__tests17__/Notification/Notification.test.jsx +20 -0
- package/__tests17__/Pagination/Pagination.test.jsx +160 -0
- package/__tests17__/Progress/Progress.test.jsx +79 -0
- package/__tests17__/Radio/Radio.test.jsx +87 -0
- package/__tests17__/Radio/RadioGroup.test.jsx +220 -0
- package/__tests17__/RadioCard/RadioCard.test.jsx +87 -0
- package/__tests17__/RadioCard/RadioCardGroup.test.jsx +246 -0
- package/__tests17__/Search/Search.test.jsx +87 -0
- package/__tests17__/Select/Select.test.jsx +94 -0
- package/__tests17__/SideNav/SideNav.test.jsx +110 -0
- package/__tests17__/Skeleton/Skeleton.test.jsx +61 -0
- package/__tests17__/SkipLink/SkipLink.test.jsx +61 -0
- package/__tests17__/Spacer/Spacer.test.jsx +63 -0
- package/__tests17__/StackView/StackView.test.jsx +211 -0
- package/__tests17__/StackView/StackWrap.test.jsx +47 -0
- package/__tests17__/StackView/getStackedContent.test.jsx +295 -0
- package/__tests17__/StepTracker/StepTracker.test.jsx +108 -0
- package/__tests17__/Tabs/Tabs.test.jsx +49 -0
- package/__tests17__/Tags/Tags.test.jsx +327 -0
- package/__tests17__/TextInput/TextArea.test.jsx +35 -0
- package/__tests17__/TextInput/TextInputBase.test.jsx +125 -0
- package/__tests17__/ThemeProvider/ThemeProvider.test.jsx +80 -0
- package/__tests17__/ThemeProvider/useThemeTokens.test.jsx +514 -0
- package/__tests17__/ThemeProvider/utils/theme-tokens.test.js +41 -0
- package/__tests17__/ToggleSwitch/ToggleSwitch.test.jsx +82 -0
- package/__tests17__/ToggleSwitch/ToggleSwitchGroup.test.jsx +192 -0
- package/__tests17__/Tooltip/Tooltip.test.jsx +65 -0
- package/__tests17__/Tooltip/getTooltipPosition.test.js +79 -0
- package/__tests17__/Typography/typography.test.jsx +90 -0
- package/__tests17__/utils/children.test.jsx +128 -0
- package/__tests17__/utils/containUniqueFields.test.js +25 -0
- package/__tests17__/utils/input.test.js +375 -0
- package/__tests17__/utils/props.test.js +36 -0
- package/__tests17__/utils/semantics.test.jsx +34 -0
- package/__tests17__/utils/useCopy.test.js +42 -0
- package/__tests17__/utils/useResponsiveProp.test.jsx +202 -0
- package/__tests17__/utils/useSpacingScale.test.jsx +273 -0
- package/__tests17__/utils/useUniqueId.test.js +31 -0
- package/component-docs.json +95 -438
- package/lib/A11yInfoProvider/index.js +14 -5
- package/lib/Button/ButtonGroup.js +3 -2
- package/lib/Checkbox/Checkbox.js +9 -6
- package/lib/ExpandCollapse/Control.js +6 -5
- package/lib/ExpandCollapse/Panel.js +5 -4
- package/lib/List/ListItem.js +10 -236
- package/lib/List/ListItemBase.js +162 -0
- package/lib/List/ListItemContent.js +85 -0
- package/lib/List/ListItemMark.js +158 -0
- package/lib/List/PressableListItemBase.js +147 -0
- package/lib/Notification/Notification.js +2 -1
- package/lib/Pagination/Pagination.js +4 -3
- package/lib/Pagination/SideButton.js +17 -7
- package/lib/Radio/Radio.js +9 -6
- package/lib/RadioCard/RadioCard.js +9 -6
- package/lib/Select/Select.js +1 -0
- package/lib/Tabs/Tabs.js +12 -3
- package/lib/Tags/Tags.js +3 -3
- package/lib/TextInput/TextInput.js +5 -4
- package/lib/ViewportProvider/useViewportListener.js +11 -5
- package/lib/utils/hasOwnProperty.js +18 -0
- package/lib/utils/props/a11yProps.js +212 -45
- package/lib/utils/props/getPropSelector.js +47 -5
- package/lib/utils/ssr.js +116 -1
- package/lib/utils/useResponsiveProp.js +5 -3
- package/lib/utils/withLinkRouter.js +3 -5
- package/lib-module/A11yInfoProvider/index.js +14 -4
- package/lib-module/Button/ButtonGroup.js +3 -2
- package/lib-module/Checkbox/Checkbox.js +9 -6
- package/lib-module/ExpandCollapse/Control.js +6 -5
- package/lib-module/ExpandCollapse/Panel.js +5 -4
- package/lib-module/List/ListItem.js +13 -235
- package/lib-module/List/ListItemBase.js +139 -0
- package/lib-module/List/ListItemContent.js +66 -0
- package/lib-module/List/ListItemMark.js +143 -0
- package/lib-module/List/PressableListItemBase.js +117 -0
- package/lib-module/Notification/Notification.js +2 -1
- package/lib-module/Pagination/Pagination.js +5 -3
- package/lib-module/Pagination/SideButton.js +18 -8
- package/lib-module/Radio/Radio.js +9 -6
- package/lib-module/RadioCard/RadioCard.js +9 -6
- package/lib-module/Select/Select.js +1 -0
- package/lib-module/Tabs/Tabs.js +13 -4
- package/lib-module/Tags/Tags.js +3 -3
- package/lib-module/TextInput/TextInput.js +5 -4
- package/lib-module/ViewportProvider/useViewportListener.js +10 -4
- package/lib-module/utils/hasOwnProperty.js +11 -0
- package/lib-module/utils/props/a11yProps.js +210 -45
- package/lib-module/utils/props/getPropSelector.js +44 -5
- package/lib-module/utils/ssr.js +106 -0
- package/lib-module/utils/useResponsiveProp.js +3 -4
- package/lib-module/utils/withLinkRouter.js +3 -5
- package/package.json +12 -17
- package/src/A11yInfoProvider/index.jsx +20 -4
- package/src/Button/ButtonGroup.jsx +4 -2
- package/src/Checkbox/Checkbox.jsx +7 -3
- package/src/ExpandCollapse/Control.jsx +8 -5
- package/src/ExpandCollapse/Panel.jsx +7 -5
- package/src/List/ListItem.jsx +12 -191
- package/src/List/ListItemBase.jsx +118 -0
- package/src/List/ListItemContent.jsx +52 -0
- package/src/List/ListItemMark.jsx +99 -0
- package/src/List/PressableListItemBase.jsx +102 -0
- package/src/Notification/Notification.jsx +1 -1
- package/src/Pagination/Pagination.jsx +6 -1
- package/src/Pagination/SideButton.jsx +4 -1
- package/src/Radio/Radio.jsx +7 -3
- package/src/RadioCard/RadioCard.jsx +7 -3
- package/src/Select/Select.jsx +1 -1
- package/src/Tabs/Tabs.jsx +19 -2
- package/src/Tags/Tags.jsx +3 -3
- package/src/TextInput/TextInput.jsx +4 -4
- package/src/ViewportProvider/useViewportListener.js +10 -5
- package/src/utils/hasOwnProperty.js +11 -0
- package/src/utils/props/a11yProps.js +168 -55
- package/src/utils/props/getPropSelector.js +45 -4
- package/src/utils/ssr.jsx +124 -0
- package/src/utils/useResponsiveProp.js +3 -3
- package/src/utils/withLinkRouter.jsx +1 -3
- package/src/utils/ssr.js +0 -35
|
@@ -60,11 +60,13 @@ const ExpandCollapsePanel = forwardRef(
|
|
|
60
60
|
const [containerHeight, setContainerHeight] = useState(null)
|
|
61
61
|
const isExpanded = openIds.includes(panelId)
|
|
62
62
|
|
|
63
|
-
const selectedProps = selectProps(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
const selectedProps = selectProps({
|
|
64
|
+
...rest,
|
|
65
|
+
accessibilityState: {
|
|
66
|
+
...(rest.accessibilityState || {}),
|
|
67
|
+
expanded: isExpanded
|
|
68
|
+
}
|
|
69
|
+
})
|
|
68
70
|
|
|
69
71
|
const themeTokens = useThemeTokens('ExpandCollapsePanel', tokens, variant, {
|
|
70
72
|
expanded: isExpanded
|
package/src/List/ListItem.jsx
CHANGED
|
@@ -1,204 +1,25 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react'
|
|
2
|
-
import { View, Platform, StyleSheet } from 'react-native'
|
|
3
|
-
import PropTypes from 'prop-types'
|
|
4
|
-
import { useTheme, useThemeTokens, applyTextStyles } from '../ThemeProvider'
|
|
5
|
-
import {
|
|
6
|
-
a11yProps,
|
|
7
|
-
getTokensPropType,
|
|
8
|
-
selectSystemProps,
|
|
9
|
-
variantProp,
|
|
10
|
-
viewProps,
|
|
11
|
-
wrapStringsInText
|
|
12
|
-
} from '../utils'
|
|
13
2
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
width: itemBulletWidth,
|
|
18
|
-
height: itemBulletHeight,
|
|
19
|
-
borderRadius: itemBulletHeight / 2,
|
|
20
|
-
backgroundColor: itemBulletColor
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
const selectBulletContainerStyles = ({ itemBulletContainerWidth, itemBulletContainerAlign }) => ({
|
|
24
|
-
width: itemBulletContainerWidth,
|
|
25
|
-
alignItems: itemBulletContainerAlign
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
const selectItemIconTokens = ({ itemIconSize, itemIconColor }) => ({
|
|
29
|
-
size: itemIconSize,
|
|
30
|
-
color: itemIconColor
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
const selectSideItemContainerStyles = ({ listGutter, iconMarginTop }) => ({
|
|
34
|
-
marginTop: iconMarginTop,
|
|
35
|
-
marginRight: listGutter
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
// Align bullets with the top line of text the same way icons are aligned
|
|
39
|
-
const selectBulletPositioningStyles = ({ itemIconSize }) => ({
|
|
40
|
-
width: itemIconSize,
|
|
41
|
-
height: itemIconSize
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
const selectItemStyles = (
|
|
45
|
-
{ itemFontWeight, itemFontSize, itemLineHeight, itemFontName },
|
|
46
|
-
themeOptions
|
|
47
|
-
) =>
|
|
48
|
-
applyTextStyles({
|
|
49
|
-
fontWeight: itemFontWeight,
|
|
50
|
-
fontSize: itemFontSize,
|
|
51
|
-
lineHeight: itemLineHeight,
|
|
52
|
-
fontName: itemFontName,
|
|
53
|
-
themeOptions
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
const selectItemBlockStyles = ({ interItemMargin }) => ({
|
|
57
|
-
marginBottom: interItemMargin
|
|
58
|
-
})
|
|
59
|
-
|
|
60
|
-
const selectDividerStyles = ({ dividerColor, dividerSize, interItemMarginWithDivider }) => ({
|
|
61
|
-
borderBottomWidth: dividerSize,
|
|
62
|
-
borderColor: dividerColor,
|
|
63
|
-
marginBottom: interItemMarginWithDivider,
|
|
64
|
-
paddingBottom: interItemMarginWithDivider
|
|
65
|
-
})
|
|
3
|
+
import ListItemBase from './ListItemBase'
|
|
4
|
+
import { useThemeTokens } from '../ThemeProvider'
|
|
5
|
+
import { variantProp } from '../utils'
|
|
66
6
|
|
|
67
7
|
/**
|
|
68
8
|
* ListItem is responsible for rendering icon or a bullet as side item
|
|
69
9
|
*/
|
|
70
|
-
const ListItem = forwardRef(
|
|
71
|
-
(
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
iconSize,
|
|
78
|
-
showDivider,
|
|
79
|
-
children,
|
|
80
|
-
isLastItem,
|
|
81
|
-
accessibilityRole = Platform.select({ web: 'listitem', default: undefined }),
|
|
82
|
-
...rest
|
|
83
|
-
},
|
|
84
|
-
ref
|
|
85
|
-
) => {
|
|
86
|
-
const themeTokens = useThemeTokens('List', tokens, variant)
|
|
87
|
-
const { themeOptions } = useTheme()
|
|
88
|
-
|
|
89
|
-
const itemStyles = selectItemStyles(themeTokens, themeOptions)
|
|
90
|
-
const itemBlockStyles = selectItemBlockStyles(themeTokens)
|
|
91
|
-
const dividerStyles = selectDividerStyles(themeTokens)
|
|
92
|
-
const itemBulletContainerStyles = selectBulletContainerStyles(themeTokens)
|
|
93
|
-
const itemBulletStyles = selectBulletStyles(themeTokens)
|
|
94
|
-
const itemBulletPositioningStyles = selectBulletPositioningStyles(themeTokens)
|
|
95
|
-
const iconTokens = selectItemIconTokens(themeTokens)
|
|
96
|
-
const sideItemContainerStyles = selectSideItemContainerStyles(themeTokens)
|
|
97
|
-
|
|
98
|
-
const renderItem = () => (
|
|
99
|
-
<View style={staticStyles.wrap}>{wrapStringsInText(children, { style: itemStyles })}</View>
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Function responsible returning styling, in case the item is the last shouldn't
|
|
104
|
-
* add extra margin on the bottom, if "showDivider" is true it should add a divider
|
|
105
|
-
* and custom margin and padding, otherwise just adds a margin to the bottom
|
|
106
|
-
*/
|
|
107
|
-
const getContainerStyle = () => {
|
|
108
|
-
if (isLastItem) {
|
|
109
|
-
return undefined
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (showDivider) {
|
|
113
|
-
return dividerStyles
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
return itemBlockStyles
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Renders item bullet or Icon in case it's defined
|
|
121
|
-
* in case children are string the icon is centered otherwise
|
|
122
|
-
* it will align itself at start of the container
|
|
123
|
-
*/
|
|
124
|
-
const renderMarker = () => {
|
|
125
|
-
const IconComponent = icon || <></>
|
|
126
|
-
|
|
127
|
-
if (icon) {
|
|
128
|
-
return (
|
|
129
|
-
<View style={sideItemContainerStyles}>
|
|
130
|
-
<IconComponent
|
|
131
|
-
size={iconSize || iconTokens.size}
|
|
132
|
-
color={iconColor || iconTokens.color}
|
|
133
|
-
/>
|
|
134
|
-
</View>
|
|
135
|
-
)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return (
|
|
139
|
-
<View style={[sideItemContainerStyles, itemBulletContainerStyles]}>
|
|
140
|
-
<View style={[staticStyles.bulletPositioning, itemBulletPositioningStyles]}>
|
|
141
|
-
<View style={itemBulletStyles} testID="unordered-item-bullet" />
|
|
142
|
-
</View>
|
|
143
|
-
</View>
|
|
144
|
-
)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return (
|
|
148
|
-
<View
|
|
149
|
-
ref={ref}
|
|
150
|
-
style={[staticStyles.itemContainer, getContainerStyle()]}
|
|
151
|
-
accessibilityRole={accessibilityRole}
|
|
152
|
-
{...selectProps(rest)}
|
|
153
|
-
>
|
|
154
|
-
{renderMarker()}
|
|
155
|
-
{renderItem()}
|
|
156
|
-
</View>
|
|
157
|
-
)
|
|
158
|
-
}
|
|
159
|
-
)
|
|
160
|
-
ListItem.displayName = 'ListItem'
|
|
161
|
-
|
|
162
|
-
const staticStyles = StyleSheet.create({
|
|
163
|
-
itemContainer: {
|
|
164
|
-
flexDirection: 'row'
|
|
165
|
-
},
|
|
166
|
-
wrap: {
|
|
167
|
-
flex: 1
|
|
168
|
-
},
|
|
169
|
-
bulletPositioning: {
|
|
170
|
-
alignItems: 'center',
|
|
171
|
-
justifyContent: 'center'
|
|
172
|
-
}
|
|
10
|
+
const ListItem = forwardRef(({ tokens, variant, children, ...listItemProps }, ref) => {
|
|
11
|
+
const themeTokens = useThemeTokens('List', tokens, variant)
|
|
12
|
+
return (
|
|
13
|
+
<ListItemBase tokens={themeTokens} ref={ref} {...listItemProps}>
|
|
14
|
+
{children}
|
|
15
|
+
</ListItemBase>
|
|
16
|
+
)
|
|
173
17
|
})
|
|
18
|
+
ListItem.displayName = 'ListItem'
|
|
174
19
|
|
|
175
20
|
ListItem.propTypes = {
|
|
176
|
-
...selectedSystemPropTypes,
|
|
177
|
-
tokens: getTokensPropType('List'),
|
|
178
21
|
variant: variantProp.propType,
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Renders side item icon
|
|
182
|
-
*/
|
|
183
|
-
icon: PropTypes.elementType,
|
|
184
|
-
/**
|
|
185
|
-
* Will set display icon color
|
|
186
|
-
*/
|
|
187
|
-
iconColor: PropTypes.string,
|
|
188
|
-
/**
|
|
189
|
-
* Allow the user define the icon size if not defined the theme's file
|
|
190
|
-
*/
|
|
191
|
-
iconSize: PropTypes.number,
|
|
192
|
-
/**
|
|
193
|
-
* @ignore
|
|
194
|
-
* Defined by parent if it's last item on the list
|
|
195
|
-
*/
|
|
196
|
-
isLastItem: PropTypes.bool,
|
|
197
|
-
/**
|
|
198
|
-
* @ignore
|
|
199
|
-
* In case it is not the last item allow display divider
|
|
200
|
-
*/
|
|
201
|
-
showDivider: PropTypes.bool
|
|
22
|
+
...ListItemBase.propTypes
|
|
202
23
|
}
|
|
203
24
|
|
|
204
25
|
export default ListItem
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
|
+
import { View, Platform, StyleSheet } from 'react-native'
|
|
3
|
+
import PropTypes from 'prop-types'
|
|
4
|
+
import { a11yProps, getTokensPropType, selectSystemProps, variantProp, viewProps } from '../utils'
|
|
5
|
+
|
|
6
|
+
import ListItemContent from './ListItemContent'
|
|
7
|
+
import ListItemMark from './ListItemMark'
|
|
8
|
+
|
|
9
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
10
|
+
|
|
11
|
+
const selectItemBlockStyles = ({ interItemMargin }) => ({
|
|
12
|
+
marginBottom: interItemMargin
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
const selectDividerStyles = ({ dividerColor, dividerSize, interItemMarginWithDivider }) => ({
|
|
16
|
+
borderBottomWidth: dividerSize,
|
|
17
|
+
borderColor: dividerColor,
|
|
18
|
+
marginBottom: interItemMarginWithDivider,
|
|
19
|
+
paddingBottom: interItemMarginWithDivider
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* ListItem is responsible for rendering icon or a bullet as side item
|
|
24
|
+
*/
|
|
25
|
+
const ListItemBase = forwardRef(
|
|
26
|
+
(
|
|
27
|
+
{
|
|
28
|
+
tokens,
|
|
29
|
+
icon,
|
|
30
|
+
iconColor,
|
|
31
|
+
iconSize,
|
|
32
|
+
showDivider,
|
|
33
|
+
children,
|
|
34
|
+
isLastItem,
|
|
35
|
+
accessibilityRole = Platform.select({ web: 'listitem', default: undefined }),
|
|
36
|
+
...rest
|
|
37
|
+
},
|
|
38
|
+
ref
|
|
39
|
+
) => {
|
|
40
|
+
const themeTokens = typeof tokens === 'function' ? tokens() : tokens
|
|
41
|
+
|
|
42
|
+
const itemBlockStyles = selectItemBlockStyles(themeTokens)
|
|
43
|
+
const dividerStyles = selectDividerStyles(themeTokens)
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Function responsible returning styling, in case the item is the last shouldn't
|
|
47
|
+
* add extra margin on the bottom, if "showDivider" is true it should add a divider
|
|
48
|
+
* and custom margin and padding, otherwise just adds a margin to the bottom
|
|
49
|
+
*/
|
|
50
|
+
const getContainerStyle = () => {
|
|
51
|
+
if (isLastItem) {
|
|
52
|
+
return undefined
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (showDivider) {
|
|
56
|
+
return dividerStyles
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return itemBlockStyles
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<View
|
|
64
|
+
ref={ref}
|
|
65
|
+
style={[staticStyles.itemContainer, getContainerStyle()]}
|
|
66
|
+
accessibilityRole={accessibilityRole}
|
|
67
|
+
{...selectProps(rest)}
|
|
68
|
+
>
|
|
69
|
+
{typeof children === 'function' ? (
|
|
70
|
+
children({ tokens, icon, iconColor, iconSize, isLastItem })
|
|
71
|
+
) : (
|
|
72
|
+
<>
|
|
73
|
+
<ListItemMark tokens={tokens} icon={icon} iconColor={iconColor} iconSize={iconSize} />
|
|
74
|
+
<ListItemContent tokens={tokens}>{children}</ListItemContent>
|
|
75
|
+
</>
|
|
76
|
+
)}
|
|
77
|
+
</View>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
ListItemBase.displayName = 'ListItem'
|
|
82
|
+
|
|
83
|
+
const staticStyles = StyleSheet.create({
|
|
84
|
+
itemContainer: {
|
|
85
|
+
flexDirection: 'row'
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
ListItemBase.propTypes = {
|
|
90
|
+
...selectedSystemPropTypes,
|
|
91
|
+
tokens: getTokensPropType('List'),
|
|
92
|
+
variant: variantProp.propType,
|
|
93
|
+
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired,
|
|
94
|
+
/**
|
|
95
|
+
* Renders side item icon
|
|
96
|
+
*/
|
|
97
|
+
icon: PropTypes.elementType,
|
|
98
|
+
/**
|
|
99
|
+
* Will set display icon color
|
|
100
|
+
*/
|
|
101
|
+
iconColor: PropTypes.string,
|
|
102
|
+
/**
|
|
103
|
+
* Allow the user define the icon size if not defined the theme's file
|
|
104
|
+
*/
|
|
105
|
+
iconSize: PropTypes.number,
|
|
106
|
+
/**
|
|
107
|
+
* @ignore
|
|
108
|
+
* Defined by parent if it's last item on the list
|
|
109
|
+
*/
|
|
110
|
+
isLastItem: PropTypes.bool,
|
|
111
|
+
/**
|
|
112
|
+
* @ignore
|
|
113
|
+
* In case it is not the last item allow display divider
|
|
114
|
+
*/
|
|
115
|
+
showDivider: PropTypes.bool
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export default ListItemBase
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import { View, StyleSheet } from 'react-native'
|
|
5
|
+
import { wrapStringsInText } from '../utils'
|
|
6
|
+
import { useTheme, applyTextStyles } from '../ThemeProvider'
|
|
7
|
+
|
|
8
|
+
export const tokenTypes = {
|
|
9
|
+
itemFontWeight: PropTypes.string.isRequired,
|
|
10
|
+
itemFontSize: PropTypes.number.isRequired,
|
|
11
|
+
itemLineHeight: PropTypes.number.isRequired,
|
|
12
|
+
itemFontName: PropTypes.string.isRequired
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const selectItemTextStyles = (
|
|
16
|
+
{ itemFontWeight, itemFontSize, itemLineHeight, itemFontName },
|
|
17
|
+
themeOptions
|
|
18
|
+
) =>
|
|
19
|
+
applyTextStyles({
|
|
20
|
+
fontWeight: itemFontWeight,
|
|
21
|
+
fontSize: itemFontSize,
|
|
22
|
+
lineHeight: itemLineHeight,
|
|
23
|
+
fontName: itemFontName,
|
|
24
|
+
themeOptions
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Subcomponent used within ListItem and similar components for rendering content that fills
|
|
29
|
+
* and wraps available space in a { flexDirection: row } container alongside a ListIconMark,
|
|
30
|
+
* and that applies text styles to strings via supplied tokens.
|
|
31
|
+
*
|
|
32
|
+
* It's the responsibility of themes to make sure that these text tokens align the first line of
|
|
33
|
+
* text nicely against the bullet or icon rendered by ListIconMark.
|
|
34
|
+
*/
|
|
35
|
+
const ListItemContent = ({ tokens, children }) => {
|
|
36
|
+
const { themeOptions } = useTheme()
|
|
37
|
+
const textStyles = selectItemTextStyles(tokens, themeOptions)
|
|
38
|
+
return <View style={staticStyles.wrap}>{wrapStringsInText(children, { style: textStyles })}</View>
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const staticStyles = StyleSheet.create({
|
|
42
|
+
wrap: {
|
|
43
|
+
flex: 1
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
ListItemContent.propTypes = {
|
|
48
|
+
tokens: PropTypes.shape(tokenTypes).isRequired,
|
|
49
|
+
children: PropTypes.node.isRequired
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default ListItemContent
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
|
|
4
|
+
import { View, StyleSheet } from 'react-native'
|
|
5
|
+
|
|
6
|
+
export const tokenTypes = {
|
|
7
|
+
itemIconSize: PropTypes.number.isRequired,
|
|
8
|
+
itemIconColor: PropTypes.string.isRequired,
|
|
9
|
+
listGutter: PropTypes.number.isRequired,
|
|
10
|
+
iconMarginTop: PropTypes.number.isRequired
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const selectItemIconTokens = ({ itemIconSize, itemIconColor }) => ({
|
|
14
|
+
size: itemIconSize,
|
|
15
|
+
color: itemIconColor
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const selectSideItemContainerStyles = ({ listGutter, iconMarginTop }) => ({
|
|
19
|
+
marginTop: iconMarginTop,
|
|
20
|
+
marginRight: listGutter
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
// Align bullets with the top line of text the same way icons are aligned
|
|
24
|
+
const selectBulletPositioningStyles = ({ itemIconSize }) => ({
|
|
25
|
+
width: itemIconSize,
|
|
26
|
+
height: itemIconSize
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
const selectBulletStyles = ({ itemBulletWidth, itemBulletHeight, itemBulletColor }) => ({
|
|
30
|
+
width: itemBulletWidth,
|
|
31
|
+
height: itemBulletHeight,
|
|
32
|
+
borderRadius: itemBulletHeight / 2,
|
|
33
|
+
backgroundColor: itemBulletColor
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const selectBulletContainerStyles = ({ itemBulletContainerWidth, itemBulletContainerAlign }) => ({
|
|
37
|
+
width: itemBulletContainerWidth,
|
|
38
|
+
alignItems: itemBulletContainerAlign
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Subcomponent used within ListItem and similar components for rendering bullets or icons
|
|
43
|
+
* that sit alongside a ListIconContent in a { flexDirection: row } container.
|
|
44
|
+
*
|
|
45
|
+
* It's the responsibility of themes to make sure that the supplied tokens align the
|
|
46
|
+
* icon or bullet nicely against the first line of text in a ListIconContent.
|
|
47
|
+
*/
|
|
48
|
+
const ListItemMark = ({ icon, iconColor, iconSize, tokens = {} }) => {
|
|
49
|
+
const IconComponent = icon || <></>
|
|
50
|
+
|
|
51
|
+
const themeTokens = typeof tokens === 'function' ? tokens() : tokens
|
|
52
|
+
|
|
53
|
+
const sideItemContainerStyles = selectSideItemContainerStyles(themeTokens)
|
|
54
|
+
|
|
55
|
+
if (icon) {
|
|
56
|
+
const iconTokens = selectItemIconTokens(themeTokens)
|
|
57
|
+
return (
|
|
58
|
+
<View style={sideItemContainerStyles}>
|
|
59
|
+
<IconComponent size={iconSize || iconTokens.size} color={iconColor || iconTokens.color} />
|
|
60
|
+
</View>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const itemBulletContainerStyles = selectBulletContainerStyles(themeTokens)
|
|
65
|
+
const itemBulletStyles = selectBulletStyles(themeTokens)
|
|
66
|
+
const itemBulletPositioningStyles = selectBulletPositioningStyles(themeTokens)
|
|
67
|
+
return (
|
|
68
|
+
<View style={[sideItemContainerStyles, itemBulletContainerStyles]}>
|
|
69
|
+
<View style={[staticStyles.bulletPositioning, itemBulletPositioningStyles]}>
|
|
70
|
+
<View style={itemBulletStyles} testID="unordered-item-bullet" />
|
|
71
|
+
</View>
|
|
72
|
+
</View>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
ListItemMark.propTypes = {
|
|
77
|
+
tokens: PropTypes.shape(tokenTypes).isRequired,
|
|
78
|
+
/**
|
|
79
|
+
* Renders side item icon
|
|
80
|
+
*/
|
|
81
|
+
icon: PropTypes.elementType,
|
|
82
|
+
/**
|
|
83
|
+
* Will set display icon color
|
|
84
|
+
*/
|
|
85
|
+
iconColor: PropTypes.string,
|
|
86
|
+
/**
|
|
87
|
+
* Allow the user define the icon size
|
|
88
|
+
*/
|
|
89
|
+
iconSize: PropTypes.number
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const staticStyles = StyleSheet.create({
|
|
93
|
+
bulletPositioning: {
|
|
94
|
+
alignItems: 'center',
|
|
95
|
+
justifyContent: 'center'
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
export default ListItemMark
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import ABBPropTypes from 'airbnb-prop-types'
|
|
4
|
+
|
|
5
|
+
import { Pressable, StyleSheet, Platform } from 'react-native'
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
resolvePressableTokens,
|
|
9
|
+
clickProps,
|
|
10
|
+
linkProps,
|
|
11
|
+
hrefAttrsProp,
|
|
12
|
+
withLinkRouter
|
|
13
|
+
} from '../utils'
|
|
14
|
+
|
|
15
|
+
import ListItemBase from './ListItemBase'
|
|
16
|
+
import ListItemContent, { tokenTypes as contentTokenTypes } from './ListItemContent'
|
|
17
|
+
import ListItemMark, { tokenTypes as markTokenTypes } from './ListItemMark'
|
|
18
|
+
|
|
19
|
+
const selectPressableStyles = ({
|
|
20
|
+
backgroundColor,
|
|
21
|
+
paddingLeft,
|
|
22
|
+
paddingRight,
|
|
23
|
+
paddingTop,
|
|
24
|
+
paddingBottom,
|
|
25
|
+
interItemMargin
|
|
26
|
+
}) => ({
|
|
27
|
+
backgroundColor,
|
|
28
|
+
paddingLeft,
|
|
29
|
+
paddingRight,
|
|
30
|
+
paddingTop,
|
|
31
|
+
paddingBottom,
|
|
32
|
+
marginBottom: interItemMargin,
|
|
33
|
+
...Platform.select({ web: { outline: 'none' } })
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const PressableListItemBase = forwardRef(
|
|
37
|
+
({ href, tokens, icon, children, listItemRef, ...rest }, ref) => {
|
|
38
|
+
const { onPress, ...props } = clickProps.toPressProps(rest)
|
|
39
|
+
const { hrefAttrs, rest: listItemProps } = hrefAttrsProp.bundle(props)
|
|
40
|
+
const handlePress = linkProps.handleHref({ href, onPress })
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<ListItemBase ref={listItemRef} tokens={tokens()} {...listItemProps}>
|
|
44
|
+
{({ isLastItem }) => {
|
|
45
|
+
const getTokens = (pressableState) =>
|
|
46
|
+
resolvePressableTokens(tokens, pressableState, { last: isLastItem })
|
|
47
|
+
const getPressableStyle = (pressableState) => [
|
|
48
|
+
staticStyles.itemContainer,
|
|
49
|
+
selectPressableStyles(getTokens(pressableState))
|
|
50
|
+
]
|
|
51
|
+
return (
|
|
52
|
+
<Pressable
|
|
53
|
+
onPress={handlePress}
|
|
54
|
+
href={href}
|
|
55
|
+
hrefAttrs={hrefAttrs}
|
|
56
|
+
style={getPressableStyle}
|
|
57
|
+
ref={ref}
|
|
58
|
+
>
|
|
59
|
+
{(pressableState) => {
|
|
60
|
+
const themeTokens = getTokens(pressableState)
|
|
61
|
+
return (
|
|
62
|
+
<>
|
|
63
|
+
<ListItemMark icon={icon} tokens={themeTokens} />
|
|
64
|
+
<ListItemContent tokens={themeTokens}>
|
|
65
|
+
{typeof children === 'function' ? children(pressableState) : children}
|
|
66
|
+
</ListItemContent>
|
|
67
|
+
</>
|
|
68
|
+
)
|
|
69
|
+
}}
|
|
70
|
+
</Pressable>
|
|
71
|
+
)
|
|
72
|
+
}}
|
|
73
|
+
</ListItemBase>
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
PressableListItemBase.displayName = 'PressableListItemBase'
|
|
79
|
+
|
|
80
|
+
const staticStyles = StyleSheet.create({
|
|
81
|
+
itemContainer: {
|
|
82
|
+
flexDirection: 'row',
|
|
83
|
+
flex: 1
|
|
84
|
+
},
|
|
85
|
+
tokens: {
|
|
86
|
+
...contentTokenTypes,
|
|
87
|
+
...markTokenTypes
|
|
88
|
+
}
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
PressableListItemBase.propTypes = {
|
|
92
|
+
href: PropTypes.string,
|
|
93
|
+
onPress: PropTypes.func,
|
|
94
|
+
// TODO - type this better, maybe import the subcomponent token types and run it through util
|
|
95
|
+
// eslint-disable-next-line react/forbid-prop-types
|
|
96
|
+
tokens: PropTypes.any,
|
|
97
|
+
icon: PropTypes.elementType,
|
|
98
|
+
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
|
99
|
+
listItemRef: ABBPropTypes.ref()
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export default withLinkRouter(PressableListItemBase)
|
|
@@ -112,7 +112,7 @@ const Notification = forwardRef(
|
|
|
112
112
|
const textStyles = selectTextStyles(themeTokens, themeOptions)
|
|
113
113
|
|
|
114
114
|
const content = wrapStringsInText(
|
|
115
|
-
typeof children === 'function' ? children({ textStyles }) : children,
|
|
115
|
+
typeof children === 'function' ? children({ textStyles, variant }) : children,
|
|
116
116
|
{ style: textStyles }
|
|
117
117
|
)
|
|
118
118
|
|
|
@@ -103,12 +103,17 @@ const Pagination = forwardRef(
|
|
|
103
103
|
label={buttonLabel}
|
|
104
104
|
copy={copy}
|
|
105
105
|
isActive={isItemActive(itemIndex)}
|
|
106
|
+
key={buttonLabel}
|
|
106
107
|
/>
|
|
107
108
|
)
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
if (shouldRenderEllipsis(itemIndex)) {
|
|
111
|
-
return
|
|
112
|
+
return (
|
|
113
|
+
<Text key="..." style={ellipsisTextStyles}>
|
|
114
|
+
...
|
|
115
|
+
</Text>
|
|
116
|
+
)
|
|
112
117
|
}
|
|
113
118
|
|
|
114
119
|
return null
|
|
@@ -12,6 +12,9 @@ import { copyPropTypes, hrefAttrsProp, linkProps, selectTokens, withLinkRouter }
|
|
|
12
12
|
import dictionary from './dictionary'
|
|
13
13
|
import useCopy from '../utils/useCopy'
|
|
14
14
|
|
|
15
|
+
// We need to drop the icon here since it gets rendered via children and not
|
|
16
|
+
// `ButtonBase` in order to tap into the state of the button
|
|
17
|
+
const selectButtonTokens = ({ icon: _, ...rest }) => selectTokens('Button', rest)
|
|
15
18
|
const selectIconTokens = ({ color, iconSize, iconDisplace }, direction) => {
|
|
16
19
|
return {
|
|
17
20
|
color,
|
|
@@ -35,7 +38,7 @@ const SideButton = forwardRef(
|
|
|
35
38
|
|
|
36
39
|
const { icon } = getTokens(tokens, buttonVariant)
|
|
37
40
|
|
|
38
|
-
const getButtonTokens = (buttonState) =>
|
|
41
|
+
const getButtonTokens = (buttonState) => selectButtonTokens(getTokens(buttonState))
|
|
39
42
|
const getIconTokens = (buttonState) => selectIconTokens(getTokens(buttonState), direction)
|
|
40
43
|
|
|
41
44
|
const label = direction === 'previous' ? getCopy('previousText') : getCopy('nextText')
|
package/src/Radio/Radio.jsx
CHANGED
|
@@ -151,15 +151,19 @@ const Radio = forwardRef(
|
|
|
151
151
|
const uniqueId = useUniqueId('radio')
|
|
152
152
|
const inputId = id ?? uniqueId
|
|
153
153
|
|
|
154
|
+
const selectedProps = selectProps({
|
|
155
|
+
accessibilityRole: 'radio',
|
|
156
|
+
accessibilityState: { checked: isChecked, disabled: inactive },
|
|
157
|
+
...rest
|
|
158
|
+
})
|
|
159
|
+
|
|
154
160
|
return (
|
|
155
161
|
<Pressable
|
|
156
162
|
ref={ref}
|
|
157
163
|
disabled={inactive}
|
|
158
164
|
onKeyDown={handleKeyDown}
|
|
159
165
|
onPress={handleChange}
|
|
160
|
-
|
|
161
|
-
accessibilityState={{ checked: isChecked, disabled: inactive }}
|
|
162
|
-
{...selectProps(rest)}
|
|
166
|
+
{...selectedProps}
|
|
163
167
|
>
|
|
164
168
|
{({ focused: focus, hovered: hover, pressed }) => {
|
|
165
169
|
const stateTokens = getTokens({ focus, hover, pressed })
|