@telus-uds/components-base 1.5.0 → 1.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/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-lint.log +13 -0
- package/CHANGELOG.json +154 -1
- package/CHANGELOG.md +47 -2
- package/__tests__/FlexGrid/Row.test.jsx +100 -25
- package/__tests__/utils/containUniqueFields.test.js +25 -0
- package/component-docs.json +78 -26
- package/generate-component-docs.js +20 -7
- package/lib/Button/ButtonBase.js +1 -1
- package/lib/Button/ButtonGroup.js +20 -12
- package/lib/Card/PressableCardBase.js +1 -1
- package/lib/Checkbox/Checkbox.js +27 -16
- package/lib/Checkbox/CheckboxGroup.js +19 -5
- package/lib/ExpandCollapse/Panel.js +10 -10
- package/lib/FlexGrid/Col/Col.js +13 -3
- package/lib/FlexGrid/Row/Row.js +8 -2
- package/lib/InputLabel/InputLabel.js +27 -25
- package/lib/Link/LinkBase.js +19 -6
- package/lib/Link/TextButton.js +1 -10
- package/lib/List/ListItem.js +22 -12
- package/lib/Modal/Modal.js +18 -18
- package/lib/Radio/Radio.js +23 -12
- package/lib/Radio/RadioGroup.js +12 -3
- package/lib/RadioCard/RadioCard.js +1 -1
- package/lib/RadioCard/RadioCardGroup.js +11 -2
- package/lib/Search/Search.js +27 -19
- package/lib/Select/Select.js +2 -3
- package/lib/Tags/Tags.js +23 -17
- package/lib/TextInput/TextArea.js +2 -2
- package/lib/TextInput/TextInput.js +12 -2
- package/lib/TextInput/TextInputBase.js +1 -1
- package/lib/TextInput/propTypes.js +8 -1
- package/lib/ToggleSwitch/ToggleSwitch.js +5 -2
- package/lib/ToggleSwitch/ToggleSwitchGroup.js +20 -12
- package/lib/Typography/Typography.js +12 -10
- package/lib/index.js +22 -1
- package/lib/utils/containUniqueFields.js +34 -0
- package/lib/utils/index.js +10 -1
- package/lib/utils/input.js +5 -6
- package/lib/utils/props/handlerProps.js +72 -0
- package/lib/utils/props/index.js +32 -0
- package/lib/utils/props/inputSupportsProps.js +3 -5
- package/lib/utils/props/linkProps.js +3 -7
- package/lib/utils/props/textInputProps.js +206 -0
- package/lib/utils/props/textProps.js +72 -0
- package/lib-module/Button/ButtonBase.js +2 -2
- package/lib-module/Button/ButtonGroup.js +15 -6
- package/lib-module/Card/PressableCardBase.js +2 -2
- package/lib-module/Checkbox/Checkbox.js +28 -17
- package/lib-module/Checkbox/CheckboxGroup.js +20 -7
- package/lib-module/ExpandCollapse/Panel.js +10 -10
- package/lib-module/FlexGrid/Col/Col.js +13 -3
- package/lib-module/FlexGrid/Row/Row.js +8 -2
- package/lib-module/InputLabel/InputLabel.js +28 -25
- package/lib-module/Link/LinkBase.js +19 -6
- package/lib-module/Link/TextButton.js +1 -10
- package/lib-module/List/ListItem.js +22 -12
- package/lib-module/Modal/Modal.js +19 -19
- package/lib-module/Radio/Radio.js +24 -13
- package/lib-module/Radio/RadioGroup.js +13 -4
- package/lib-module/RadioCard/RadioCard.js +2 -2
- package/lib-module/RadioCard/RadioCardGroup.js +12 -3
- package/lib-module/Search/Search.js +29 -21
- package/lib-module/Select/Select.js +2 -3
- package/lib-module/Tags/Tags.js +18 -11
- package/lib-module/TextInput/TextArea.js +3 -3
- package/lib-module/TextInput/TextInput.js +11 -3
- package/lib-module/TextInput/TextInputBase.js +2 -2
- package/lib-module/TextInput/propTypes.js +7 -1
- package/lib-module/ToggleSwitch/ToggleSwitch.js +6 -3
- package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +15 -6
- package/lib-module/Typography/Typography.js +13 -11
- package/lib-module/index.js +1 -1
- package/lib-module/utils/containUniqueFields.js +26 -0
- package/lib-module/utils/index.js +2 -1
- package/lib-module/utils/input.js +6 -6
- package/lib-module/utils/props/handlerProps.js +59 -0
- package/lib-module/utils/props/index.js +3 -0
- package/lib-module/utils/props/inputSupportsProps.js +3 -5
- package/lib-module/utils/props/linkProps.js +3 -7
- package/lib-module/utils/props/textInputProps.js +193 -0
- package/lib-module/utils/props/textProps.js +59 -0
- package/package.json +5 -5
- package/src/Button/ButtonBase.jsx +8 -2
- package/src/Button/ButtonGroup.jsx +51 -34
- package/src/Card/PressableCardBase.jsx +6 -1
- package/src/Checkbox/Checkbox.jsx +35 -23
- package/src/Checkbox/CheckboxGroup.jsx +52 -22
- package/src/ExpandCollapse/Panel.jsx +9 -9
- package/src/FlexGrid/Col/Col.jsx +11 -2
- package/src/FlexGrid/Row/Row.jsx +8 -2
- package/src/InputLabel/InputLabel.jsx +36 -27
- package/src/Link/LinkBase.jsx +20 -4
- package/src/Link/TextButton.jsx +1 -19
- package/src/List/ListItem.jsx +17 -9
- package/src/Modal/Modal.jsx +30 -26
- package/src/Radio/Radio.jsx +26 -14
- package/src/Radio/RadioGroup.jsx +39 -21
- package/src/RadioCard/RadioCard.jsx +6 -1
- package/src/RadioCard/RadioCardGroup.jsx +17 -1
- package/src/Search/Search.jsx +33 -21
- package/src/Select/Select.jsx +2 -2
- package/src/Tags/Tags.jsx +23 -9
- package/src/TextInput/TextArea.jsx +7 -1
- package/src/TextInput/TextInput.jsx +15 -3
- package/src/TextInput/TextInputBase.jsx +8 -1
- package/src/TextInput/propTypes.js +7 -1
- package/src/ToggleSwitch/ToggleSwitch.jsx +11 -2
- package/src/ToggleSwitch/ToggleSwitchGroup.jsx +19 -6
- package/src/Typography/Typography.jsx +13 -9
- package/src/index.js +4 -1
- package/src/utils/containUniqueFields.js +32 -0
- package/src/utils/index.js +1 -0
- package/src/utils/input.js +5 -7
- package/src/utils/props/handlerProps.js +47 -0
- package/src/utils/props/index.js +3 -0
- package/src/utils/props/inputSupportsProps.js +3 -4
- package/src/utils/props/linkProps.js +3 -6
- package/src/utils/props/textInputProps.js +177 -0
- package/src/utils/props/textProps.js +58 -0
- package/stories/InputLabel/InputLabel.stories.jsx +25 -28
- package/stories/Modal/Modal.stories.jsx +25 -0
- package/stories/Search/Search.stories.jsx +53 -3
- package/stories/TextInput/TextInput.stories.jsx +40 -2
- package/__tests__/Link/LinkBase.test.jsx +0 -22
|
@@ -9,17 +9,25 @@ import { useViewport } from '../ViewportProvider'
|
|
|
9
9
|
import { useThemeTokens, useThemeTokensCallback } from '../ThemeProvider'
|
|
10
10
|
import {
|
|
11
11
|
a11yProps,
|
|
12
|
+
containUniqueFields,
|
|
13
|
+
focusHandlerProps,
|
|
12
14
|
pressProps,
|
|
13
15
|
getTokensPropType,
|
|
14
16
|
selectSystemProps,
|
|
15
17
|
selectTokens,
|
|
18
|
+
useMultipleInputValues,
|
|
16
19
|
variantProp,
|
|
17
20
|
viewProps
|
|
18
|
-
} from '../utils
|
|
19
|
-
import { useMultipleInputValues } from '../utils/input'
|
|
21
|
+
} from '../utils'
|
|
20
22
|
import { getPressHandlersWithArgs } from '../utils/pressability'
|
|
21
23
|
|
|
22
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps,
|
|
24
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
25
|
+
const [selectItemProps, selectedItemPropTypes] = selectSystemProps([
|
|
26
|
+
a11yProps,
|
|
27
|
+
focusHandlerProps,
|
|
28
|
+
pressProps,
|
|
29
|
+
viewProps
|
|
30
|
+
])
|
|
23
31
|
|
|
24
32
|
const ButtonGroup = forwardRef(
|
|
25
33
|
(
|
|
@@ -61,6 +69,11 @@ const ButtonGroup = forwardRef(
|
|
|
61
69
|
})
|
|
62
70
|
const itemA11yRole = systemProps.accessibilityRole === 'radiogroup' ? 'radio' : 'checkbox'
|
|
63
71
|
|
|
72
|
+
const uniqueFields = ['id', 'label']
|
|
73
|
+
if (!containUniqueFields(items, uniqueFields)) {
|
|
74
|
+
throw new Error(`ButtonGroup items must have unique ${uniqueFields.join(', ')}`)
|
|
75
|
+
}
|
|
76
|
+
|
|
64
77
|
return (
|
|
65
78
|
<StackWrap
|
|
66
79
|
{...systemProps}
|
|
@@ -69,41 +82,44 @@ const ButtonGroup = forwardRef(
|
|
|
69
82
|
tokens={stackTokens}
|
|
70
83
|
ref={ref}
|
|
71
84
|
>
|
|
72
|
-
{items.map(
|
|
73
|
-
|
|
85
|
+
{items.map(
|
|
86
|
+
({ label, id = label, accessibilityLabel, ref: itemRef, ...itemRest }, index) => {
|
|
87
|
+
const isSelected = currentValues.includes(id)
|
|
74
88
|
|
|
75
|
-
|
|
76
|
-
|
|
89
|
+
// Pass an object of relevant component state as first argument for any passed-in press handlers
|
|
90
|
+
const pressHandlers = getPressHandlersWithArgs(rest, [{ id, label, currentValues }])
|
|
77
91
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
const handlePress = (event) => {
|
|
93
|
+
if (pressHandlers.onPress) pressHandlers.onPress(event)
|
|
94
|
+
toggleOneValue(id, event)
|
|
95
|
+
}
|
|
82
96
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
97
|
+
const itemA11y = {
|
|
98
|
+
accessibilityState: { checked: isSelected },
|
|
99
|
+
accessibilityRole: itemA11yRole,
|
|
100
|
+
accessibilityLabel,
|
|
101
|
+
...a11yProps.getPositionInSet(items.length, index)
|
|
102
|
+
}
|
|
89
103
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
// Ensure button is direct child of group as MacOS voiceover only applies "X of Y" to
|
|
105
|
+
// "radio" if it's a direct child of "radiogroup", even if aria-posinset etc exists
|
|
106
|
+
return (
|
|
107
|
+
<ButtonBase
|
|
108
|
+
ref={itemRef}
|
|
109
|
+
key={id}
|
|
110
|
+
{...pressHandlers}
|
|
111
|
+
onPress={handlePress}
|
|
112
|
+
tokens={getButtonTokens}
|
|
113
|
+
selected={isSelected}
|
|
114
|
+
inactive={inactive}
|
|
115
|
+
{...itemA11y}
|
|
116
|
+
{...selectItemProps(itemRest)}
|
|
117
|
+
>
|
|
118
|
+
{label}
|
|
119
|
+
</ButtonBase>
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
)}
|
|
107
123
|
</StackWrap>
|
|
108
124
|
)
|
|
109
125
|
}
|
|
@@ -124,6 +140,7 @@ ButtonGroup.propTypes = {
|
|
|
124
140
|
*/
|
|
125
141
|
items: PropTypes.arrayOf(
|
|
126
142
|
PropTypes.shape({
|
|
143
|
+
...selectedItemPropTypes,
|
|
127
144
|
/**
|
|
128
145
|
* The text displayed to the user in the button, describing this option,
|
|
129
146
|
* passed to the button as its child.
|
|
@@ -7,6 +7,7 @@ import { applyOuterBorder, validateThemeTokens } from '../ThemeProvider'
|
|
|
7
7
|
import {
|
|
8
8
|
a11yProps,
|
|
9
9
|
clickProps,
|
|
10
|
+
focusHandlerProps,
|
|
10
11
|
getTokenNames,
|
|
11
12
|
getTokensSetPropType,
|
|
12
13
|
linkProps,
|
|
@@ -20,7 +21,11 @@ import {
|
|
|
20
21
|
} from '../utils'
|
|
21
22
|
import CardBase from './CardBase'
|
|
22
23
|
|
|
23
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
24
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
25
|
+
a11yProps,
|
|
26
|
+
focusHandlerProps,
|
|
27
|
+
viewProps
|
|
28
|
+
])
|
|
24
29
|
|
|
25
30
|
const tokenKeys = [
|
|
26
31
|
...getTokenNames('Card'),
|
|
@@ -9,6 +9,7 @@ import StackView from '../StackView'
|
|
|
9
9
|
import { applyShadowToken, applyTextStyles, useThemeTokensCallback } from '../ThemeProvider'
|
|
10
10
|
import {
|
|
11
11
|
a11yProps,
|
|
12
|
+
focusHandlerProps,
|
|
12
13
|
getTokensPropType,
|
|
13
14
|
selectSystemProps,
|
|
14
15
|
useInputValue,
|
|
@@ -17,7 +18,11 @@ import {
|
|
|
17
18
|
} from '../utils'
|
|
18
19
|
import useUniqueId from '../utils/useUniqueId'
|
|
19
20
|
|
|
20
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
21
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
22
|
+
a11yProps,
|
|
23
|
+
focusHandlerProps,
|
|
24
|
+
viewProps
|
|
25
|
+
])
|
|
21
26
|
|
|
22
27
|
const selectInputStyles = (
|
|
23
28
|
{
|
|
@@ -179,32 +184,38 @@ const Checkbox = forwardRef(
|
|
|
179
184
|
{({ focused: focus, hovered: hover, pressed }) => {
|
|
180
185
|
const { icon: IconComponent, ...stateTokens } = getTokens({ focus, hover, pressed })
|
|
181
186
|
const iconTokens = selectIconTokens(stateTokens)
|
|
187
|
+
const labelStyles = selectLabelStyles(stateTokens)
|
|
188
|
+
const alignWithLabel = label
|
|
189
|
+
? [staticStyles.alignWithLabel, { height: labelStyles.lineHeight }]
|
|
190
|
+
: null
|
|
182
191
|
|
|
183
192
|
return (
|
|
184
193
|
<View style={staticStyles.container}>
|
|
185
|
-
<View
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
194
|
+
<View style={alignWithLabel}>
|
|
195
|
+
<View
|
|
196
|
+
style={[
|
|
197
|
+
staticStyles.defaultInputStyles,
|
|
198
|
+
selectInputStyles(stateTokens, isChecked)
|
|
199
|
+
]}
|
|
200
|
+
testID="Checkbox-Input"
|
|
201
|
+
>
|
|
202
|
+
{/* Add a real input on Web, skip on native platforms */}
|
|
203
|
+
<CheckboxInput
|
|
204
|
+
checked={isChecked}
|
|
205
|
+
defaultChecked={defaultChecked}
|
|
206
|
+
disabled={inactive}
|
|
207
|
+
id={inputId}
|
|
208
|
+
isControlled={isControlled}
|
|
209
|
+
name={name}
|
|
210
|
+
value={value}
|
|
211
|
+
/>
|
|
212
|
+
{isChecked && IconComponent && (
|
|
213
|
+
<IconComponent {...iconTokens} testID="Checkbox-Icon" />
|
|
214
|
+
)}
|
|
215
|
+
</View>
|
|
205
216
|
</View>
|
|
206
217
|
{Boolean(label) && (
|
|
207
|
-
<Text style={
|
|
218
|
+
<Text style={labelStyles}>
|
|
208
219
|
<CheckboxLabel forId={inputId}>{label}</CheckboxLabel>
|
|
209
220
|
</Text>
|
|
210
221
|
)}
|
|
@@ -285,5 +296,6 @@ export default Checkbox
|
|
|
285
296
|
const staticStyles = StyleSheet.create({
|
|
286
297
|
wrapper: { backgroundColor: 'transparent' },
|
|
287
298
|
container: { flexDirection: 'row', alignItems: 'center' },
|
|
288
|
-
defaultInputStyles: { alignItems: 'center', justifyContent: 'center' }
|
|
299
|
+
defaultInputStyles: { alignItems: 'center', justifyContent: 'center' },
|
|
300
|
+
alignWithLabel: { alignSelf: 'flex-start', justifyContent: 'center' }
|
|
289
301
|
})
|
|
@@ -4,11 +4,27 @@ import ABBPropTypes from 'airbnb-prop-types'
|
|
|
4
4
|
|
|
5
5
|
import { useViewport } from '../ViewportProvider'
|
|
6
6
|
import { useThemeTokens } from '../ThemeProvider'
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
a11yProps,
|
|
9
|
+
containUniqueFields,
|
|
10
|
+
focusHandlerProps,
|
|
11
|
+
getTokensPropType,
|
|
12
|
+
selectSystemProps,
|
|
13
|
+
useMultipleInputValues,
|
|
14
|
+
variantProp,
|
|
15
|
+
viewProps
|
|
16
|
+
} from '../utils'
|
|
8
17
|
import { getStackedContent } from '../StackView'
|
|
9
18
|
import Checkbox from './Checkbox'
|
|
10
19
|
import Fieldset from '../Fieldset'
|
|
11
20
|
|
|
21
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
22
|
+
const [selectItemProps, selectedItemPropTypes] = selectSystemProps([
|
|
23
|
+
a11yProps,
|
|
24
|
+
focusHandlerProps,
|
|
25
|
+
viewProps
|
|
26
|
+
])
|
|
27
|
+
|
|
12
28
|
/**
|
|
13
29
|
* A group of Checkboxs that behave as a fieldset. Use when users select any number of choices from options.
|
|
14
30
|
*
|
|
@@ -73,7 +89,8 @@ const CheckboxGroup = forwardRef(
|
|
|
73
89
|
onChange,
|
|
74
90
|
readOnly,
|
|
75
91
|
name: inputGroupName,
|
|
76
|
-
inactive
|
|
92
|
+
inactive,
|
|
93
|
+
...rest
|
|
77
94
|
},
|
|
78
95
|
ref
|
|
79
96
|
) => {
|
|
@@ -89,27 +106,37 @@ const CheckboxGroup = forwardRef(
|
|
|
89
106
|
onChange,
|
|
90
107
|
readOnly: readOnly || inactive
|
|
91
108
|
})
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
109
|
+
|
|
110
|
+
const uniqueFields = ['id', 'label']
|
|
111
|
+
if (!containUniqueFields(items, uniqueFields)) {
|
|
112
|
+
throw new Error(`CheckboxGroup items must have unique ${uniqueFields.join(', ')}`)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const checkboxes = items.map(
|
|
116
|
+
({ label, id, onChange: itemOnChange, ref: itemRef, ...itemRest }, index) => {
|
|
117
|
+
const checkboxId = id || `Checkbox[${index}]`
|
|
118
|
+
const handleChange = (newCheckedState, event) => {
|
|
119
|
+
if (typeof itemOnChange === 'function') itemOnChange(newCheckedState, event)
|
|
120
|
+
toggleOneValue(checkboxId, event)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<Checkbox
|
|
125
|
+
ref={itemRef}
|
|
126
|
+
key={checkboxId}
|
|
127
|
+
id={checkboxId}
|
|
128
|
+
checked={currentValues.includes(checkboxId)}
|
|
129
|
+
onChange={handleChange}
|
|
130
|
+
inactive={inactive}
|
|
131
|
+
label={label}
|
|
132
|
+
name={inputGroupName}
|
|
133
|
+
tokens={radioTokens}
|
|
134
|
+
variant={variant}
|
|
135
|
+
{...selectItemProps(itemRest)}
|
|
136
|
+
/>
|
|
137
|
+
)
|
|
97
138
|
}
|
|
98
|
-
|
|
99
|
-
<Checkbox
|
|
100
|
-
ref={itemRef}
|
|
101
|
-
key={checkboxId}
|
|
102
|
-
id={checkboxId}
|
|
103
|
-
checked={currentValues.includes(checkboxId)}
|
|
104
|
-
onChange={handleChange}
|
|
105
|
-
inactive={inactive}
|
|
106
|
-
label={label}
|
|
107
|
-
name={inputGroupName}
|
|
108
|
-
tokens={radioTokens}
|
|
109
|
-
variant={variant}
|
|
110
|
-
/>
|
|
111
|
-
)
|
|
112
|
-
})
|
|
139
|
+
)
|
|
113
140
|
|
|
114
141
|
return (
|
|
115
142
|
<Fieldset
|
|
@@ -122,6 +149,7 @@ const CheckboxGroup = forwardRef(
|
|
|
122
149
|
feedback={feedback}
|
|
123
150
|
inactive={inactive}
|
|
124
151
|
validation={validation}
|
|
152
|
+
{...selectProps(rest)}
|
|
125
153
|
>
|
|
126
154
|
{getStackedContent(checkboxes, { space, direction: 'column' })}
|
|
127
155
|
</Fieldset>
|
|
@@ -131,6 +159,7 @@ const CheckboxGroup = forwardRef(
|
|
|
131
159
|
CheckboxGroup.displayName = 'CheckboxGroup'
|
|
132
160
|
|
|
133
161
|
CheckboxGroup.propTypes = {
|
|
162
|
+
...selectedSystemPropTypes,
|
|
134
163
|
/**
|
|
135
164
|
* Optional theme token overrides for the outer CheckboxGroup component
|
|
136
165
|
*/
|
|
@@ -148,6 +177,7 @@ CheckboxGroup.propTypes = {
|
|
|
148
177
|
*/
|
|
149
178
|
items: PropTypes.arrayOf(
|
|
150
179
|
PropTypes.exact({
|
|
180
|
+
...selectedItemPropTypes,
|
|
151
181
|
label: PropTypes.string,
|
|
152
182
|
id: PropTypes.string,
|
|
153
183
|
onChange: PropTypes.func,
|
|
@@ -74,8 +74,8 @@ const ExpandCollapsePanel = forwardRef(
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
const onContainerLayout = (event) => {
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
const { layout: { height = 0 } = {} } = event.nativeEvent
|
|
78
|
+
if (Platform.OS === 'web' || (Platform.OS !== 'web' && containerHeight === null)) {
|
|
79
79
|
setContainerHeight(height)
|
|
80
80
|
}
|
|
81
81
|
}
|
|
@@ -104,14 +104,14 @@ const ExpandCollapsePanel = forwardRef(
|
|
|
104
104
|
>
|
|
105
105
|
{control}
|
|
106
106
|
</ExpandCollapseControl>
|
|
107
|
-
<View
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
>
|
|
107
|
+
<Animated.View
|
|
108
|
+
style={[overflowContainerStyles, animatedStyles, staticStyles.itemsContainer]}
|
|
109
|
+
{...focusabilityProps}
|
|
110
|
+
>
|
|
111
|
+
<View onLayout={onContainerLayout}>
|
|
112
112
|
<View style={selectContainerStyles(themeTokens)}>{children}</View>
|
|
113
|
-
</
|
|
114
|
-
</View>
|
|
113
|
+
</View>
|
|
114
|
+
</Animated.View>
|
|
115
115
|
</View>
|
|
116
116
|
)
|
|
117
117
|
}
|
package/src/FlexGrid/Col/Col.jsx
CHANGED
|
@@ -23,6 +23,7 @@ const Col = forwardRef(
|
|
|
23
23
|
mdOffset,
|
|
24
24
|
lgOffset,
|
|
25
25
|
xlOffset,
|
|
26
|
+
flex,
|
|
26
27
|
...viewProps
|
|
27
28
|
},
|
|
28
29
|
ref
|
|
@@ -106,7 +107,10 @@ const Col = forwardRef(
|
|
|
106
107
|
|
|
107
108
|
let hidingStyles = {}
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
// TODO: consider setting this to always 'flex' in a major release.
|
|
111
|
+
// `display: block` is invalid in native apps.
|
|
112
|
+
// See https://telusdigital.atlassian.net/browse/UDS1-92
|
|
113
|
+
const shown = !flex && Platform.OS === 'web' ? 'block' : 'flex'
|
|
110
114
|
|
|
111
115
|
if (viewPort === viewports.xs) {
|
|
112
116
|
hidingStyles = {
|
|
@@ -267,7 +271,12 @@ Col.propTypes = {
|
|
|
267
271
|
*/
|
|
268
272
|
horizontalAlign: responsiveProps.getTypeOptionallyByViewport(
|
|
269
273
|
PropTypes.oneOf(['left', 'center', 'right'])
|
|
270
|
-
)
|
|
274
|
+
),
|
|
275
|
+
/**
|
|
276
|
+
* (web only) Stretches the column to fill vertical space using `display: flex`.
|
|
277
|
+
* In native apps, FlexGrid.Col behaves as if this is always true (as do all `View`s).
|
|
278
|
+
*/
|
|
279
|
+
flex: PropTypes.bool
|
|
271
280
|
}
|
|
272
281
|
|
|
273
282
|
export default Col
|
package/src/FlexGrid/Row/Row.jsx
CHANGED
|
@@ -72,21 +72,27 @@ const Row = forwardRef(
|
|
|
72
72
|
const reverseLevel = applyInheritance([xsReverse, smReverse, mdReverse, lgReverse, xlReverse])
|
|
73
73
|
|
|
74
74
|
let flexDirection = ''
|
|
75
|
+
let flexWrap = ''
|
|
75
76
|
|
|
76
77
|
if (viewPort === viewports.xs) {
|
|
77
78
|
flexDirection = reverseLevel[0] ? 'row-reverse' : 'row'
|
|
79
|
+
flexWrap = reverseLevel[0] ? 'wrap-reverse' : 'wrap'
|
|
78
80
|
}
|
|
79
81
|
if (viewPort === viewports.sm) {
|
|
80
82
|
flexDirection = reverseLevel[1] ? 'row-reverse' : 'row'
|
|
83
|
+
flexWrap = reverseLevel[1] ? 'wrap-reverse' : 'wrap'
|
|
81
84
|
}
|
|
82
85
|
if (viewPort === viewports.md) {
|
|
83
86
|
flexDirection = reverseLevel[2] ? 'row-reverse' : 'row'
|
|
87
|
+
flexWrap = reverseLevel[2] ? 'wrap-reverse' : 'wrap'
|
|
84
88
|
}
|
|
85
89
|
if (viewPort === viewports.lg) {
|
|
86
90
|
flexDirection = reverseLevel[3] ? 'row-reverse' : 'row'
|
|
91
|
+
flexWrap = reverseLevel[3] ? 'wrap-reverse' : 'wrap'
|
|
87
92
|
}
|
|
88
93
|
if (viewPort === viewports.xl) {
|
|
89
94
|
flexDirection = reverseLevel[4] ? 'row-reverse' : 'row'
|
|
95
|
+
flexWrap = reverseLevel[4] ? 'wrap-reverse' : 'wrap'
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
return (
|
|
@@ -97,6 +103,7 @@ const Row = forwardRef(
|
|
|
97
103
|
styles.row,
|
|
98
104
|
{
|
|
99
105
|
flexDirection,
|
|
106
|
+
flexWrap,
|
|
100
107
|
...horizontalAlignStyles(horizontalAlign),
|
|
101
108
|
...verticalAlignStyles(verticalAlign),
|
|
102
109
|
...distributeStyles(distribute)
|
|
@@ -118,8 +125,7 @@ const styles = StyleSheet.create({
|
|
|
118
125
|
flexGrow: 0,
|
|
119
126
|
flexShrink: 1,
|
|
120
127
|
flexBasis: 'auto',
|
|
121
|
-
flexDirection: 'row'
|
|
122
|
-
flexWrap: 'wrap'
|
|
128
|
+
flexDirection: 'row'
|
|
123
129
|
}
|
|
124
130
|
})
|
|
125
131
|
|
|
@@ -47,35 +47,46 @@ const InputLabel = forwardRef(
|
|
|
47
47
|
const isHintInline = hintPosition === 'inline'
|
|
48
48
|
|
|
49
49
|
return (
|
|
50
|
-
|
|
51
|
-
ref={ref}
|
|
52
|
-
style={[staticStyles.container, !isHintInline && staticStyles.containerWithHintBelow]}
|
|
53
|
-
{...selectProps(rest)}
|
|
54
|
-
>
|
|
55
|
-
<Text
|
|
56
|
-
style={[selectLabelStyles(themeTokens), selectGapStyles(themeTokens), staticStyles.label]}
|
|
57
|
-
>
|
|
58
|
-
<LabelContent forId={forId}>{label}</LabelContent>
|
|
59
|
-
</Text>
|
|
60
|
-
{hint && isHintInline && (
|
|
50
|
+
<>
|
|
51
|
+
<View ref={ref} style={staticStyles.container} {...selectProps(rest)}>
|
|
61
52
|
<Text
|
|
62
|
-
style={[
|
|
63
|
-
|
|
53
|
+
style={[
|
|
54
|
+
selectLabelStyles(themeTokens),
|
|
55
|
+
selectGapStyles(themeTokens),
|
|
56
|
+
staticStyles.label
|
|
57
|
+
]}
|
|
64
58
|
>
|
|
65
|
-
{
|
|
59
|
+
<LabelContent forId={forId}>{label}</LabelContent>
|
|
66
60
|
</Text>
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
61
|
+
{hint && isHintInline && (
|
|
62
|
+
<Text
|
|
63
|
+
style={[
|
|
64
|
+
selectHintStyles(themeTokens),
|
|
65
|
+
hasTooltip && selectGapStyles(themeTokens),
|
|
66
|
+
staticStyles.label
|
|
67
|
+
]}
|
|
68
|
+
nativeID={hintId}
|
|
69
|
+
>
|
|
70
|
+
{hint}
|
|
71
|
+
</Text>
|
|
72
|
+
)}
|
|
73
|
+
{hasTooltip && (
|
|
74
|
+
<View
|
|
75
|
+
style={[
|
|
76
|
+
staticStyles.tooltipAlign,
|
|
77
|
+
{ height: themeTokens.fontSize * themeTokens.lineHeight }
|
|
78
|
+
]}
|
|
79
|
+
>
|
|
80
|
+
<Tooltip content={tooltip} />
|
|
81
|
+
</View>
|
|
82
|
+
)}
|
|
83
|
+
</View>
|
|
73
84
|
{hint && !isHintInline && (
|
|
74
85
|
<Text style={[selectHintStyles(themeTokens), staticStyles.hintBelow]} nativeID={hintId}>
|
|
75
86
|
{hint}
|
|
76
87
|
</Text>
|
|
77
88
|
)}
|
|
78
|
-
|
|
89
|
+
</>
|
|
79
90
|
)
|
|
80
91
|
}
|
|
81
92
|
)
|
|
@@ -115,21 +126,19 @@ export default InputLabel
|
|
|
115
126
|
|
|
116
127
|
const staticStyles = StyleSheet.create({
|
|
117
128
|
container: {
|
|
118
|
-
|
|
129
|
+
flexShrink: 1,
|
|
119
130
|
flexDirection: 'row',
|
|
120
131
|
alignItems: 'baseline'
|
|
121
132
|
},
|
|
122
|
-
containerWithHintBelow: {
|
|
123
|
-
flexWrap: 'wrap'
|
|
124
|
-
},
|
|
125
133
|
label: {
|
|
126
|
-
flexShrink:
|
|
134
|
+
flexShrink: 1
|
|
127
135
|
},
|
|
128
136
|
hintBelow: {
|
|
129
137
|
flexBasis: '100%',
|
|
130
138
|
flexShrink: 0
|
|
131
139
|
},
|
|
132
140
|
tooltipAlign: {
|
|
133
|
-
alignSelf: '
|
|
141
|
+
alignSelf: 'flex-start',
|
|
142
|
+
justifyContent: 'center'
|
|
134
143
|
}
|
|
135
144
|
})
|
package/src/Link/LinkBase.jsx
CHANGED
|
@@ -45,10 +45,8 @@ const selectOuterBorderStyles = ({
|
|
|
45
45
|
}
|
|
46
46
|
: {}
|
|
47
47
|
|
|
48
|
-
const selectTextStyles = ({ color
|
|
48
|
+
const selectTextStyles = ({ color }) => ({
|
|
49
49
|
color,
|
|
50
|
-
textDecorationLine: textLine,
|
|
51
|
-
textDecorationStyle: textLineStyle,
|
|
52
50
|
...Platform.select({
|
|
53
51
|
web: {
|
|
54
52
|
// TODO: https://github.com/telus/universal-design-system/issues/487
|
|
@@ -65,6 +63,18 @@ const selectBlockStyles = ({ blockFontWeight, blockFontSize, blockLineHeight, bl
|
|
|
65
63
|
fontName: blockFontName
|
|
66
64
|
})
|
|
67
65
|
|
|
66
|
+
const selectDecorationStyles = ({ color, textLine, textLineStyle }) => ({
|
|
67
|
+
color,
|
|
68
|
+
textDecorationLine: textLine,
|
|
69
|
+
textDecorationStyle: textLineStyle,
|
|
70
|
+
...Platform.select({
|
|
71
|
+
web: {
|
|
72
|
+
// TODO: https://github.com/telus/universal-design-system/issues/487
|
|
73
|
+
transition: 'color 200ms'
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
|
|
68
78
|
const selectIconTokens = ({ color, iconSize, iconTranslateX, iconTranslateY }) => ({
|
|
69
79
|
color,
|
|
70
80
|
translateX: iconTranslateX,
|
|
@@ -132,8 +142,14 @@ const LinkBase = forwardRef(
|
|
|
132
142
|
style={(linkState) => {
|
|
133
143
|
const themeTokens = resolveLinkTokens(linkState)
|
|
134
144
|
const outerBorderStyles = selectOuterBorderStyles(themeTokens)
|
|
145
|
+
const decorationStyles = selectDecorationStyles(themeTokens)
|
|
135
146
|
const hasIcon = Boolean(icon || themeTokens.icon)
|
|
136
|
-
return [
|
|
147
|
+
return [
|
|
148
|
+
outerBorderStyles,
|
|
149
|
+
blockLeftStyle,
|
|
150
|
+
decorationStyles,
|
|
151
|
+
hasIcon && staticStyles.rowContainer
|
|
152
|
+
]
|
|
137
153
|
}}
|
|
138
154
|
>
|
|
139
155
|
{(linkState) => {
|
package/src/Link/TextButton.jsx
CHANGED
|
@@ -10,19 +10,7 @@ import LinkBase from './LinkBase'
|
|
|
10
10
|
* take place on the current page, or for navigation within an app.
|
|
11
11
|
*/
|
|
12
12
|
const TextButton = forwardRef(
|
|
13
|
-
(
|
|
14
|
-
{
|
|
15
|
-
onPress,
|
|
16
|
-
children,
|
|
17
|
-
variant,
|
|
18
|
-
tokens,
|
|
19
|
-
// TODO: this may need to use `link` role on Web in the case of being passed both `href` and
|
|
20
|
-
// `onPress` in an omniplatform app that uses React Navigation's useLinkProps for internal nav.
|
|
21
|
-
accessibilityRole = 'button',
|
|
22
|
-
...linkProps
|
|
23
|
-
},
|
|
24
|
-
ref
|
|
25
|
-
) => {
|
|
13
|
+
({ onPress, children, variant, tokens, accessibilityRole = 'button', ...linkProps }, ref) => {
|
|
26
14
|
const getTokens = useThemeTokensCallback('Link', tokens, variant)
|
|
27
15
|
return (
|
|
28
16
|
<LinkBase
|
|
@@ -44,10 +32,4 @@ TextButton.propTypes = {
|
|
|
44
32
|
onPress: PropTypes.func.isRequired
|
|
45
33
|
}
|
|
46
34
|
|
|
47
|
-
// Remove incompatible Link prop (if this build includes propTypes)
|
|
48
|
-
// TODO: test if this works with web navigation in omniplatform React Navigation
|
|
49
|
-
// https://github.com/telus/universal-design-system/issues/665
|
|
50
|
-
// eslint-disable-next-line react/forbid-foreign-prop-types
|
|
51
|
-
if (TextButton.propTypes?.href) delete TextButton.propTypes.href
|
|
52
|
-
|
|
53
35
|
export default TextButton
|