@telus-uds/components-base 3.28.2 → 3.29.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 +16 -1
- package/lib/cjs/Card/CardBase.js +12 -0
- package/lib/cjs/ColourToggle/ColourBubble.js +17 -3
- package/lib/cjs/ColourToggle/ColourToggle.js +8 -2
- package/lib/cjs/ExpandCollapse/Control.js +17 -3
- package/lib/cjs/ExpandCollapse/Panel.js +6 -0
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMini.js +14 -2
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMiniControl.js +15 -2
- package/lib/cjs/Link/ChevronLink.js +1 -0
- package/lib/cjs/Link/LinkBase.js +29 -13
- package/lib/cjs/Link/MobileIconTextContent.js +156 -0
- package/lib/cjs/TabBar/TabBar.js +7 -2
- package/lib/esm/Card/CardBase.js +12 -0
- package/lib/esm/ColourToggle/ColourBubble.js +17 -3
- package/lib/esm/ColourToggle/ColourToggle.js +8 -2
- package/lib/esm/ExpandCollapse/Control.js +17 -3
- package/lib/esm/ExpandCollapse/Panel.js +6 -0
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMini.js +14 -2
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMiniControl.js +15 -2
- package/lib/esm/Link/ChevronLink.js +1 -0
- package/lib/esm/Link/LinkBase.js +29 -13
- package/lib/esm/Link/MobileIconTextContent.js +147 -0
- package/lib/esm/TabBar/TabBar.js +7 -2
- package/lib/package.json +1 -1
- package/package.json +1 -1
- package/src/Card/CardBase.jsx +12 -0
- package/src/ColourToggle/ColourBubble.jsx +18 -3
- package/src/ColourToggle/ColourToggle.jsx +7 -2
- package/src/ExpandCollapse/Control.jsx +24 -4
- package/src/ExpandCollapse/Panel.jsx +6 -0
- package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +23 -3
- package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +14 -2
- package/src/Link/ChevronLink.jsx +1 -0
- package/src/Link/LinkBase.jsx +47 -20
- package/src/Link/MobileIconTextContent.jsx +129 -0
- package/src/TabBar/TabBar.jsx +21 -4
|
@@ -90,6 +90,7 @@ const ExpandCollapsePanel = React.forwardRef(
|
|
|
90
90
|
onPress,
|
|
91
91
|
control,
|
|
92
92
|
controlTokens,
|
|
93
|
+
controlAlign,
|
|
93
94
|
children,
|
|
94
95
|
tokens,
|
|
95
96
|
variant,
|
|
@@ -174,6 +175,7 @@ const ExpandCollapsePanel = React.forwardRef(
|
|
|
174
175
|
{...selectedProps}
|
|
175
176
|
isExpanded={isExpanded}
|
|
176
177
|
tokens={controlTokens}
|
|
178
|
+
controlAlign={controlAlign}
|
|
177
179
|
variant={variant}
|
|
178
180
|
onPress={handleControlPress}
|
|
179
181
|
ref={controlRef}
|
|
@@ -284,6 +286,10 @@ ExpandCollapsePanel.propTypes = {
|
|
|
284
286
|
* Optional theme token overrides that may be passed to the ExpandCollapseControl element.
|
|
285
287
|
*/
|
|
286
288
|
controlTokens: getTokensPropType('ExpandCollapseControl'),
|
|
289
|
+
/**
|
|
290
|
+
* Optional alignment for control content.
|
|
291
|
+
*/
|
|
292
|
+
controlAlign: PropTypes.oneOf(['flex-start', 'center', 'flex-end']),
|
|
287
293
|
/**
|
|
288
294
|
* An optional ref to be attached to the control
|
|
289
295
|
*/
|
|
@@ -7,9 +7,24 @@ import ExpandCollapseMiniControl from './ExpandCollapseMiniControl'
|
|
|
7
7
|
|
|
8
8
|
const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([contentfulProps])
|
|
9
9
|
|
|
10
|
+
const alignMap = {
|
|
11
|
+
start: 'flex-start',
|
|
12
|
+
middle: 'center',
|
|
13
|
+
end: 'flex-end'
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
const ExpandCollapseMini = React.forwardRef(
|
|
11
17
|
(
|
|
12
|
-
{
|
|
18
|
+
{
|
|
19
|
+
children,
|
|
20
|
+
onToggle = () => {},
|
|
21
|
+
tokens = {},
|
|
22
|
+
nativeID,
|
|
23
|
+
initialOpen = false,
|
|
24
|
+
dataSet,
|
|
25
|
+
align,
|
|
26
|
+
...rest
|
|
27
|
+
},
|
|
13
28
|
ref
|
|
14
29
|
) => {
|
|
15
30
|
const expandCollapeMiniPanelId = useUniqueId('ExpandCollapseMiniPanel')
|
|
@@ -40,10 +55,11 @@ const ExpandCollapseMini = React.forwardRef(
|
|
|
40
55
|
textLine: tokens.textLine ?? 'none',
|
|
41
56
|
backgroundColor: 'transparent'
|
|
42
57
|
}}
|
|
58
|
+
controlAlign={align && alignMap[align]}
|
|
43
59
|
// TODO refactor
|
|
44
60
|
// eslint-disable-next-line react/no-unstable-nested-components
|
|
45
61
|
control={(pressableState) => (
|
|
46
|
-
<ExpandCollapseMiniControl pressableState={pressableState} {...rest} />
|
|
62
|
+
<ExpandCollapseMiniControl pressableState={pressableState} align={align} {...rest} />
|
|
47
63
|
)}
|
|
48
64
|
controlRef={ref}
|
|
49
65
|
nativeID={nativeID}
|
|
@@ -87,7 +103,11 @@ ExpandCollapseMini.propTypes = {
|
|
|
87
103
|
/**
|
|
88
104
|
* The dataSet prop allows to pass data-* attributes element to the component.
|
|
89
105
|
*/
|
|
90
|
-
dataSet: PropTypes.object
|
|
106
|
+
dataSet: PropTypes.object,
|
|
107
|
+
/**
|
|
108
|
+
* Controls the horizontal alignment of the trigger label and icon within the panel width.
|
|
109
|
+
*/
|
|
110
|
+
align: PropTypes.oneOf(['start', 'middle', 'end'])
|
|
91
111
|
}
|
|
92
112
|
|
|
93
113
|
export default ExpandCollapseMini
|
|
@@ -7,6 +7,12 @@ import { htmlAttrs, viewProps, selectSystemProps } from '../utils'
|
|
|
7
7
|
|
|
8
8
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([htmlAttrs, viewProps])
|
|
9
9
|
|
|
10
|
+
const alignSelfMap = {
|
|
11
|
+
start: 'flex-start',
|
|
12
|
+
middle: 'center',
|
|
13
|
+
end: 'flex-end'
|
|
14
|
+
}
|
|
15
|
+
|
|
10
16
|
// The ExpandCollapseControl has all the appropriate role, a11y, press handling etc
|
|
11
17
|
// and a more appropriate press area, defer interaction handling to it.
|
|
12
18
|
const presentationOnly = {
|
|
@@ -24,6 +30,7 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
24
30
|
iconPosition = 'right',
|
|
25
31
|
tokens,
|
|
26
32
|
variant = {},
|
|
33
|
+
align,
|
|
27
34
|
...rest
|
|
28
35
|
},
|
|
29
36
|
ref
|
|
@@ -96,7 +103,8 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
96
103
|
...getTokens(linkState),
|
|
97
104
|
iconSize,
|
|
98
105
|
blockFontSize: fontSize,
|
|
99
|
-
blockLineHeight: lineHeight
|
|
106
|
+
blockLineHeight: lineHeight,
|
|
107
|
+
...(align && { alignSelf: alignSelfMap[align] })
|
|
100
108
|
})}
|
|
101
109
|
ref={ref}
|
|
102
110
|
{...presentationOnly}
|
|
@@ -132,7 +140,11 @@ ExpandCollapseMiniControl.propTypes = {
|
|
|
132
140
|
/**
|
|
133
141
|
* Optional variant object to override the default theme tokens
|
|
134
142
|
*/
|
|
135
|
-
variant: PropTypes.object
|
|
143
|
+
variant: PropTypes.object,
|
|
144
|
+
/**
|
|
145
|
+
* Controls the horizontal alignment of the trigger label and icon
|
|
146
|
+
*/
|
|
147
|
+
align: PropTypes.oneOf(['start', 'middle', 'end'])
|
|
136
148
|
}
|
|
137
149
|
|
|
138
150
|
export default ExpandCollapseMiniControl
|
package/src/Link/ChevronLink.jsx
CHANGED
package/src/Link/LinkBase.jsx
CHANGED
|
@@ -16,6 +16,7 @@ import { resolvePressableTokens } from '../utils/pressability'
|
|
|
16
16
|
import { withLinkRouter } from '../utils'
|
|
17
17
|
|
|
18
18
|
import InlinePressable from './InlinePressable'
|
|
19
|
+
import MobileIconTextContent from './MobileIconTextContent'
|
|
19
20
|
import { applyTextStyles, applyOuterBorder, useTheme } from '../ThemeProvider'
|
|
20
21
|
import { IconText, iconComponentPropTypes } from '../Icon'
|
|
21
22
|
|
|
@@ -133,6 +134,7 @@ const LinkBase = React.forwardRef(
|
|
|
133
134
|
tokens = {},
|
|
134
135
|
children,
|
|
135
136
|
dataSet,
|
|
137
|
+
useMeasuredMobileIconLayout = false,
|
|
136
138
|
accessibilityRole = 'link',
|
|
137
139
|
...rawRest
|
|
138
140
|
},
|
|
@@ -171,12 +173,14 @@ const LinkBase = React.forwardRef(
|
|
|
171
173
|
const themeTokens = resolveLinkTokens(linkState)
|
|
172
174
|
const outerBorderStyles = selectOuterBorderStyles(themeTokens)
|
|
173
175
|
const decorationStyles = selectDecorationStyles(themeTokens)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
+
const shouldUseMeasuredMobileContent =
|
|
177
|
+
Platform.OS !== 'web' && useMeasuredMobileIconLayout
|
|
176
178
|
|
|
177
179
|
return [
|
|
178
180
|
outerBorderStyles,
|
|
179
|
-
|
|
181
|
+
shouldUseMeasuredMobileContent
|
|
182
|
+
? staticStyles.measuredMobileOuterBorderCompensation
|
|
183
|
+
: null,
|
|
180
184
|
blockLeftStyle,
|
|
181
185
|
decorationStyles,
|
|
182
186
|
hasIcon && staticStyles.rowContainer
|
|
@@ -196,28 +200,50 @@ const LinkBase = React.forwardRef(
|
|
|
196
200
|
|
|
197
201
|
const isTextOnlyLink = !IconComponent && !icon && accessibilityRole === 'link'
|
|
198
202
|
const adjustedIconSpace = Platform.OS !== 'web' && isTextOnlyLink ? 0 : iconSpace
|
|
203
|
+
const shouldUseMeasuredMobileContent =
|
|
204
|
+
Platform.OS !== 'web' && useMeasuredMobileIconLayout
|
|
205
|
+
const textBaselineStyle = shouldUseMeasuredMobileContent ? null : staticStyles.baseline
|
|
206
|
+
|
|
207
|
+
const linkTextContent = (
|
|
208
|
+
<Text
|
|
209
|
+
style={[
|
|
210
|
+
textStyles,
|
|
211
|
+
blockTextStyles,
|
|
212
|
+
textBaselineStyle,
|
|
213
|
+
staticStyles.bubblePointerEvents
|
|
214
|
+
]}
|
|
215
|
+
>
|
|
216
|
+
{typeof children === 'function' ? children(linkState) : children}
|
|
217
|
+
</Text>
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
const sharedIconProps = {
|
|
221
|
+
...iconProps,
|
|
222
|
+
tokens: iconTokens,
|
|
223
|
+
style: staticStyles.bubblePointerEvents
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (shouldUseMeasuredMobileContent) {
|
|
227
|
+
return (
|
|
228
|
+
<MobileIconTextContent
|
|
229
|
+
icon={IconComponent}
|
|
230
|
+
iconPosition={iconPosition}
|
|
231
|
+
space={adjustedIconSpace}
|
|
232
|
+
iconProps={sharedIconProps}
|
|
233
|
+
>
|
|
234
|
+
{linkTextContent}
|
|
235
|
+
</MobileIconTextContent>
|
|
236
|
+
)
|
|
237
|
+
}
|
|
199
238
|
|
|
200
239
|
return (
|
|
201
240
|
<IconText
|
|
202
241
|
icon={IconComponent}
|
|
203
242
|
iconPosition={iconPosition}
|
|
204
243
|
space={adjustedIconSpace}
|
|
205
|
-
iconProps={
|
|
206
|
-
...iconProps,
|
|
207
|
-
tokens: iconTokens,
|
|
208
|
-
style: staticStyles.bubblePointerEvents
|
|
209
|
-
}}
|
|
244
|
+
iconProps={sharedIconProps}
|
|
210
245
|
>
|
|
211
|
-
|
|
212
|
-
style={[
|
|
213
|
-
textStyles,
|
|
214
|
-
blockTextStyles,
|
|
215
|
-
staticStyles.baseline,
|
|
216
|
-
staticStyles.bubblePointerEvents
|
|
217
|
-
]}
|
|
218
|
-
>
|
|
219
|
-
{typeof children === 'function' ? children(linkState) : children}
|
|
220
|
-
</Text>
|
|
246
|
+
{linkTextContent}
|
|
221
247
|
</IconText>
|
|
222
248
|
)
|
|
223
249
|
}}
|
|
@@ -280,11 +306,12 @@ const staticStyles = StyleSheet.create({
|
|
|
280
306
|
}
|
|
281
307
|
})
|
|
282
308
|
},
|
|
283
|
-
|
|
309
|
+
measuredMobileOuterBorderCompensation: {
|
|
284
310
|
...(Platform.OS !== 'web' && {
|
|
285
311
|
marginHorizontal: 2,
|
|
312
|
+
marginVertical: 2,
|
|
286
313
|
paddingHorizontal: Platform.OS === 'android' ? 2 : 0,
|
|
287
|
-
|
|
314
|
+
paddingVertical: Platform.OS === 'android' ? 2 : 0
|
|
288
315
|
})
|
|
289
316
|
}
|
|
290
317
|
})
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import { Text, View, StyleSheet } from 'react-native'
|
|
4
|
+
|
|
5
|
+
import Icon, { iconComponentPropTypes } from '../Icon/Icon'
|
|
6
|
+
import { spacingProps } from '../utils'
|
|
7
|
+
|
|
8
|
+
const MobileIconTextContent = React.forwardRef(
|
|
9
|
+
({ space = 0, iconPosition = 'left', icon: IconComponent, iconProps = {}, children }, ref) => {
|
|
10
|
+
const [translateY, setTranslateY] = React.useState(0)
|
|
11
|
+
const latestTranslateYRef = React.useRef(0)
|
|
12
|
+
const layoutsRef = React.useRef({
|
|
13
|
+
container: null,
|
|
14
|
+
text: null,
|
|
15
|
+
icon: null
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const applyAlignment = React.useCallback(() => {
|
|
19
|
+
const { container, text, icon } = layoutsRef.current
|
|
20
|
+
|
|
21
|
+
if (!container || !icon || !icon.height) return
|
|
22
|
+
|
|
23
|
+
const targetY = text ? text.y + text.height / 2 : container.height / 2
|
|
24
|
+
const iconY = icon.y + icon.height / 2
|
|
25
|
+
const nextTranslateY = Math.round((targetY - iconY) * 100) / 100
|
|
26
|
+
|
|
27
|
+
if (!Number.isFinite(nextTranslateY)) return
|
|
28
|
+
if (Math.abs(nextTranslateY - latestTranslateYRef.current) < 0.5) return
|
|
29
|
+
|
|
30
|
+
latestTranslateYRef.current = nextTranslateY
|
|
31
|
+
setTranslateY(nextTranslateY)
|
|
32
|
+
}, [])
|
|
33
|
+
|
|
34
|
+
const handleContainerLayout = React.useCallback(
|
|
35
|
+
({ nativeEvent: { layout } }) => {
|
|
36
|
+
layoutsRef.current.container = layout
|
|
37
|
+
applyAlignment()
|
|
38
|
+
},
|
|
39
|
+
[applyAlignment]
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const handleTextLayout = React.useCallback(
|
|
43
|
+
({ nativeEvent: { layout } }) => {
|
|
44
|
+
layoutsRef.current.text = layout
|
|
45
|
+
applyAlignment()
|
|
46
|
+
},
|
|
47
|
+
[applyAlignment]
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
const handleIconLayout = React.useCallback(
|
|
51
|
+
({ nativeEvent: { layout } }) => {
|
|
52
|
+
layoutsRef.current.icon = layout
|
|
53
|
+
applyAlignment()
|
|
54
|
+
},
|
|
55
|
+
[applyAlignment]
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
const iconContent = IconComponent ? (
|
|
59
|
+
<Icon ref={ref} icon={IconComponent} scalesWithText {...iconProps} />
|
|
60
|
+
) : null
|
|
61
|
+
|
|
62
|
+
const iconWrapper = IconComponent ? (
|
|
63
|
+
<View
|
|
64
|
+
onLayout={handleIconLayout}
|
|
65
|
+
style={[staticStyles.iconContainer, { transform: [{ translateY }] }]}
|
|
66
|
+
>
|
|
67
|
+
{iconContent}
|
|
68
|
+
</View>
|
|
69
|
+
) : null
|
|
70
|
+
|
|
71
|
+
if (iconPosition === 'inline') {
|
|
72
|
+
return (
|
|
73
|
+
<Text onLayout={handleContainerLayout}>
|
|
74
|
+
<Text onLayout={handleTextLayout}>{children}</Text>{' '}
|
|
75
|
+
<View style={staticStyles.inlineIconContainer}>{iconWrapper}</View>
|
|
76
|
+
</Text>
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const iconSpaceStyle = iconPosition === 'left' ? { marginRight: space } : { marginLeft: space }
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<View onLayout={handleContainerLayout} style={staticStyles.rowContainer}>
|
|
84
|
+
{iconPosition === 'left' && <View style={iconSpaceStyle}>{iconWrapper}</View>}
|
|
85
|
+
<View onLayout={handleTextLayout}>{children}</View>
|
|
86
|
+
{iconPosition === 'right' && <View style={iconSpaceStyle}>{iconWrapper}</View>}
|
|
87
|
+
</View>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
MobileIconTextContent.displayName = 'MobileIconTextContent'
|
|
93
|
+
|
|
94
|
+
MobileIconTextContent.propTypes = {
|
|
95
|
+
/**
|
|
96
|
+
* Amount of space between text and icon. Uses the theme spacing scale.
|
|
97
|
+
*/
|
|
98
|
+
space: spacingProps.types.spacingValue,
|
|
99
|
+
/**
|
|
100
|
+
* Position of the icon relative to text.
|
|
101
|
+
*/
|
|
102
|
+
iconPosition: PropTypes.oneOf(['left', 'right', 'inline']),
|
|
103
|
+
/**
|
|
104
|
+
* A valid UDS icon component imported from a UDS palette.
|
|
105
|
+
*/
|
|
106
|
+
icon: PropTypes.elementType,
|
|
107
|
+
/**
|
|
108
|
+
* Props passed to the icon component.
|
|
109
|
+
*/
|
|
110
|
+
iconProps: PropTypes.exact(iconComponentPropTypes),
|
|
111
|
+
/**
|
|
112
|
+
* Content rendered alongside the icon.
|
|
113
|
+
*/
|
|
114
|
+
children: PropTypes.node
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const staticStyles = StyleSheet.create({
|
|
118
|
+
rowContainer: {
|
|
119
|
+
flexDirection: 'row'
|
|
120
|
+
},
|
|
121
|
+
iconContainer: {
|
|
122
|
+
alignSelf: 'flex-start'
|
|
123
|
+
},
|
|
124
|
+
inlineIconContainer: {
|
|
125
|
+
position: 'absolute'
|
|
126
|
+
}
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
export default MobileIconTextContent
|
package/src/TabBar/TabBar.jsx
CHANGED
|
@@ -42,12 +42,24 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, vie
|
|
|
42
42
|
* items={items}
|
|
43
43
|
* initiallySelectedItem="1"
|
|
44
44
|
* onChange={(itemId) => console.log(itemId)}
|
|
45
|
+
* accessibilityLabel="Main navigation"
|
|
45
46
|
* />
|
|
46
47
|
* )
|
|
47
48
|
*/
|
|
48
49
|
|
|
49
50
|
const TabBar = React.forwardRef(
|
|
50
|
-
(
|
|
51
|
+
(
|
|
52
|
+
{
|
|
53
|
+
items = [],
|
|
54
|
+
initiallySelectedItem = '0',
|
|
55
|
+
onChange,
|
|
56
|
+
variant,
|
|
57
|
+
tokens,
|
|
58
|
+
accessibilityLabel,
|
|
59
|
+
...rest
|
|
60
|
+
},
|
|
61
|
+
ref
|
|
62
|
+
) => {
|
|
51
63
|
const [isSelected, setIsSelected] = React.useState(initiallySelectedItem)
|
|
52
64
|
const themeTokens = useThemeTokens('TabBar', tokens, variant)
|
|
53
65
|
|
|
@@ -62,7 +74,11 @@ const TabBar = React.forwardRef(
|
|
|
62
74
|
style={[styles.tabBar, selectTabBarContainerStyles(themeTokens)]}
|
|
63
75
|
{...selectProps(rest)}
|
|
64
76
|
>
|
|
65
|
-
<View
|
|
77
|
+
<View
|
|
78
|
+
style={[styles.tabBarItem, selectTabBarItemContainerStyles(themeTokens)]}
|
|
79
|
+
accessibilityRole="tablist"
|
|
80
|
+
accessibilityLabel={accessibilityLabel}
|
|
81
|
+
>
|
|
66
82
|
{items.map((item, index) => (
|
|
67
83
|
<TabBarItem
|
|
68
84
|
key={item.id}
|
|
@@ -73,7 +89,6 @@ const TabBar = React.forwardRef(
|
|
|
73
89
|
iconActive={item.iconActive}
|
|
74
90
|
onPress={() => handlePress(item.id)}
|
|
75
91
|
id={`tab-item-${index}`}
|
|
76
|
-
accessibilityRole="tablist"
|
|
77
92
|
tokens={item.tokens}
|
|
78
93
|
/>
|
|
79
94
|
))}
|
|
@@ -105,7 +120,9 @@ TabBar.propTypes = {
|
|
|
105
120
|
/** Variant of TabBar for styling purposes. */
|
|
106
121
|
variant: variantProp.propType,
|
|
107
122
|
/** Tokens for theming and styling. */
|
|
108
|
-
tokens: getTokensPropType('TabBar')
|
|
123
|
+
tokens: getTokensPropType('TabBar'),
|
|
124
|
+
/** Accessible label for the tab bar navigation region, used by screen readers to identify the tablist. */
|
|
125
|
+
accessibilityLabel: PropTypes.string
|
|
109
126
|
}
|
|
110
127
|
|
|
111
128
|
const styles = StyleSheet.create({
|