@telus-uds/components-base 3.5.2 → 3.7.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 +29 -2
- package/lib/cjs/Box/Box.js +53 -7
- package/lib/cjs/Card/Card.js +12 -2
- package/lib/cjs/Card/PressableCardBase.js +67 -1
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMini.js +5 -0
- package/lib/cjs/ExpandCollapseMini/ExpandCollapseMiniControl.js +17 -26
- package/lib/cjs/Icon/Icon.js +2 -1
- package/lib/cjs/InputLabel/InputLabel.js +9 -3
- package/lib/cjs/InputSupports/InputSupports.js +6 -2
- package/lib/cjs/List/ListItemMark.js +8 -4
- package/lib/cjs/MultiSelectFilter/MultiSelectFilter.js +7 -1
- package/lib/cjs/ToggleSwitch/ToggleSwitch.js +11 -3
- package/lib/cjs/ToggleSwitch/ToggleSwitchGroup.js +9 -1
- package/lib/cjs/Tooltip/shared.js +5 -4
- package/lib/cjs/utils/getSpacingScale.js +66 -0
- package/lib/cjs/utils/index.js +9 -1
- package/lib/cjs/utils/props/inputSupportsProps.js +6 -2
- package/lib/esm/Box/Box.js +55 -9
- package/lib/esm/Card/Card.js +13 -3
- package/lib/esm/Card/PressableCardBase.js +67 -1
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMini.js +5 -0
- package/lib/esm/ExpandCollapseMini/ExpandCollapseMiniControl.js +17 -26
- package/lib/esm/Icon/Icon.js +2 -1
- package/lib/esm/InputLabel/InputLabel.js +9 -3
- package/lib/esm/InputSupports/InputSupports.js +6 -2
- package/lib/esm/List/ListItemMark.js +9 -5
- package/lib/esm/MultiSelectFilter/MultiSelectFilter.js +7 -1
- package/lib/esm/ToggleSwitch/ToggleSwitch.js +11 -3
- package/lib/esm/ToggleSwitch/ToggleSwitchGroup.js +9 -1
- package/lib/esm/Tooltip/shared.js +2 -1
- package/lib/esm/utils/getSpacingScale.js +61 -0
- package/lib/esm/utils/index.js +2 -1
- package/lib/esm/utils/props/inputSupportsProps.js +6 -2
- package/lib/package.json +4 -4
- package/package.json +4 -4
- package/src/Box/Box.jsx +61 -8
- package/src/Card/Card.jsx +20 -3
- package/src/Card/PressableCardBase.jsx +60 -2
- package/src/ExpandCollapseMini/ExpandCollapseMini.jsx +5 -0
- package/src/ExpandCollapseMini/ExpandCollapseMiniControl.jsx +17 -21
- package/src/Icon/Icon.jsx +6 -1
- package/src/InputLabel/InputLabel.jsx +7 -2
- package/src/InputSupports/InputSupports.jsx +6 -2
- package/src/List/ListItemMark.jsx +5 -3
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +7 -1
- package/src/ToggleSwitch/ToggleSwitch.jsx +14 -2
- package/src/ToggleSwitch/ToggleSwitchGroup.jsx +9 -1
- package/src/Tooltip/shared.js +2 -2
- package/src/utils/getSpacingScale.js +50 -0
- package/src/utils/index.js +1 -0
- package/src/utils/props/inputSupportsProps.js +6 -2
- package/types/ToggleSwitch.d.ts +1 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
|
+
import tooltipPropTypes from '../../Tooltip/shared';
|
|
2
3
|
export default {
|
|
3
4
|
types: {
|
|
4
5
|
/**
|
|
@@ -31,9 +32,12 @@ export default {
|
|
|
31
32
|
*/
|
|
32
33
|
feedbackProps: PropTypes.object,
|
|
33
34
|
/**
|
|
34
|
-
*
|
|
35
|
+
* an optional `Tooltip`. If set, tooltip will be shown next to the label.
|
|
36
|
+
* Props can be passed to the tooltip in one of the following ways.
|
|
37
|
+
* 1. `tooltip` as a string - The content of the tooltip.
|
|
38
|
+
* 2. `tooltip` as an object - Tooltip component props to be passed.
|
|
35
39
|
*/
|
|
36
|
-
tooltip: PropTypes.string,
|
|
40
|
+
tooltip: PropTypes.oneOfType([tooltipPropTypes, PropTypes.string]),
|
|
37
41
|
/**
|
|
38
42
|
* Use to visually mark an input as valid or invalid.
|
|
39
43
|
*/
|
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.
|
|
15
|
+
"@telus-uds/system-theme-tokens": "^4.5.0",
|
|
16
16
|
"airbnb-prop-types": "^2.16.0",
|
|
17
17
|
"css-mediaquery": "^0.1.2",
|
|
18
18
|
"expo-document-picker": "^13.0.1",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"module": "lib/esm/index.js",
|
|
57
57
|
"name": "@telus-uds/components-base",
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"react": "
|
|
60
|
-
"react-dom": "
|
|
59
|
+
"react": ">=18.2.0 <19.0.0",
|
|
60
|
+
"react-dom": ">=18.2.0 <19.0.0",
|
|
61
61
|
"react-native": "^0.74.5",
|
|
62
62
|
"react-native-web": "^0.19.10",
|
|
63
63
|
"react-native-svg": "15.7.1"
|
|
@@ -84,6 +84,6 @@
|
|
|
84
84
|
"standard-engine": {
|
|
85
85
|
"skip": true
|
|
86
86
|
},
|
|
87
|
-
"version": "3.
|
|
87
|
+
"version": "3.7.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.
|
|
15
|
+
"@telus-uds/system-theme-tokens": "^4.5.0",
|
|
16
16
|
"airbnb-prop-types": "^2.16.0",
|
|
17
17
|
"css-mediaquery": "^0.1.2",
|
|
18
18
|
"expo-document-picker": "^13.0.1",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"module": "lib/esm/index.js",
|
|
57
57
|
"name": "@telus-uds/components-base",
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"react": "
|
|
60
|
-
"react-dom": "
|
|
59
|
+
"react": ">=18.2.0 <19.0.0",
|
|
60
|
+
"react-dom": ">=18.2.0 <19.0.0",
|
|
61
61
|
"react-native": "^0.74.5",
|
|
62
62
|
"react-native-web": "^0.19.10",
|
|
63
63
|
"react-native-svg": "15.7.1"
|
|
@@ -84,6 +84,6 @@
|
|
|
84
84
|
"standard-engine": {
|
|
85
85
|
"skip": true
|
|
86
86
|
},
|
|
87
|
-
"version": "3.
|
|
87
|
+
"version": "3.7.0",
|
|
88
88
|
"types": "types/index.d.ts"
|
|
89
89
|
}
|
package/src/Box/Box.jsx
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { View, ScrollView, Platform, StyleSheet, ImageBackground, Image } from 'react-native'
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
useTheme,
|
|
6
|
+
useThemeTokens,
|
|
7
|
+
useResponsiveThemeTokens,
|
|
8
|
+
useThemeTokensCallback
|
|
9
|
+
} from '../ThemeProvider'
|
|
5
10
|
import {
|
|
6
11
|
a11yProps,
|
|
12
|
+
createMediaQueryStyles,
|
|
7
13
|
getA11yPropsFromHtmlTag,
|
|
8
14
|
getTokensPropType,
|
|
9
15
|
layoutTags,
|
|
@@ -13,9 +19,12 @@ import {
|
|
|
13
19
|
useResponsiveProp,
|
|
14
20
|
useSpacingScale,
|
|
15
21
|
variantProp,
|
|
16
|
-
viewProps
|
|
22
|
+
viewProps,
|
|
23
|
+
StyleSheet as RNMQStyleSheet,
|
|
24
|
+
getSpacingScale
|
|
17
25
|
} from '../utils'
|
|
18
26
|
import backgroundImageStylesMap from './backgroundImageStylesMap'
|
|
27
|
+
import { useViewport } from '../ViewportProvider'
|
|
19
28
|
|
|
20
29
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
21
30
|
|
|
@@ -212,8 +221,20 @@ const Box = React.forwardRef(
|
|
|
212
221
|
...selectProps(rest)
|
|
213
222
|
}
|
|
214
223
|
|
|
215
|
-
const
|
|
216
|
-
const
|
|
224
|
+
const viewport = useViewport()
|
|
225
|
+
const { themeOptions } = useTheme()
|
|
226
|
+
const { enableMediaQueryStyleSheet } = themeOptions
|
|
227
|
+
|
|
228
|
+
const useTokens = enableMediaQueryStyleSheet ? useResponsiveThemeTokens : useThemeTokens
|
|
229
|
+
const themeTokens = useTokens(
|
|
230
|
+
'Box',
|
|
231
|
+
tokens,
|
|
232
|
+
variant,
|
|
233
|
+
!enableMediaQueryStyleSheet && { viewport }
|
|
234
|
+
)
|
|
235
|
+
const getSpacingTokens = useThemeTokensCallback('spacingScale')
|
|
236
|
+
|
|
237
|
+
let boxStyles = {
|
|
217
238
|
flex,
|
|
218
239
|
paddingLeft: useSpacingScale(left),
|
|
219
240
|
paddingRight: useSpacingScale(right),
|
|
@@ -221,10 +242,40 @@ const Box = React.forwardRef(
|
|
|
221
242
|
paddingBottom: useSpacingScale(bottom),
|
|
222
243
|
...selectBoxStyles(themeTokens, customGradient)
|
|
223
244
|
}
|
|
245
|
+
let boxMediaIds
|
|
246
|
+
|
|
247
|
+
if (enableMediaQueryStyleSheet) {
|
|
248
|
+
const { transformedThemeTokens } = Object.entries(themeTokens).reduce(
|
|
249
|
+
(acc, [vp]) => {
|
|
250
|
+
acc.transformedThemeTokens[vp] = {
|
|
251
|
+
paddingLeft: getSpacingScale(left, vp, getSpacingTokens),
|
|
252
|
+
paddingRight: getSpacingScale(right, vp, getSpacingTokens),
|
|
253
|
+
paddingTop: getSpacingScale(top, vp, getSpacingTokens),
|
|
254
|
+
paddingBottom: getSpacingScale(bottom, vp, getSpacingTokens)
|
|
255
|
+
}
|
|
256
|
+
return acc
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
transformedThemeTokens: {}
|
|
260
|
+
}
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
const mediaQueryStyles = createMediaQueryStyles(transformedThemeTokens)
|
|
264
|
+
const { ids } = RNMQStyleSheet.create({
|
|
265
|
+
box: {
|
|
266
|
+
...mediaQueryStyles
|
|
267
|
+
}
|
|
268
|
+
})
|
|
269
|
+
boxStyles = {
|
|
270
|
+
flex,
|
|
271
|
+
...selectBoxStyles(themeTokens[viewport], customGradient)
|
|
272
|
+
}
|
|
273
|
+
boxMediaIds = ids.box
|
|
274
|
+
}
|
|
224
275
|
|
|
225
276
|
let content = children
|
|
226
277
|
if (typeof customGradient === 'function')
|
|
227
|
-
content = customGradient(
|
|
278
|
+
content = customGradient(boxStyles.colors, boxStyles)(children)
|
|
228
279
|
|
|
229
280
|
const { src = '', alt = '', resizeMode = '', position = '', align = '' } = backgroundImage || {}
|
|
230
281
|
const backgroundImageResizeMode = useResponsiveProp(resizeMode, 'cover')
|
|
@@ -256,17 +307,19 @@ const Box = React.forwardRef(
|
|
|
256
307
|
}
|
|
257
308
|
}, [backgroundImage, backgroundImageWidth, backgroundImageHeight, src])
|
|
258
309
|
|
|
310
|
+
const dataSetValue = boxMediaIds ? { media: boxMediaIds, ...dataSet } : dataSet
|
|
311
|
+
|
|
259
312
|
if (scroll) {
|
|
260
313
|
const scrollProps = typeof scroll === 'object' ? scroll : {}
|
|
261
|
-
scrollProps.contentContainerStyle = [
|
|
314
|
+
scrollProps.contentContainerStyle = [boxStyles, scrollProps.contentContainerStyle]
|
|
262
315
|
return (
|
|
263
|
-
<ScrollView {...scrollProps} {...props} testID={testID} dataSet={
|
|
316
|
+
<ScrollView {...scrollProps} {...props} testID={testID} dataSet={dataSetValue} ref={ref}>
|
|
264
317
|
{content}
|
|
265
318
|
</ScrollView>
|
|
266
319
|
)
|
|
267
320
|
}
|
|
268
321
|
return (
|
|
269
|
-
<View {...props} style={
|
|
322
|
+
<View {...props} style={boxStyles} testID={testID} dataSet={dataSetValue} ref={ref}>
|
|
270
323
|
{content}
|
|
271
324
|
</View>
|
|
272
325
|
)
|
package/src/Card/Card.jsx
CHANGED
|
@@ -9,7 +9,14 @@ import {
|
|
|
9
9
|
} from '../ThemeProvider'
|
|
10
10
|
import { getTokensPropType, variantProp, StyleSheet, createMediaQueryStyles } from '../utils'
|
|
11
11
|
import { useViewport } from '../ViewportProvider'
|
|
12
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
a11yProps,
|
|
14
|
+
linkProps,
|
|
15
|
+
selectSystemProps,
|
|
16
|
+
viewProps,
|
|
17
|
+
responsiveProps,
|
|
18
|
+
hrefAttrsProp
|
|
19
|
+
} from '../utils/props'
|
|
13
20
|
import CardBase from './CardBase'
|
|
14
21
|
import PressableCardBase from './PressableCardBase'
|
|
15
22
|
import CheckboxButton from '../Checkbox/CheckboxButton'
|
|
@@ -227,6 +234,8 @@ const Card = React.forwardRef(
|
|
|
227
234
|
tokens={getThemeTokens}
|
|
228
235
|
dataSet={dataSet}
|
|
229
236
|
onPress={onPress}
|
|
237
|
+
href={interactiveCard?.href}
|
|
238
|
+
hrefAttrs={interactiveCard?.hrefAttrs}
|
|
230
239
|
{...selectProps(rest)}
|
|
231
240
|
>
|
|
232
241
|
{(cardState) => {
|
|
@@ -308,12 +317,16 @@ Card.propTypes = {
|
|
|
308
317
|
- `radiogroup`
|
|
309
318
|
- `checkbox`
|
|
310
319
|
* - variant: The variant to be used for the interactive card
|
|
320
|
+
* - href: The href to be used for the interactive card
|
|
321
|
+
* - hrefAttrs: The href attributes to be used for the interactive card
|
|
311
322
|
*/
|
|
312
323
|
interactiveCard: PropTypes.shape({
|
|
313
324
|
body: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
|
314
325
|
tokens: getTokensPropType('Card'),
|
|
315
326
|
selectionType: PropTypes.oneOf(Object.values(SelectionType)),
|
|
316
|
-
variant: variantProp.propType
|
|
327
|
+
variant: variantProp.propType,
|
|
328
|
+
href: PropTypes.string,
|
|
329
|
+
hrefAttrs: PropTypes.shape(hrefAttrsProp.types)
|
|
317
330
|
}),
|
|
318
331
|
/**
|
|
319
332
|
* Apply background image to the card.
|
|
@@ -326,7 +339,11 @@ Card.propTypes = {
|
|
|
326
339
|
resizeMode: responsiveProps.getTypeOptionallyByViewport(
|
|
327
340
|
PropTypes.oneOf(['cover', 'contain', 'stretch', 'repeat', 'center'])
|
|
328
341
|
)
|
|
329
|
-
})
|
|
342
|
+
}),
|
|
343
|
+
/**
|
|
344
|
+
* Data set for the card.
|
|
345
|
+
*/
|
|
346
|
+
dataSet: PropTypes.object
|
|
330
347
|
}
|
|
331
348
|
|
|
332
349
|
export default Card
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
|
-
import { Pressable, Platform } from 'react-native'
|
|
3
|
+
import { Pressable, Platform, View, StyleSheet } from 'react-native'
|
|
4
4
|
|
|
5
5
|
import { useViewport } from '../ViewportProvider'
|
|
6
6
|
import { applyOuterBorder, validateThemeTokens } from '../ThemeProvider'
|
|
@@ -118,7 +118,57 @@ const PressableCardBase = React.forwardRef(
|
|
|
118
118
|
const handleChange = linkProps.handleHref({ href, onPress })
|
|
119
119
|
const handleKeyDown = (event) => {
|
|
120
120
|
// The expected keyboard shortcut for selecting a focused item is the Space key
|
|
121
|
-
if (event?.key === ' ') handleChange(event)
|
|
121
|
+
if (event?.key === ' ') handleChange?.(event)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const [hovered, setHovered] = React.useState(false)
|
|
125
|
+
const [focused, setFocused] = React.useState(false)
|
|
126
|
+
const [pressed, setPressed] = React.useState(false)
|
|
127
|
+
|
|
128
|
+
if (Platform.OS === 'web' && href) {
|
|
129
|
+
return (
|
|
130
|
+
<View
|
|
131
|
+
ref={ref}
|
|
132
|
+
style={getOuterBorderStyle({ pressed, focused, hovered })}
|
|
133
|
+
dataSet={dataSet}
|
|
134
|
+
onMouseEnter={() => setHovered(true)}
|
|
135
|
+
onMouseLeave={() => setHovered(false)}
|
|
136
|
+
{...selectProps({ ...rest, accessibilityRole })}
|
|
137
|
+
>
|
|
138
|
+
<a
|
|
139
|
+
href={href}
|
|
140
|
+
tabIndex={0}
|
|
141
|
+
onClick={(event) => {
|
|
142
|
+
setPressed(false)
|
|
143
|
+
handleChange?.(event)
|
|
144
|
+
}}
|
|
145
|
+
onKeyDown={(event) => {
|
|
146
|
+
if (event.key === ' ') {
|
|
147
|
+
setPressed(true)
|
|
148
|
+
handleKeyDown(event)
|
|
149
|
+
}
|
|
150
|
+
}}
|
|
151
|
+
onKeyUp={(event) => {
|
|
152
|
+
if (event.key === ' ') setPressed(false)
|
|
153
|
+
}}
|
|
154
|
+
onMouseDown={() => setPressed(true)}
|
|
155
|
+
onMouseUp={() => setPressed(false)}
|
|
156
|
+
onFocus={() => setFocused(true)}
|
|
157
|
+
onBlur={() => {
|
|
158
|
+
setFocused(false)
|
|
159
|
+
setPressed(false)
|
|
160
|
+
}}
|
|
161
|
+
style={staticStyles.container}
|
|
162
|
+
{...(hrefAttrs || {})}
|
|
163
|
+
>
|
|
164
|
+
<CardBase tokens={getCardTokens({ pressed, focused, hovered })}>
|
|
165
|
+
{typeof children === 'function'
|
|
166
|
+
? children(getCardState({ pressed, focused, hovered }))
|
|
167
|
+
: children}
|
|
168
|
+
</CardBase>
|
|
169
|
+
</a>
|
|
170
|
+
</View>
|
|
171
|
+
)
|
|
122
172
|
}
|
|
123
173
|
|
|
124
174
|
return (
|
|
@@ -141,6 +191,14 @@ const PressableCardBase = React.forwardRef(
|
|
|
141
191
|
)
|
|
142
192
|
}
|
|
143
193
|
)
|
|
194
|
+
|
|
195
|
+
const staticStyles = StyleSheet.create({
|
|
196
|
+
container: {
|
|
197
|
+
flex: 1,
|
|
198
|
+
display: 'flex'
|
|
199
|
+
}
|
|
200
|
+
})
|
|
201
|
+
|
|
144
202
|
PressableCardBase.displayName = 'PressableCardBase'
|
|
145
203
|
|
|
146
204
|
PressableCardBase.propTypes = {
|
|
@@ -2,6 +2,7 @@ import React from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import ExpandCollapse from '../ExpandCollapse'
|
|
4
4
|
import { getTokensPropType, selectSystemProps, contentfulProps } from '../utils'
|
|
5
|
+
import { variantProp } from '../utils/props'
|
|
5
6
|
import ExpandCollapseMiniControl from './ExpandCollapseMiniControl'
|
|
6
7
|
|
|
7
8
|
const [selectContainerProps, selectedContainerPropTypes] = selectSystemProps([contentfulProps])
|
|
@@ -79,6 +80,10 @@ ExpandCollapseMini.propTypes = {
|
|
|
79
80
|
* Optional variant object to override the default theme tokens
|
|
80
81
|
*/
|
|
81
82
|
tokens: getTokensPropType('ExpandCollapseMini'),
|
|
83
|
+
/**
|
|
84
|
+
* ExpandCollapseMini variant.
|
|
85
|
+
*/
|
|
86
|
+
variant: variantProp.propType,
|
|
82
87
|
/**
|
|
83
88
|
* The dataSet prop allows to pass data-* attributes element to the component.
|
|
84
89
|
*/
|
|
@@ -15,13 +15,6 @@ const presentationOnly = {
|
|
|
15
15
|
focusable: false // Stop RNW from setting tabIndex={0}: focus goes to Control only
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const selectLinkTokens = ({ color, textLine, lineHeight, fontSize }) => ({
|
|
19
|
-
color,
|
|
20
|
-
textLine,
|
|
21
|
-
blockLineHeight: lineHeight,
|
|
22
|
-
blockFontSize: fontSize
|
|
23
|
-
})
|
|
24
|
-
|
|
25
18
|
const ExpandCollapseMiniControl = React.forwardRef(
|
|
26
19
|
(
|
|
27
20
|
{
|
|
@@ -35,20 +28,24 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
35
28
|
},
|
|
36
29
|
ref
|
|
37
30
|
) => {
|
|
38
|
-
const { expanded, hover, focus } = pressableState || {}
|
|
39
|
-
|
|
40
|
-
const
|
|
31
|
+
const { expanded, hover, focus, pressed } = pressableState || {}
|
|
32
|
+
const { quiet } = variant
|
|
33
|
+
const isFocusVisible = Platform.OS === 'web' ? focus && !pressed && !hover : expanded
|
|
34
|
+
|
|
35
|
+
const linkTokens = useThemeTokens(
|
|
41
36
|
'Link',
|
|
42
37
|
{},
|
|
43
|
-
{},
|
|
44
|
-
{
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
variant,
|
|
50
|
-
{ expanded, focus }
|
|
38
|
+
{ ...variant, quiet: expanded ?? quiet },
|
|
39
|
+
{
|
|
40
|
+
focus: isFocusVisible,
|
|
41
|
+
hover,
|
|
42
|
+
pressed
|
|
43
|
+
}
|
|
51
44
|
)
|
|
45
|
+
const { size, icon } = useThemeTokens('ExpandCollapseMiniControl', tokens, variant, {
|
|
46
|
+
expanded,
|
|
47
|
+
focus
|
|
48
|
+
})
|
|
52
49
|
|
|
53
50
|
// Choose hover styles when any part of Control is hoverred
|
|
54
51
|
const appearance = { ...variant, hover }
|
|
@@ -75,9 +72,8 @@ const ExpandCollapseMiniControl = React.forwardRef(
|
|
|
75
72
|
icon={icon}
|
|
76
73
|
iconPosition={iconPosition}
|
|
77
74
|
tokens={(linkState) => ({
|
|
78
|
-
...
|
|
79
|
-
...
|
|
80
|
-
outerBorderColor
|
|
75
|
+
...linkTokens,
|
|
76
|
+
...getTokens(linkState)
|
|
81
77
|
})}
|
|
82
78
|
ref={ref}
|
|
83
79
|
{...presentationOnly}
|
package/src/Icon/Icon.jsx
CHANGED
|
@@ -24,7 +24,12 @@ const Icon = React.forwardRef(
|
|
|
24
24
|
const size = scalesWithText ? themeTokens.size * fontScale : themeTokens.size
|
|
25
25
|
|
|
26
26
|
const iconContent = (
|
|
27
|
-
<IconComponent
|
|
27
|
+
<IconComponent
|
|
28
|
+
title={accessibilityLabel}
|
|
29
|
+
size={size}
|
|
30
|
+
color={themeTokens.color}
|
|
31
|
+
gradient={themeTokens.gradient}
|
|
32
|
+
/>
|
|
28
33
|
)
|
|
29
34
|
|
|
30
35
|
const paddingStyles = variant?.padding
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
|
|
15
15
|
import LabelContent from './LabelContent'
|
|
16
16
|
import Tooltip from '../Tooltip'
|
|
17
|
+
import tooltipPropTypes from '../Tooltip/shared'
|
|
17
18
|
|
|
18
19
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
19
20
|
|
|
@@ -56,10 +57,14 @@ const InputLabel = React.forwardRef(
|
|
|
56
57
|
const themeTokens = useThemeTokens('InputLabel', tokens, variant)
|
|
57
58
|
|
|
58
59
|
const hasTooltip = tooltip !== undefined
|
|
60
|
+
|
|
59
61
|
const isHintInline = hintPosition === 'inline'
|
|
60
62
|
|
|
61
63
|
const { themeOptions } = useTheme()
|
|
62
64
|
|
|
65
|
+
const getTooltipProps = () => {
|
|
66
|
+
return typeof tooltip === 'string' ? { content: tooltip } : tooltip
|
|
67
|
+
}
|
|
63
68
|
return (
|
|
64
69
|
<>
|
|
65
70
|
<View ref={ref} style={staticStyles.container} {...selectProps(rest)}>
|
|
@@ -94,7 +99,7 @@ const InputLabel = React.forwardRef(
|
|
|
94
99
|
}
|
|
95
100
|
]}
|
|
96
101
|
>
|
|
97
|
-
<Tooltip
|
|
102
|
+
<Tooltip copy={copy} {...getTooltipProps()} />
|
|
98
103
|
</View>
|
|
99
104
|
)}
|
|
100
105
|
{maxCharacterAllowed && isHintInline && (
|
|
@@ -156,7 +161,7 @@ InputLabel.propTypes = {
|
|
|
156
161
|
/**
|
|
157
162
|
* Content of an optional `Tooltip`. If set, a tooltip button will be shown next to the label.
|
|
158
163
|
*/
|
|
159
|
-
tooltip: PropTypes.string,
|
|
164
|
+
tooltip: PropTypes.oneOfType([tooltipPropTypes, PropTypes.string]),
|
|
160
165
|
/**
|
|
161
166
|
* Current number of characterts of an input text.
|
|
162
167
|
*/
|
|
@@ -8,6 +8,7 @@ import { useThemeTokens } from '../ThemeProvider'
|
|
|
8
8
|
import useInputSupports from './useInputSupports'
|
|
9
9
|
import { getTokensPropType, useCopy } from '../utils'
|
|
10
10
|
import dictionary from './dictionary'
|
|
11
|
+
import tooltipPropTypes from '../Tooltip/shared'
|
|
11
12
|
|
|
12
13
|
const InputSupports = React.forwardRef(
|
|
13
14
|
(
|
|
@@ -115,9 +116,12 @@ InputSupports.propTypes = {
|
|
|
115
116
|
*/
|
|
116
117
|
feedbackProps: PropTypes.object,
|
|
117
118
|
/**
|
|
118
|
-
*
|
|
119
|
+
* an optional `Tooltip`. If set, tooltip will be shown next to the label.
|
|
120
|
+
* Props can be passed to the tooltip in one of the following ways.
|
|
121
|
+
* 1. `tooltip` as a string - The content of the tooltip.
|
|
122
|
+
* 2. `tooltip` as an object - Tooltip component props to be passed.
|
|
119
123
|
*/
|
|
120
|
-
tooltip: PropTypes.string,
|
|
124
|
+
tooltip: PropTypes.oneOfType([tooltipPropTypes, PropTypes.string]),
|
|
121
125
|
/**
|
|
122
126
|
* Use to visually mark an input as valid or invalid.
|
|
123
127
|
*/
|
|
@@ -45,8 +45,6 @@ const selectBulletContainerStyles = ({
|
|
|
45
45
|
* icon or bullet nicely against the first line of text in a ListIconContent.
|
|
46
46
|
*/
|
|
47
47
|
const ListItemMark = React.forwardRef(({ icon, iconColor, iconSize, tokens = {} }, ref) => {
|
|
48
|
-
const IconComponent = icon || <></>
|
|
49
|
-
|
|
50
48
|
const themeTokens = typeof tokens === 'function' ? tokens() : tokens
|
|
51
49
|
|
|
52
50
|
const sideItemContainerStyles = selectSideItemContainerStyles(themeTokens)
|
|
@@ -56,7 +54,11 @@ const ListItemMark = React.forwardRef(({ icon, iconColor, iconSize, tokens = {}
|
|
|
56
54
|
const iconTokens = selectItemIconTokens(themeTokens)
|
|
57
55
|
return (
|
|
58
56
|
<View style={[sideItemContainerStyles, bulletContainerStyles]}>
|
|
59
|
-
<
|
|
57
|
+
<Icon
|
|
58
|
+
icon={icon}
|
|
59
|
+
tokens={{ size: iconSize ?? iconTokens.size }}
|
|
60
|
+
variant={{ color: iconColor ?? iconTokens.color }}
|
|
61
|
+
/>
|
|
60
62
|
</View>
|
|
61
63
|
)
|
|
62
64
|
}
|
|
@@ -134,6 +134,10 @@ const MultiSelectFilter = React.forwardRef(
|
|
|
134
134
|
buttonIconPadding,
|
|
135
135
|
subtitleColor,
|
|
136
136
|
dividerColor,
|
|
137
|
+
iconColor,
|
|
138
|
+
buttonBackgroundColor,
|
|
139
|
+
iconColorSelected,
|
|
140
|
+
buttonBackgroundColorSelected,
|
|
137
141
|
...restTokens
|
|
138
142
|
} = useThemeTokens(
|
|
139
143
|
'MultiSelectFilter',
|
|
@@ -154,7 +158,9 @@ const MultiSelectFilter = React.forwardRef(
|
|
|
154
158
|
paddingBottom: labelPaddingBottom,
|
|
155
159
|
paddingLeft: labelPaddingLeft,
|
|
156
160
|
paddingRight: labelPaddingRight,
|
|
157
|
-
iconBackground: buttonIconBackgroundColor
|
|
161
|
+
iconBackground: buttonIconBackgroundColor,
|
|
162
|
+
iconColor: isSelected ? iconColorSelected : iconColor,
|
|
163
|
+
backgroundColor: isSelected ? buttonBackgroundColorSelected : buttonBackgroundColor
|
|
158
164
|
}
|
|
159
165
|
const getButtonDropdownTokens = useThemeTokensCallback(
|
|
160
166
|
'ButtonDropdown',
|
|
@@ -107,6 +107,7 @@ const ToggleSwitch = React.forwardRef(
|
|
|
107
107
|
variant,
|
|
108
108
|
accessibilityRole = 'switch',
|
|
109
109
|
accessibilityLabel = label,
|
|
110
|
+
togglePosition = 'end',
|
|
110
111
|
...rest
|
|
111
112
|
},
|
|
112
113
|
ref
|
|
@@ -125,8 +126,13 @@ const ToggleSwitch = React.forwardRef(
|
|
|
125
126
|
selectButtonTokens(getTokens(buttonState), getTokens(themeTokens))
|
|
126
127
|
const uniqueId = useUniqueId('toggleSwitch')
|
|
127
128
|
const inputId = id ?? uniqueId
|
|
129
|
+
|
|
128
130
|
return (
|
|
129
|
-
<StackView
|
|
131
|
+
<StackView
|
|
132
|
+
space={themeTokens.space}
|
|
133
|
+
direction={togglePosition === 'start' ? 'row-reverse' : 'row'}
|
|
134
|
+
tokens={{ alignItems: 'center', justifyContent: 'start' }}
|
|
135
|
+
>
|
|
130
136
|
{Boolean(label) && (
|
|
131
137
|
<View style={[selectLabelStyles(themeTokens), staticStyles.containText]}>
|
|
132
138
|
<InputLabel
|
|
@@ -225,7 +231,13 @@ ToggleSwitch.propTypes = {
|
|
|
225
231
|
/**
|
|
226
232
|
* Content of an optional Tooltip. If set, a tooltip button will be shown next to the label.
|
|
227
233
|
*/
|
|
228
|
-
tooltip: PropTypes.string
|
|
234
|
+
tooltip: PropTypes.string,
|
|
235
|
+
/**
|
|
236
|
+
* Controls the position of the switch in relation to the label.
|
|
237
|
+
* - 'start': switch on the start, before the `label` and `tooltip`.
|
|
238
|
+
* - 'end': switch to the end, after the `label` and `tooltip` (default).
|
|
239
|
+
*/
|
|
240
|
+
togglePosition: PropTypes.oneOf(['start', 'end'])
|
|
229
241
|
}
|
|
230
242
|
|
|
231
243
|
const staticStyles = StyleSheet.create({
|
|
@@ -87,6 +87,7 @@ const ToggleSwitchGroup = React.forwardRef(
|
|
|
87
87
|
onChange: itemOnChange,
|
|
88
88
|
ref: itemRef,
|
|
89
89
|
tooltip: itemTooltip,
|
|
90
|
+
togglePosition,
|
|
90
91
|
...itemRest
|
|
91
92
|
},
|
|
92
93
|
index
|
|
@@ -117,6 +118,7 @@ const ToggleSwitchGroup = React.forwardRef(
|
|
|
117
118
|
inactive={inactive}
|
|
118
119
|
label={label}
|
|
119
120
|
tooltip={itemTooltip}
|
|
121
|
+
togglePosition={togglePosition}
|
|
120
122
|
{...itemA11y}
|
|
121
123
|
{...selectItemProps(itemRest)}
|
|
122
124
|
/>
|
|
@@ -182,7 +184,13 @@ ToggleSwitchGroup.propTypes = {
|
|
|
182
184
|
/**
|
|
183
185
|
* An optional ref for one individual ToggleSwitch in the ToggleSwitchGroup
|
|
184
186
|
*/
|
|
185
|
-
ref: ABBPropTypes.ref()
|
|
187
|
+
ref: ABBPropTypes.ref(),
|
|
188
|
+
/**
|
|
189
|
+
* Controls the position of the switch in relation to the label.
|
|
190
|
+
* - 'start': switch on the start, before the `label` and `tooltip`.
|
|
191
|
+
* - 'end': switch to the end, after the `label` and `tooltip` (default).
|
|
192
|
+
*/
|
|
193
|
+
togglePosition: PropTypes.oneOf(['start', 'end'])
|
|
186
194
|
})
|
|
187
195
|
),
|
|
188
196
|
/**
|
package/src/Tooltip/shared.js
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { resolveResponsiveProp } from './useResponsiveProp'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolves spacing options from the provided space object.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} space - The space configuration object.
|
|
7
|
+
* @param {Object} [space.options] - The options for spacing.
|
|
8
|
+
* @param {number|string} [space.options.size] - The size of the spacing. Can be a number or a string.
|
|
9
|
+
* @param {string} [space.options.variant] - The variant of the spacing.
|
|
10
|
+
* @param {number} [space.options.subtract=0] - A value to subtract from the spacing size.
|
|
11
|
+
* @returns {Object} An object containing resolved spacing tokens, variant, overridden flag, and subtract value.
|
|
12
|
+
* @property {Object} tokens - The resolved spacing tokens.
|
|
13
|
+
* @property {number|string} tokens.size - The size of the spacing.
|
|
14
|
+
* @property {string} [variant] - The variant of the spacing.
|
|
15
|
+
* @property {boolean} overridden - Indicates if the size is explicitly overridden as a number.
|
|
16
|
+
* @property {number} subtract - The value to subtract from the spacing size.
|
|
17
|
+
*/
|
|
18
|
+
const resolveSpacingOptions = (space) => {
|
|
19
|
+
if (!space?.options) return {}
|
|
20
|
+
|
|
21
|
+
const { size, variant, subtract = 0 } = space.options
|
|
22
|
+
const overridden = typeof size === 'number'
|
|
23
|
+
|
|
24
|
+
return { tokens: { size }, variant, overridden, subtract }
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Calculates the spacing scale based on the provided space value, viewport, and spacing tokens.
|
|
29
|
+
*
|
|
30
|
+
* @param {Object} spaceValue - The space value configuration, which may include responsive properties.
|
|
31
|
+
* @param {Object} viewport - The current viewport dimensions or configuration.
|
|
32
|
+
* @param {Function} getSpacingTokens - A function that retrieves spacing tokens based on the provided options.
|
|
33
|
+
* @returns {number} The calculated spacing scale, ensuring it is non-negative.
|
|
34
|
+
*/
|
|
35
|
+
const getSpacingScale = (spaceValue, viewport, getSpacingTokens) => {
|
|
36
|
+
const { tokens, variant, overridden, subtract = 0 } = resolveSpacingOptions(spaceValue)
|
|
37
|
+
const space = !overridden && (spaceValue?.space ?? resolveResponsiveProp(spaceValue, viewport, 0))
|
|
38
|
+
|
|
39
|
+
const { size } = getSpacingTokens(
|
|
40
|
+
{
|
|
41
|
+
...variant,
|
|
42
|
+
space: typeof space === 'number' ? space : 0,
|
|
43
|
+
viewport
|
|
44
|
+
},
|
|
45
|
+
tokens
|
|
46
|
+
)
|
|
47
|
+
return Math.max(size - subtract, 0)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default getSpacingScale
|
package/src/utils/index.js
CHANGED
|
@@ -23,3 +23,4 @@ export { default as htmlAttrs } from './htmlAttrs'
|
|
|
23
23
|
export { transformGradient } from './transformGradient'
|
|
24
24
|
export { default as convertFromMegaByteToByte } from './convertFromMegaByteToByte'
|
|
25
25
|
export { default as formatImageSource } from './formatImageSource'
|
|
26
|
+
export { default as getSpacingScale } from './getSpacingScale'
|