@telus-uds/components-base 1.49.0 → 1.51.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 +27 -2
- package/component-docs.json +110 -14
- package/lib/Link/LinkBase.js +1 -1
- package/lib/MultiSelectFilter/ModalOverlay.js +24 -8
- package/lib/MultiSelectFilter/MultiSelectFilter.js +154 -21
- package/lib/QuickLinksFeature/QuickLinksFeatureItem.js +62 -41
- package/lib/StepTracker/Step.js +35 -14
- package/lib/StepTracker/StepTracker.js +5 -2
- package/lib/StepTracker/dictionary.js +24 -4
- package/lib/TextInput/TextInput.js +17 -15
- package/lib/ThemeProvider/ThemeProvider.js +7 -1
- package/lib-module/Link/LinkBase.js +1 -1
- package/lib-module/MultiSelectFilter/ModalOverlay.js +25 -9
- package/lib-module/MultiSelectFilter/MultiSelectFilter.js +154 -23
- package/lib-module/QuickLinksFeature/QuickLinksFeatureItem.js +64 -43
- package/lib-module/StepTracker/Step.js +35 -14
- package/lib-module/StepTracker/StepTracker.js +5 -2
- package/lib-module/StepTracker/dictionary.js +24 -4
- package/lib-module/TextInput/TextInput.js +19 -15
- package/lib-module/ThemeProvider/ThemeProvider.js +8 -2
- package/package.json +2 -2
- package/src/Card/CardBase.jsx +0 -1
- package/src/Link/LinkBase.jsx +3 -1
- package/src/MultiSelectFilter/ModalOverlay.jsx +30 -6
- package/src/MultiSelectFilter/MultiSelectFilter.jsx +142 -20
- package/src/QuickLinksFeature/QuickLinksFeatureItem.jsx +42 -35
- package/src/StepTracker/Step.jsx +34 -10
- package/src/StepTracker/StepTracker.jsx +11 -2
- package/src/StepTracker/dictionary.js +24 -4
- package/src/TextInput/TextInput.jsx +8 -5
- package/src/ThemeProvider/ThemeProvider.jsx +9 -2
- package/src/Typography/Typography.jsx +1 -0
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"@floating-ui/react-native": "^0.8.1",
|
|
12
12
|
"@gorhom/portal": "^1.0.14",
|
|
13
13
|
"@telus-uds/system-constants": "^1.2.1",
|
|
14
|
-
"@telus-uds/system-theme-tokens": "^2.
|
|
14
|
+
"@telus-uds/system-theme-tokens": "^2.33.0",
|
|
15
15
|
"airbnb-prop-types": "^2.16.0",
|
|
16
16
|
"lodash.debounce": "^4.0.8",
|
|
17
17
|
"lodash.merge": "^4.6.2",
|
|
@@ -72,5 +72,5 @@
|
|
|
72
72
|
"standard-engine": {
|
|
73
73
|
"skip": true
|
|
74
74
|
},
|
|
75
|
-
"version": "1.
|
|
75
|
+
"version": "1.51.0"
|
|
76
76
|
}
|
package/src/Card/CardBase.jsx
CHANGED
|
@@ -42,7 +42,6 @@ const selectStyles = ({
|
|
|
42
42
|
const CardBase = forwardRef(({ children, tokens, dataSet, ...rest }, ref) => {
|
|
43
43
|
const cardStyle = selectStyles(typeof tokens === 'function' ? tokens() : tokens)
|
|
44
44
|
const props = selectProps(rest)
|
|
45
|
-
|
|
46
45
|
return (
|
|
47
46
|
<View style={cardStyle} dataSet={dataSet} ref={ref} {...props}>
|
|
48
47
|
{children}
|
package/src/Link/LinkBase.jsx
CHANGED
|
@@ -183,7 +183,9 @@ const LinkBase = forwardRef(
|
|
|
183
183
|
space={iconSpace}
|
|
184
184
|
iconProps={{ ...iconProps, tokens: iconTokens }}
|
|
185
185
|
>
|
|
186
|
-
<Text style={[textStyles, blockTextStyles, staticStyles.baseline]}>
|
|
186
|
+
<Text style={[textStyles, blockTextStyles, staticStyles.baseline]}>
|
|
187
|
+
{typeof children === 'function' ? children(linkState) : children}
|
|
188
|
+
</Text>
|
|
187
189
|
</IconText>
|
|
188
190
|
)
|
|
189
191
|
}}
|
|
@@ -2,7 +2,7 @@ import React, { forwardRef } from 'react'
|
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import { View, StyleSheet } from 'react-native'
|
|
4
4
|
import { Portal } from '@gorhom/portal'
|
|
5
|
-
import {
|
|
5
|
+
import { useCopy, copyPropTypes, getTokensPropType, variantProp } from '../utils'
|
|
6
6
|
import { useViewport } from '../ViewportProvider'
|
|
7
7
|
import { useThemeTokens } from '../ThemeProvider'
|
|
8
8
|
import dictionary from './dictionary'
|
|
@@ -14,7 +14,6 @@ const staticStyles = StyleSheet.create({
|
|
|
14
14
|
positioner: {
|
|
15
15
|
flex: 1, // Grow to maxWidth when possible, shrink when not possible
|
|
16
16
|
position: 'absolute',
|
|
17
|
-
height: 330,
|
|
18
17
|
zIndex: 10000 // Position on top of all the other overlays, including backdrops and modals
|
|
19
18
|
},
|
|
20
19
|
closeButtonContainer: {
|
|
@@ -44,13 +43,33 @@ const selectPaddingContainerStyles = ({ paddingTop, paddingLeft, paddingRight })
|
|
|
44
43
|
|
|
45
44
|
const ModalOverlay = forwardRef(
|
|
46
45
|
(
|
|
47
|
-
{
|
|
46
|
+
{
|
|
47
|
+
children,
|
|
48
|
+
isReady = false,
|
|
49
|
+
maxHeight,
|
|
50
|
+
maxHeightSize,
|
|
51
|
+
maxWidthSize,
|
|
52
|
+
minHeight,
|
|
53
|
+
minWidth,
|
|
54
|
+
overlaidPosition,
|
|
55
|
+
onLayout,
|
|
56
|
+
variant,
|
|
57
|
+
tokens,
|
|
58
|
+
copy,
|
|
59
|
+
onClose
|
|
60
|
+
},
|
|
48
61
|
ref
|
|
49
62
|
) => {
|
|
50
63
|
const viewport = useViewport()
|
|
51
64
|
const themeTokens = useThemeTokens('Modal', tokens, variant, { viewport, maxWidth: false })
|
|
65
|
+
const containerWidthHeight = {
|
|
66
|
+
minWidth,
|
|
67
|
+
minHeight,
|
|
68
|
+
...(tokens.maxWidth && maxWidthSize && { maxWidth: maxWidthSize }),
|
|
69
|
+
...(maxHeight && maxHeightSize && { maxHeight: maxHeightSize })
|
|
70
|
+
}
|
|
52
71
|
|
|
53
|
-
const { closeIcon: CloseIconComponent
|
|
72
|
+
const { closeIcon: CloseIconComponent } = themeTokens
|
|
54
73
|
|
|
55
74
|
const getCopy = useCopy({ dictionary, copy })
|
|
56
75
|
const closeLabel = getCopy('closeButton')
|
|
@@ -62,7 +81,7 @@ const ModalOverlay = forwardRef(
|
|
|
62
81
|
onLayout={onLayout}
|
|
63
82
|
style={[
|
|
64
83
|
overlaidPosition,
|
|
65
|
-
|
|
84
|
+
containerWidthHeight,
|
|
66
85
|
staticStyles.positioner,
|
|
67
86
|
!isReady && staticStyles.hidden
|
|
68
87
|
]}
|
|
@@ -79,7 +98,6 @@ const ModalOverlay = forwardRef(
|
|
|
79
98
|
icon={CloseIconComponent}
|
|
80
99
|
accessibilityRole="button"
|
|
81
100
|
accessibilityLabel={closeLabel}
|
|
82
|
-
tokens={selectTokens('IconButton', themeTokens, 'close')}
|
|
83
101
|
/>
|
|
84
102
|
</View>
|
|
85
103
|
{children}
|
|
@@ -99,6 +117,12 @@ ModalOverlay.propTypes = {
|
|
|
99
117
|
left: PropTypes.number,
|
|
100
118
|
width: PropTypes.number
|
|
101
119
|
}),
|
|
120
|
+
minWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
121
|
+
minHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
122
|
+
maxHeightSize: PropTypes.number,
|
|
123
|
+
maxWidthSize: PropTypes.number,
|
|
124
|
+
maxHeight: PropTypes.bool,
|
|
125
|
+
maxWidth: PropTypes.bool,
|
|
102
126
|
onLayout: PropTypes.func,
|
|
103
127
|
variant: variantProp.propType,
|
|
104
128
|
tokens: getTokensPropType('Modal'),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import React, { useState } from 'react'
|
|
1
|
+
import React, { useState, useEffect } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
|
-
import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider'
|
|
4
|
+
import { useThemeTokens, useThemeTokensCallback, applyTextStyles } from '../ThemeProvider'
|
|
5
5
|
import {
|
|
6
6
|
containUniqueFields,
|
|
7
7
|
getTokensPropType,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
variantProp
|
|
15
15
|
} from '../utils'
|
|
16
16
|
import dictionary from './dictionary'
|
|
17
|
-
|
|
17
|
+
import { useViewport } from '../ViewportProvider'
|
|
18
18
|
import Box from '../Box'
|
|
19
19
|
import { Button, ButtonDropdown } from '../Button'
|
|
20
20
|
import { CheckboxGroup } from '../Checkbox'
|
|
@@ -25,6 +25,7 @@ import StackView from '../StackView'
|
|
|
25
25
|
import Typography from '../Typography'
|
|
26
26
|
import { TextButton } from '../Link'
|
|
27
27
|
import ModalOverlay from './ModalOverlay'
|
|
28
|
+
import Modal from '../Modal'
|
|
28
29
|
|
|
29
30
|
const { Col, Row } = FlexGrid
|
|
30
31
|
|
|
@@ -47,6 +48,7 @@ const MultiSelectFilter = ({
|
|
|
47
48
|
tokens,
|
|
48
49
|
items = [],
|
|
49
50
|
values,
|
|
51
|
+
maxHeight = false,
|
|
50
52
|
initialValues,
|
|
51
53
|
maxValues,
|
|
52
54
|
onChange,
|
|
@@ -56,6 +58,7 @@ const MultiSelectFilter = ({
|
|
|
56
58
|
rowLimit = 12,
|
|
57
59
|
...rest
|
|
58
60
|
}) => {
|
|
61
|
+
const viewport = useViewport()
|
|
59
62
|
const { currentValues, setValues } = useMultipleInputValues({
|
|
60
63
|
initialValues,
|
|
61
64
|
values,
|
|
@@ -63,17 +66,39 @@ const MultiSelectFilter = ({
|
|
|
63
66
|
onChange,
|
|
64
67
|
readOnly
|
|
65
68
|
})
|
|
69
|
+
const [isOpen, setIsOpen] = useState(false)
|
|
70
|
+
const [checkedIds, setCheckedIds] = useState(currentValues ?? [])
|
|
71
|
+
const [maxWidth, setMaxWidth] = useState(false)
|
|
66
72
|
|
|
67
73
|
const themeTokens = useThemeTokens('ButtonDropdown', tokens, variant)
|
|
68
74
|
const getItemTokens = useThemeTokensCallback('ButtonDropdown', tokens, variant)
|
|
69
75
|
const getButtonTokens = (buttonState) => selectTokens('Button', getItemTokens(buttonState))
|
|
70
76
|
const getCopy = useCopy({ dictionary, copy })
|
|
77
|
+
const colSizeNotMobile = items.length > rowLimit ? 2 : 1
|
|
78
|
+
const colSize = viewport !== 'xs' ? colSizeNotMobile : 1
|
|
79
|
+
const itemsLengthNotMobile = items.length > 24 ? items.length / 2 : rowLimit
|
|
80
|
+
const isSelected = currentValues.length > 0
|
|
81
|
+
const rowLength = viewport !== 'xs' ? itemsLengthNotMobile : items.length
|
|
71
82
|
|
|
72
|
-
|
|
73
|
-
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (colSize === 1) return setMaxWidth(false)
|
|
85
|
+
return colSize === 2 && setMaxWidth(true)
|
|
86
|
+
}, [colSize])
|
|
74
87
|
|
|
75
|
-
const
|
|
76
|
-
|
|
88
|
+
const {
|
|
89
|
+
headerFontColor,
|
|
90
|
+
headerFontSize,
|
|
91
|
+
buttonDirection,
|
|
92
|
+
headerFontWeight,
|
|
93
|
+
headerLineHeight,
|
|
94
|
+
subHeaderFontWeight,
|
|
95
|
+
subHeaderFontSize,
|
|
96
|
+
maxHeightSize,
|
|
97
|
+
maxWidthSize,
|
|
98
|
+
subHeaderLineHeight,
|
|
99
|
+
minHeight,
|
|
100
|
+
minWidth
|
|
101
|
+
} = useThemeTokens('MultiSelectFilter', tokens, { ...variant, maxHeight, maxWidth }, { viewport })
|
|
77
102
|
|
|
78
103
|
const uniqueFields = ['id', 'label']
|
|
79
104
|
if (!containUniqueFields(items, uniqueFields)) {
|
|
@@ -93,14 +118,31 @@ const MultiSelectFilter = ({
|
|
|
93
118
|
setIsOpen(false)
|
|
94
119
|
}
|
|
95
120
|
|
|
121
|
+
const onClear = () => {
|
|
122
|
+
setCheckedIds(() => [])
|
|
123
|
+
onApply([])
|
|
124
|
+
}
|
|
125
|
+
|
|
96
126
|
const { align, offsets } = useResponsiveProp({
|
|
97
|
-
xs: { align: { top: 'top', left: 'left'
|
|
127
|
+
xs: { align: { top: 'top', left: 'left' } },
|
|
98
128
|
sm: {
|
|
99
129
|
align: { top: 'bottom', left: 'left' },
|
|
100
130
|
offsets: { vertical: 4 }
|
|
101
131
|
}
|
|
102
132
|
})
|
|
103
133
|
|
|
134
|
+
const headerStyles = applyTextStyles({
|
|
135
|
+
fontSize: headerFontSize,
|
|
136
|
+
fontWeight: headerFontWeight,
|
|
137
|
+
fontColor: headerFontColor
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
const subeHeaderStyles = applyTextStyles({
|
|
141
|
+
fontSize: subHeaderFontSize,
|
|
142
|
+
fontWeight: subHeaderFontWeight,
|
|
143
|
+
fontColor: selectSubTitleTokens(themeTokens)
|
|
144
|
+
})
|
|
145
|
+
|
|
104
146
|
const { overlaidPosition, onTargetLayout, isReady, sourceRef } = useOverlaidPosition({
|
|
105
147
|
isShown: isOpen,
|
|
106
148
|
offsets,
|
|
@@ -120,18 +162,84 @@ const MultiSelectFilter = ({
|
|
|
120
162
|
tokens={getButtonTokens}
|
|
121
163
|
inactive={inactive}
|
|
122
164
|
/>
|
|
123
|
-
{isOpen && (
|
|
165
|
+
{isOpen && viewport === 'xs' && (
|
|
166
|
+
<Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
|
|
167
|
+
<Row>
|
|
168
|
+
<Typography tokens={{ ...headerStyles, lineHeight: headerLineHeight }}>
|
|
169
|
+
{getCopy('filterByLabel').replace(/%\{filterCategory\}/g, label.toLowerCase())}
|
|
170
|
+
</Typography>
|
|
171
|
+
</Row>
|
|
172
|
+
{subtitle && (
|
|
173
|
+
<>
|
|
174
|
+
<Spacer space={5} />
|
|
175
|
+
<Row>
|
|
176
|
+
<Typography tokens={{ ...subeHeaderStyles, lineHeight: subHeaderLineHeight }}>
|
|
177
|
+
{subtitle}
|
|
178
|
+
</Typography>
|
|
179
|
+
</Row>
|
|
180
|
+
</>
|
|
181
|
+
)}
|
|
182
|
+
<Spacer space={4} />
|
|
183
|
+
<Box scroll={true}>
|
|
184
|
+
<Row distribute="between">
|
|
185
|
+
{[...Array(colSize).keys()].map((i) => (
|
|
186
|
+
<Col xs={12 / colSize} key={i}>
|
|
187
|
+
<CheckboxGroup
|
|
188
|
+
items={items.slice(i * rowLength, (i + 1) * rowLength)}
|
|
189
|
+
checkedIds={checkedIds}
|
|
190
|
+
onChange={(e) => setCheckedIds(e, i)}
|
|
191
|
+
/>
|
|
192
|
+
<Spacer size={4} />
|
|
193
|
+
</Col>
|
|
194
|
+
))}
|
|
195
|
+
</Row>
|
|
196
|
+
</Box>
|
|
197
|
+
<Divider variant={selectDividerToknes({ ...themeTokens, width: 'full' })} space={4} />
|
|
198
|
+
<Row horizontalAlign={buttonDirection === 'column' ? 'center' : 'start'}>
|
|
199
|
+
<StackView
|
|
200
|
+
direction={buttonDirection}
|
|
201
|
+
space={3}
|
|
202
|
+
tokens={{
|
|
203
|
+
alignItems: 'center',
|
|
204
|
+
...(viewport === 'xs' && { flexGrow: 1 })
|
|
205
|
+
}}
|
|
206
|
+
>
|
|
207
|
+
<Button
|
|
208
|
+
onPress={() => onApply(checkedIds)}
|
|
209
|
+
variant={{
|
|
210
|
+
size: 'small',
|
|
211
|
+
priority: 'high',
|
|
212
|
+
...(viewport === 'xs' && { width: 'full' })
|
|
213
|
+
}}
|
|
214
|
+
>
|
|
215
|
+
{getCopy('applyButtonLabel')}
|
|
216
|
+
</Button>
|
|
217
|
+
<Box>
|
|
218
|
+
<TextButton onPress={() => onClear()}>{getCopy('clearButtonLabel')}</TextButton>
|
|
219
|
+
</Box>
|
|
220
|
+
</StackView>
|
|
221
|
+
</Row>
|
|
222
|
+
</Modal>
|
|
223
|
+
)}
|
|
224
|
+
{isOpen && viewport !== 'xs' && (
|
|
124
225
|
<ModalOverlay
|
|
125
226
|
overlaidPosition={overlaidPosition}
|
|
126
|
-
variant={{ width: colSize > 1 ? 'size576' : 's' }}
|
|
127
227
|
onClose={() => setIsOpen(false)}
|
|
128
|
-
|
|
228
|
+
maxHeight={maxHeight}
|
|
229
|
+
maxHeightSize={maxHeightSize}
|
|
230
|
+
maxWidthSize={maxWidthSize}
|
|
231
|
+
minHeight={minHeight}
|
|
232
|
+
minWidth={minWidth}
|
|
233
|
+
tokens={{
|
|
234
|
+
...tokens,
|
|
235
|
+
maxWidth
|
|
236
|
+
}}
|
|
129
237
|
copy={copy}
|
|
130
238
|
isReady={isReady}
|
|
131
239
|
onLayout={onTargetLayout}
|
|
132
240
|
>
|
|
133
241
|
<Row>
|
|
134
|
-
<Typography
|
|
242
|
+
<Typography tokens={{ ...headerStyles, lineHeight: headerLineHeight }}>
|
|
135
243
|
{getCopy('filterByLabel').replace(/%\{filterCategory\}/g, label.toLowerCase())}
|
|
136
244
|
</Typography>
|
|
137
245
|
</Row>
|
|
@@ -139,7 +247,7 @@ const MultiSelectFilter = ({
|
|
|
139
247
|
<>
|
|
140
248
|
<Spacer space={5} />
|
|
141
249
|
<Row>
|
|
142
|
-
<Typography
|
|
250
|
+
<Typography tokens={{ ...subeHeaderStyles, lineHeight: subHeaderLineHeight }}>
|
|
143
251
|
{subtitle}
|
|
144
252
|
</Typography>
|
|
145
253
|
</Row>
|
|
@@ -151,7 +259,7 @@ const MultiSelectFilter = ({
|
|
|
151
259
|
{[...Array(colSize).keys()].map((i) => (
|
|
152
260
|
<Col xs={12 / colSize} key={i}>
|
|
153
261
|
<CheckboxGroup
|
|
154
|
-
items={items.slice(i *
|
|
262
|
+
items={items.slice(i * rowLength, (i + 1) * rowLength)}
|
|
155
263
|
checkedIds={checkedIds}
|
|
156
264
|
onChange={(e) => setCheckedIds(e, i)}
|
|
157
265
|
/>
|
|
@@ -161,18 +269,27 @@ const MultiSelectFilter = ({
|
|
|
161
269
|
</Row>
|
|
162
270
|
</Box>
|
|
163
271
|
<Divider variant={selectDividerToknes({ ...themeTokens, width: 'full' })} space={4} />
|
|
164
|
-
<Row>
|
|
165
|
-
<StackView
|
|
272
|
+
<Row horizontalAlign={buttonDirection === 'column' ? 'center' : 'start'}>
|
|
273
|
+
<StackView
|
|
274
|
+
direction={buttonDirection}
|
|
275
|
+
space={3}
|
|
276
|
+
tokens={{
|
|
277
|
+
alignItems: 'center',
|
|
278
|
+
...(viewport === 'xs' && { flexGrow: 1 })
|
|
279
|
+
}}
|
|
280
|
+
>
|
|
166
281
|
<Button
|
|
167
282
|
onPress={() => onApply(checkedIds)}
|
|
168
|
-
variant={{
|
|
283
|
+
variant={{
|
|
284
|
+
size: 'small',
|
|
285
|
+
priority: 'high',
|
|
286
|
+
...(viewport === 'xs' && { width: 'full' })
|
|
287
|
+
}}
|
|
169
288
|
>
|
|
170
289
|
{getCopy('applyButtonLabel')}
|
|
171
290
|
</Button>
|
|
172
291
|
<Box>
|
|
173
|
-
<TextButton onPress={() =>
|
|
174
|
-
{getCopy('clearButtonLabel')}
|
|
175
|
-
</TextButton>
|
|
292
|
+
<TextButton onPress={() => onClear()}>{getCopy('clearButtonLabel')}</TextButton>
|
|
176
293
|
</Box>
|
|
177
294
|
</StackView>
|
|
178
295
|
</Row>
|
|
@@ -239,10 +356,15 @@ MultiSelectFilter.propTypes = {
|
|
|
239
356
|
* If provided, sets a maximum number of items a user may select at once.
|
|
240
357
|
*/
|
|
241
358
|
maxValues: PropTypes.number,
|
|
359
|
+
/**
|
|
360
|
+
* If provided sets maxHeight to be active
|
|
361
|
+
*/
|
|
362
|
+
maxHeight: PropTypes.bool,
|
|
242
363
|
/**
|
|
243
364
|
* If provided, this function is called when the current selection is changed
|
|
244
365
|
* and is passed an array of the `id`s of all currently selected `items`.
|
|
245
366
|
*/
|
|
367
|
+
|
|
246
368
|
onChange: PropTypes.func,
|
|
247
369
|
/**
|
|
248
370
|
* Select English or French copy for the accessible label.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
|
|
4
4
|
import { Image, Platform, Text, View } from 'react-native'
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
selectSystemProps
|
|
12
12
|
} from '../utils'
|
|
13
13
|
import { useViewport } from '../ViewportProvider'
|
|
14
|
-
import { useThemeTokensCallback } from '../ThemeProvider'
|
|
14
|
+
import { applyTextStyles, useThemeTokensCallback } from '../ThemeProvider'
|
|
15
15
|
import { Link } from '../Link'
|
|
16
16
|
import { StackWrap } from '../StackView'
|
|
17
17
|
|
|
@@ -29,6 +29,7 @@ const selectImageStyle = (imageDimension) => ({
|
|
|
29
29
|
|
|
30
30
|
const selectContainerStyle = ({ contentMaxDimension, textAlign }) => ({
|
|
31
31
|
textAlign,
|
|
32
|
+
outline: 'red',
|
|
32
33
|
width: contentMaxDimension,
|
|
33
34
|
overflow: 'hidden'
|
|
34
35
|
})
|
|
@@ -40,6 +41,8 @@ const selectImageContainerStyle = (contentMaxDimension) => ({
|
|
|
40
41
|
alignItems: 'center'
|
|
41
42
|
})
|
|
42
43
|
|
|
44
|
+
const selectLinkToken = ({ outerBorderColor }) => ({ outerBorderColor })
|
|
45
|
+
|
|
43
46
|
/**
|
|
44
47
|
* Component export along with QuickLinksFeature to be used as children
|
|
45
48
|
*
|
|
@@ -49,42 +52,46 @@ const QuickLinksFeatureItem = forwardRef(
|
|
|
49
52
|
({ tokens, variant, children, imageAccessibilityLabel, imageSource, ...rest }, ref) => {
|
|
50
53
|
const viewport = useViewport()
|
|
51
54
|
const getTokens = useThemeTokensCallback('QuickLinksFeatureItem', tokens, variant)
|
|
52
|
-
const [hover, setHover] = useState(false)
|
|
53
|
-
const {
|
|
54
|
-
contentDirection,
|
|
55
|
-
contentSpace,
|
|
56
|
-
contentAlignItems,
|
|
57
|
-
contentMaxDimension,
|
|
58
|
-
imageDimension,
|
|
59
|
-
textAlign
|
|
60
|
-
} = getTokens({ viewport, hover })
|
|
61
55
|
|
|
62
56
|
return (
|
|
63
|
-
<Link
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
57
|
+
<Link ref={ref} {...selectProps(rest)} tokens={(state) => selectLinkToken(getTokens(state))}>
|
|
58
|
+
{({ hovered: hover, pressed, focused: focus }) => {
|
|
59
|
+
const {
|
|
60
|
+
contentDirection,
|
|
61
|
+
contentSpace,
|
|
62
|
+
contentAlignItems,
|
|
63
|
+
contentMaxDimension,
|
|
64
|
+
imageDimension,
|
|
65
|
+
textLine,
|
|
66
|
+
gap,
|
|
67
|
+
...themeTokens
|
|
68
|
+
} = getTokens({ viewport, hover, pressed, focus })
|
|
69
|
+
|
|
70
|
+
const textStyle = {
|
|
71
|
+
...applyTextStyles(themeTokens),
|
|
72
|
+
textDecorationLine: textLine
|
|
73
|
+
}
|
|
74
|
+
return (
|
|
75
|
+
<View style={selectContainerStyle({ ...themeTokens, contentMaxDimension })}>
|
|
76
|
+
<StackWrap
|
|
77
|
+
direction={contentDirection}
|
|
78
|
+
space={contentSpace}
|
|
79
|
+
gap={gap}
|
|
80
|
+
tokens={{ alignItems: contentAlignItems }}
|
|
81
|
+
>
|
|
82
|
+
<View style={selectImageContainerStyle(contentMaxDimension)}>
|
|
83
|
+
<Image
|
|
84
|
+
accessibilityIgnoresInvertColors
|
|
85
|
+
imageAccessibilityLabel={imageAccessibilityLabel}
|
|
86
|
+
source={imageSource}
|
|
87
|
+
style={selectImageStyle(imageDimension)}
|
|
88
|
+
/>
|
|
89
|
+
</View>
|
|
90
|
+
<Text style={textStyle}>{children}</Text>
|
|
91
|
+
</StackWrap>
|
|
84
92
|
</View>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
</View>
|
|
93
|
+
)
|
|
94
|
+
}}
|
|
88
95
|
</Link>
|
|
89
96
|
)
|
|
90
97
|
}
|
package/src/StepTracker/Step.jsx
CHANGED
|
@@ -59,17 +59,18 @@ const selectKnobStyles = (
|
|
|
59
59
|
height: knobSize,
|
|
60
60
|
width: knobSize,
|
|
61
61
|
...(isCompleted && {
|
|
62
|
-
backgroundColor: knobCompletedBackgroundColor,
|
|
63
|
-
borderColor: knobCompletedBorderColor,
|
|
64
|
-
paddingLeft: knobCompletedPaddingLeft,
|
|
65
|
-
paddingTop: knobCompletedPaddingTop
|
|
66
|
-
}),
|
|
67
|
-
...(isCurrent && {
|
|
68
62
|
backgroundColor: knobCurrentBackgroundColor,
|
|
69
63
|
borderColor: knobCurrentBorderColor,
|
|
70
64
|
borderWidth: knobCurrentBorderWidth,
|
|
71
65
|
paddingLeft: knobCurrentPaddingLeft,
|
|
72
66
|
paddingTop: knobCurrentPaddingTop
|
|
67
|
+
}),
|
|
68
|
+
...(isCurrent && {
|
|
69
|
+
backgroundColor: knobCompletedBackgroundColor,
|
|
70
|
+
borderColor: knobCompletedBorderColor,
|
|
71
|
+
borderWidth: knobCurrentBorderWidth,
|
|
72
|
+
paddingLeft: knobCompletedPaddingLeft,
|
|
73
|
+
paddingTop: knobCompletedPaddingTop
|
|
73
74
|
})
|
|
74
75
|
})
|
|
75
76
|
const selectLabelContainerStyles = ({
|
|
@@ -85,6 +86,26 @@ const selectLabelContainerStyles = ({
|
|
|
85
86
|
flexDirection: labelDirection,
|
|
86
87
|
gap: labelGap
|
|
87
88
|
})
|
|
89
|
+
const selectStepLabelStyles = (
|
|
90
|
+
{
|
|
91
|
+
stepLabelColor,
|
|
92
|
+
labelCurrentColor,
|
|
93
|
+
stepLabelFontWeight,
|
|
94
|
+
stepLabelFontSize,
|
|
95
|
+
stepLabelFontName,
|
|
96
|
+
stepLabelLineHeight
|
|
97
|
+
},
|
|
98
|
+
themeOptions,
|
|
99
|
+
isCurrent
|
|
100
|
+
) =>
|
|
101
|
+
applyTextStyles({
|
|
102
|
+
color: isCurrent ? labelCurrentColor : stepLabelColor,
|
|
103
|
+
fontSize: stepLabelFontSize,
|
|
104
|
+
lineHeight: stepLabelLineHeight,
|
|
105
|
+
fontWeight: stepLabelFontWeight,
|
|
106
|
+
fontName: stepLabelFontName,
|
|
107
|
+
themeOptions
|
|
108
|
+
})
|
|
88
109
|
const selectLabelStyles = (
|
|
89
110
|
{
|
|
90
111
|
labelColor,
|
|
@@ -121,7 +142,8 @@ const getStepTestID = (isCompleted, isCurrent) => {
|
|
|
121
142
|
* A single step of a StepTracker.
|
|
122
143
|
*/
|
|
123
144
|
const Step = ({ label, name, status = 0, stepCount = 0, stepIndex = 0, tokens, ...rest }) => {
|
|
124
|
-
const { completedIcon, showStepLabel, showStepName, ...themeTokens } =
|
|
145
|
+
const { completedIcon, showStepLabel, showStepName, textStepTrackerLabel, ...themeTokens } =
|
|
146
|
+
tokens
|
|
125
147
|
const isFirst = stepIndex === 0
|
|
126
148
|
const isLast = stepIndex === stepCount - 1
|
|
127
149
|
const isCompleted = status > stepIndex
|
|
@@ -150,10 +172,12 @@ const Step = ({ label, name, status = 0, stepCount = 0, stepIndex = 0, tokens, .
|
|
|
150
172
|
style={[staticStyles.knob, selectKnobStyles(themeTokens, isCompleted, isCurrent)]}
|
|
151
173
|
testID={getStepTestID(isCompleted, isCurrent)}
|
|
152
174
|
>
|
|
153
|
-
{isCompleted && completedIcon && (
|
|
175
|
+
{((isCompleted && completedIcon) || (isCurrent && !completedIcon)) && (
|
|
176
|
+
<View style={selectCurrentInnerStyles(themeTokens)} />
|
|
177
|
+
)}
|
|
178
|
+
{isCurrent && completedIcon && (
|
|
154
179
|
<Icon icon={completedIcon} tokens={selectCompletedIconTokens(themeTokens)} />
|
|
155
180
|
)}
|
|
156
|
-
{isCurrent && <View style={selectCurrentInnerStyles(themeTokens)} />}
|
|
157
181
|
</View>
|
|
158
182
|
<View
|
|
159
183
|
style={[
|
|
@@ -168,7 +192,7 @@ const Step = ({ label, name, status = 0, stepCount = 0, stepIndex = 0, tokens, .
|
|
|
168
192
|
<Text
|
|
169
193
|
style={[
|
|
170
194
|
staticStyles.centeredText,
|
|
171
|
-
|
|
195
|
+
selectStepLabelStyles(tokens, themeOptions, isCurrent)
|
|
172
196
|
]}
|
|
173
197
|
>
|
|
174
198
|
{name}
|
|
@@ -92,9 +92,13 @@ const StepTracker = forwardRef(
|
|
|
92
92
|
viewport
|
|
93
93
|
}
|
|
94
94
|
)
|
|
95
|
+
const { textStepTrackerLabel } = themeTokens
|
|
95
96
|
const getCopy = useCopy({ dictionary, copy })
|
|
96
97
|
const stepTrackerLabel = showStepTrackerLabel
|
|
97
|
-
?
|
|
98
|
+
? (typeof copy === 'string'
|
|
99
|
+
? getCopy(textStepTrackerLabel ?? 1).stepTrackerLabel
|
|
100
|
+
: getCopy('stepTrackerLabel')
|
|
101
|
+
)
|
|
98
102
|
.replace('%{stepNumber}', current < steps.length ? current + 1 : steps.length)
|
|
99
103
|
.replace('%{stepCount}', steps.length)
|
|
100
104
|
.replace(
|
|
@@ -103,7 +107,12 @@ const StepTracker = forwardRef(
|
|
|
103
107
|
)
|
|
104
108
|
: ''
|
|
105
109
|
const getStepLabel = (index) =>
|
|
106
|
-
themeTokens.showStepLabel
|
|
110
|
+
themeTokens.showStepLabel
|
|
111
|
+
? (typeof copy === 'string'
|
|
112
|
+
? getCopy(textStepTrackerLabel ?? 1).stepLabel
|
|
113
|
+
: getCopy('stepLabel')
|
|
114
|
+
).replace('%{stepNumber}', index + 1)
|
|
115
|
+
: ''
|
|
107
116
|
const { themeOptions } = useTheme()
|
|
108
117
|
if (!steps.length) return null
|
|
109
118
|
const selectedProps = selectProps({
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
en: {
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
1: {
|
|
4
|
+
stepLabel: 'Step %{stepNumber}',
|
|
5
|
+
stepTrackerLabel: 'Step %{stepNumber} of %{stepCount}: %{stepLabel}'
|
|
6
|
+
},
|
|
7
|
+
2: {
|
|
8
|
+
stepLabel: '%{stepNumber}.',
|
|
9
|
+
stepTrackerLabel: 'Step %{stepNumber} of %{stepCount}: %{stepLabel}'
|
|
10
|
+
},
|
|
11
|
+
3: {
|
|
12
|
+
stepLabel: 'Step %{stepNumber}',
|
|
13
|
+
stepTrackerLabel: 'Step %{stepNumber} of %{stepCount}: %{stepLabel}'
|
|
14
|
+
}
|
|
5
15
|
},
|
|
6
16
|
fr: {
|
|
7
|
-
|
|
8
|
-
|
|
17
|
+
1: {
|
|
18
|
+
stepLabel: 'Étape %{stepNumber}',
|
|
19
|
+
stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
|
|
20
|
+
},
|
|
21
|
+
2: {
|
|
22
|
+
stepLabel: '%{stepNumber}.',
|
|
23
|
+
stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
|
|
24
|
+
},
|
|
25
|
+
3: {
|
|
26
|
+
stepLabel: 'Étape %{stepNumber}',
|
|
27
|
+
stepTrackerLabel: 'Étape %{stepNumber} sur %{stepCount}: %{stepLabel}'
|
|
28
|
+
}
|
|
9
29
|
}
|
|
10
30
|
}
|
|
@@ -52,11 +52,14 @@ const TextInput = forwardRef(({ tokens, nativeID, variant = {}, ...rest }, ref)
|
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
return (
|
|
55
|
-
|
|
56
|
-
{
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
<>
|
|
56
|
+
<InputSupports nativeID={nativeID} {...supportsProps}>
|
|
57
|
+
{({ inputId, ...propsFromInputSupports }) => (
|
|
58
|
+
<TextInputBase ref={ref} nativeID={inputId} {...propsFromInputSupports} {...inputProps} />
|
|
59
|
+
)}
|
|
60
|
+
</InputSupports>
|
|
61
|
+
{rest.children}
|
|
62
|
+
</>
|
|
60
63
|
)
|
|
61
64
|
})
|
|
62
65
|
TextInput.displayName = 'TextInput'
|