@telus-uds/components-base 1.7.1 → 1.8.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/.storybook/main.js +7 -0
- package/.turbo/turbo-build.log +3 -3
- package/.turbo/turbo-lint.log +3 -13
- package/CHANGELOG.json +62 -1
- package/CHANGELOG.md +19 -2
- package/__fixtures__/Accessible.js +1 -2
- package/__fixtures__/Accessible.native.js +1 -2
- package/__tests__/FlexGrid/Col.test.jsx +5 -0
- package/__tests__/InputLabel/InputLabel.test.jsx +28 -0
- package/__tests__/InputLabel/__snapshots__/InputLabel.test.jsx.snap +3 -0
- package/__tests__/InputSupports/InputSupports.test.jsx +10 -0
- package/component-docs.json +264 -18
- package/lib/Button/ButtonGroup.js +118 -45
- package/lib/Checkbox/CheckboxGroup.js +3 -3
- package/lib/ExpandCollapse/Panel.js +2 -1
- package/lib/Fieldset/Fieldset.js +7 -0
- package/lib/InputLabel/InputLabel.js +8 -1
- package/lib/InputSupports/InputSupports.js +7 -0
- package/lib/Notification/Notification.js +1 -1
- package/lib/Radio/RadioGroup.js +12 -5
- package/lib/RadioCard/RadioCardGroup.js +7 -0
- package/lib/Search/Search.js +1 -1
- package/lib/Skeleton/Skeleton.js +48 -2
- package/lib/ToggleSwitch/ToggleSwitch.js +7 -0
- package/lib/ToggleSwitch/ToggleSwitchGroup.js +7 -0
- package/lib/Tooltip/Tooltip.js +1 -1
- package/lib/utils/animation/useVerticalExpandAnimation.js +26 -13
- package/lib/utils/props/inputSupportsProps.js +7 -0
- package/lib-module/Button/ButtonGroup.js +117 -45
- package/lib-module/Checkbox/CheckboxGroup.js +3 -3
- package/lib-module/ExpandCollapse/Panel.js +2 -1
- package/lib-module/Fieldset/Fieldset.js +7 -0
- package/lib-module/InputLabel/InputLabel.js +8 -1
- package/lib-module/InputSupports/InputSupports.js +7 -0
- package/lib-module/Notification/Notification.js +1 -1
- package/lib-module/Radio/RadioGroup.js +12 -5
- package/lib-module/RadioCard/RadioCardGroup.js +7 -0
- package/lib-module/Search/Search.js +1 -1
- package/lib-module/Skeleton/Skeleton.js +49 -3
- package/lib-module/ToggleSwitch/ToggleSwitch.js +7 -0
- package/lib-module/ToggleSwitch/ToggleSwitchGroup.js +7 -0
- package/lib-module/Tooltip/Tooltip.js +1 -1
- package/lib-module/utils/animation/useVerticalExpandAnimation.js +26 -14
- package/lib-module/utils/props/inputSupportsProps.js +7 -0
- package/package.json +9 -4
- package/src/Button/ButtonGroup.jsx +106 -41
- package/src/Checkbox/Checkbox.jsx +7 -4
- package/src/Checkbox/CheckboxGroup.jsx +3 -3
- package/src/ExpandCollapse/Panel.jsx +3 -1
- package/src/Fieldset/Fieldset.jsx +6 -0
- package/src/InputLabel/InputLabel.jsx +17 -2
- package/src/InputSupports/InputSupports.jsx +9 -1
- package/src/Notification/Notification.jsx +1 -1
- package/src/Radio/Radio.jsx +5 -1
- package/src/Radio/RadioGroup.jsx +11 -5
- package/src/RadioCard/RadioCard.jsx +5 -1
- package/src/RadioCard/RadioCardGroup.jsx +6 -0
- package/src/Search/Search.jsx +1 -1
- package/src/Skeleton/Skeleton.jsx +56 -3
- package/src/ToggleSwitch/ToggleSwitch.jsx +6 -0
- package/src/ToggleSwitch/ToggleSwitchGroup.jsx +6 -0
- package/src/Tooltip/Tooltip.jsx +1 -1
- package/src/utils/animation/useVerticalExpandAnimation.js +25 -12
- package/src/utils/props/inputSupportsProps.js +6 -1
- package/src/utils/props/tokens.js +21 -19
- package/stories/Tabs/Tabs.stories.jsx +4 -3
|
@@ -213,18 +213,18 @@ CheckboxGroup.propTypes = { ...selectedSystemPropTypes,
|
|
|
213
213
|
onChange: PropTypes.func,
|
|
214
214
|
|
|
215
215
|
/**
|
|
216
|
-
* If true, the
|
|
216
|
+
* If true, the checkboxes cannot be selected by the user and simply show their current state.
|
|
217
217
|
*/
|
|
218
218
|
readOnly: PropTypes.bool,
|
|
219
219
|
|
|
220
220
|
/**
|
|
221
|
-
* If true, the
|
|
221
|
+
* If true, the checkboxes cannot be interacted with, elements are set as `disabled` and if the
|
|
222
222
|
* theme supports `inactive` appearances rules, these are applied.
|
|
223
223
|
*/
|
|
224
224
|
inactive: PropTypes.bool,
|
|
225
225
|
|
|
226
226
|
/**
|
|
227
|
-
* On Web, this is passed to the `name` attribute of the fieldset and each
|
|
227
|
+
* On Web, this is passed to the `name` attribute of the fieldset and each checkbox input.
|
|
228
228
|
*/
|
|
229
229
|
name: PropTypes.string
|
|
230
230
|
};
|
|
@@ -75,7 +75,7 @@ const ExpandCollapsePanel = /*#__PURE__*/forwardRef(({
|
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
const animatedStyles = useVerticalExpandAnimation({
|
|
78
|
+
const [animatedStyles, animatedRef] = useVerticalExpandAnimation({
|
|
79
79
|
containerHeight,
|
|
80
80
|
isExpanded,
|
|
81
81
|
tokens: themeTokens
|
|
@@ -96,6 +96,7 @@ const ExpandCollapsePanel = /*#__PURE__*/forwardRef(({
|
|
|
96
96
|
onPress: handleControlPress,
|
|
97
97
|
children: control
|
|
98
98
|
}), /*#__PURE__*/_jsx(Animated.View, {
|
|
99
|
+
ref: animatedRef,
|
|
99
100
|
style: [overflowContainerStyles, animatedStyles, staticStyles.itemsContainer],
|
|
100
101
|
...focusabilityProps,
|
|
101
102
|
children: /*#__PURE__*/_jsx(View, {
|
|
@@ -17,6 +17,7 @@ import Legend from './Legend';
|
|
|
17
17
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
18
18
|
import { Fragment as _Fragment } from "react/jsx-runtime";
|
|
19
19
|
const Fieldset = /*#__PURE__*/forwardRef(({
|
|
20
|
+
copy = 'en',
|
|
20
21
|
space,
|
|
21
22
|
feedback,
|
|
22
23
|
feedbackPosition = 'top',
|
|
@@ -44,6 +45,7 @@ const Fieldset = /*#__PURE__*/forwardRef(({
|
|
|
44
45
|
|
|
45
46
|
const legendContent = legend && /*#__PURE__*/_jsx(Legend, {
|
|
46
47
|
children: /*#__PURE__*/_jsx(InputLabel, {
|
|
48
|
+
copy: copy,
|
|
47
49
|
label: legend,
|
|
48
50
|
hint: hint,
|
|
49
51
|
hintPosition: hintPosition,
|
|
@@ -83,6 +85,11 @@ Fieldset.displayName = 'Fieldset';
|
|
|
83
85
|
Fieldset.propTypes = {
|
|
84
86
|
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
|
|
85
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Whether the English or French copy will be used (e.g. for accessibility labels).
|
|
90
|
+
*/
|
|
91
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
92
|
+
|
|
86
93
|
/**
|
|
87
94
|
* The accessibility role of the `<fieldset>` element itself. Other React Native accessibility
|
|
88
95
|
* props are not supported because there is not an appropriate counterpart for Fieldsets.
|
|
@@ -35,6 +35,7 @@ const selectGapStyles = ({
|
|
|
35
35
|
});
|
|
36
36
|
|
|
37
37
|
const InputLabel = /*#__PURE__*/forwardRef(({
|
|
38
|
+
copy = 'en',
|
|
38
39
|
label,
|
|
39
40
|
forId,
|
|
40
41
|
hint,
|
|
@@ -68,7 +69,8 @@ const InputLabel = /*#__PURE__*/forwardRef(({
|
|
|
68
69
|
height: themeTokens.fontSize * themeTokens.lineHeight
|
|
69
70
|
}],
|
|
70
71
|
children: /*#__PURE__*/_jsx(Tooltip, {
|
|
71
|
-
content: tooltip
|
|
72
|
+
content: tooltip,
|
|
73
|
+
copy: copy
|
|
72
74
|
})
|
|
73
75
|
})]
|
|
74
76
|
}), hint && !isHintInline && /*#__PURE__*/_jsx(Text, {
|
|
@@ -81,6 +83,11 @@ const InputLabel = /*#__PURE__*/forwardRef(({
|
|
|
81
83
|
InputLabel.displayName = 'InputLabel';
|
|
82
84
|
InputLabel.propTypes = { ...selectedSystemPropTypes,
|
|
83
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Whether the English or French copy will be used (e.g. for accessibility labels).
|
|
88
|
+
*/
|
|
89
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
90
|
+
|
|
84
91
|
/**
|
|
85
92
|
* The input label.
|
|
86
93
|
*/
|
|
@@ -9,6 +9,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
9
9
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
10
10
|
const InputSupports = /*#__PURE__*/forwardRef(({
|
|
11
11
|
children,
|
|
12
|
+
copy = 'en',
|
|
12
13
|
label,
|
|
13
14
|
hint,
|
|
14
15
|
hintPosition = 'inline',
|
|
@@ -34,6 +35,7 @@ const InputSupports = /*#__PURE__*/forwardRef(({
|
|
|
34
35
|
space: space,
|
|
35
36
|
ref: ref,
|
|
36
37
|
children: [label && /*#__PURE__*/_jsx(InputLabel, {
|
|
38
|
+
copy: copy,
|
|
37
39
|
label: label,
|
|
38
40
|
hint: hint,
|
|
39
41
|
hintPosition: hintPosition,
|
|
@@ -54,6 +56,11 @@ InputSupports.displayName = 'InputSupports';
|
|
|
54
56
|
InputSupports.propTypes = {
|
|
55
57
|
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
|
|
56
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Whether the English or French copy will be used (e.g. for accessibility labels).
|
|
61
|
+
*/
|
|
62
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
63
|
+
|
|
57
64
|
/**
|
|
58
65
|
* The input label.
|
|
59
66
|
*/
|
|
@@ -177,7 +177,7 @@ Notification.propTypes = { ...selectedSystemPropTypes,
|
|
|
177
177
|
dismissible: PropTypes.bool,
|
|
178
178
|
|
|
179
179
|
/**
|
|
180
|
-
* Select
|
|
180
|
+
* Select English or French copy for the accessible label of the dismiss button.
|
|
181
181
|
*/
|
|
182
182
|
copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), PropTypes.shape({
|
|
183
183
|
dismiss: PropTypes.string
|
|
@@ -29,7 +29,7 @@ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, f
|
|
|
29
29
|
* ### Uncontrolled version
|
|
30
30
|
*
|
|
31
31
|
* If the RadioGroup manages its own state, you can use `initialCheckedId` prop to provide the initial value.
|
|
32
|
-
* Whenever the radio
|
|
32
|
+
* Whenever the radio gets toggled, it calls the `onChange` callback with the new value (string).
|
|
33
33
|
*
|
|
34
34
|
* ### Use in forms
|
|
35
35
|
*
|
|
@@ -60,6 +60,7 @@ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, f
|
|
|
60
60
|
*/
|
|
61
61
|
|
|
62
62
|
const RadioGroup = /*#__PURE__*/forwardRef(({
|
|
63
|
+
copy = 'en',
|
|
63
64
|
tokens,
|
|
64
65
|
radioTokens,
|
|
65
66
|
variant,
|
|
@@ -128,6 +129,7 @@ const RadioGroup = /*#__PURE__*/forwardRef(({
|
|
|
128
129
|
}, radioId);
|
|
129
130
|
});
|
|
130
131
|
return /*#__PURE__*/_jsx(Fieldset, {
|
|
132
|
+
copy: copy,
|
|
131
133
|
ref: ref,
|
|
132
134
|
name: inputGroupName,
|
|
133
135
|
legend: legend,
|
|
@@ -148,6 +150,11 @@ const RadioGroup = /*#__PURE__*/forwardRef(({
|
|
|
148
150
|
RadioGroup.displayName = 'RadioGroup';
|
|
149
151
|
RadioGroup.propTypes = { ...selectedSystemPropTypes,
|
|
150
152
|
|
|
153
|
+
/**
|
|
154
|
+
* Whether the English or French copy will be used (e.g. for accessibility labels).
|
|
155
|
+
*/
|
|
156
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
157
|
+
|
|
151
158
|
/**
|
|
152
159
|
* Optional theme token overrides for the outer RadioGroup component
|
|
153
160
|
*/
|
|
@@ -199,12 +206,12 @@ RadioGroup.propTypes = { ...selectedSystemPropTypes,
|
|
|
199
206
|
feedback: PropTypes.string,
|
|
200
207
|
|
|
201
208
|
/**
|
|
202
|
-
* If provided, the radio
|
|
209
|
+
* If provided, the radio with this id is selected on first render.
|
|
203
210
|
*/
|
|
204
211
|
initialCheckedId: PropTypes.string,
|
|
205
212
|
|
|
206
213
|
/**
|
|
207
|
-
* If not undefined, the radio
|
|
214
|
+
* If not undefined, the radio with this id is selected (or none is selected if `null`), and the
|
|
208
215
|
* element's selection state will be controlled by its parent using the `onChange` function.
|
|
209
216
|
*/
|
|
210
217
|
checkedId: PropTypes.string,
|
|
@@ -216,12 +223,12 @@ RadioGroup.propTypes = { ...selectedSystemPropTypes,
|
|
|
216
223
|
onChange: PropTypes.func,
|
|
217
224
|
|
|
218
225
|
/**
|
|
219
|
-
* If true, the
|
|
226
|
+
* If true, the radios cannot be selected by the user and simply show their current state.
|
|
220
227
|
*/
|
|
221
228
|
readOnly: PropTypes.bool,
|
|
222
229
|
|
|
223
230
|
/**
|
|
224
|
-
* If true, the
|
|
231
|
+
* If true, the radios cannot be interacted with, elements are set as `disabled` and if the
|
|
225
232
|
* theme supports `inactive` appearances rules, these are applied.
|
|
226
233
|
*/
|
|
227
234
|
inactive: PropTypes.bool,
|
|
@@ -61,6 +61,7 @@ const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, f
|
|
|
61
61
|
*/
|
|
62
62
|
|
|
63
63
|
const RadioCardGroup = /*#__PURE__*/forwardRef(({
|
|
64
|
+
copy = 'en',
|
|
64
65
|
tokens,
|
|
65
66
|
radioCardTokens,
|
|
66
67
|
variant,
|
|
@@ -106,6 +107,7 @@ const RadioCardGroup = /*#__PURE__*/forwardRef(({
|
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
return /*#__PURE__*/_jsx(Fieldset, {
|
|
110
|
+
copy: copy,
|
|
109
111
|
ref: ref,
|
|
110
112
|
name: inputGroupName,
|
|
111
113
|
legend: legend,
|
|
@@ -155,6 +157,11 @@ const RadioCardGroup = /*#__PURE__*/forwardRef(({
|
|
|
155
157
|
RadioCardGroup.displayName = 'RadioCardGroup';
|
|
156
158
|
RadioCardGroup.propTypes = { ...selectedSystemPropTypes,
|
|
157
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Whether the English or French copy will be used (e.g. for accessibility labels).
|
|
162
|
+
*/
|
|
163
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
164
|
+
|
|
158
165
|
/**
|
|
159
166
|
* Optional theme token overrides for the outer RadioCardGroup component
|
|
160
167
|
*/
|
|
@@ -216,7 +216,7 @@ Search.propTypes = { ...selectedContainerPropTypes,
|
|
|
216
216
|
accessibilityLabel: PropTypes.string,
|
|
217
217
|
|
|
218
218
|
/**
|
|
219
|
-
* Select
|
|
219
|
+
* Select English or French copy for the accessible labels.
|
|
220
220
|
* You may also pass in a custom dictionary object.
|
|
221
221
|
*/
|
|
222
222
|
copy: PropTypes.oneOfType([PropTypes.oneOf(['en', 'fr']), PropTypes.shape({
|
|
@@ -4,7 +4,7 @@ import Platform from "react-native-web/dist/exports/Platform";
|
|
|
4
4
|
import propTypes from 'prop-types';
|
|
5
5
|
import StackView from '../StackView';
|
|
6
6
|
import { useThemeTokens } from '../ThemeProvider';
|
|
7
|
-
import { a11yProps, getTokensPropType, selectSystemProps, useSpacingScale, variantProp, viewProps } from '../utils';
|
|
7
|
+
import { a11yProps, getTokensPropType, selectSystemProps, responsiveProps, useResponsiveProp, useSpacingScale, spacingProps, variantProp, viewProps } from '../utils';
|
|
8
8
|
import useSkeletonNativeAnimation from './useSkeletonNativeAnimation';
|
|
9
9
|
import skeletonWebAnimation from './skeletonWebAnimation';
|
|
10
10
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -45,13 +45,23 @@ const Skeleton = /*#__PURE__*/forwardRef(({
|
|
|
45
45
|
tokens,
|
|
46
46
|
variant,
|
|
47
47
|
size,
|
|
48
|
+
sizeIndex = size,
|
|
49
|
+
sizePixels,
|
|
48
50
|
characters,
|
|
49
51
|
lines,
|
|
50
52
|
shape = 'line',
|
|
51
53
|
...rest
|
|
52
54
|
}, ref) => {
|
|
53
55
|
const themeTokens = useThemeTokens('Skeleton', tokens, variant);
|
|
54
|
-
const
|
|
56
|
+
const pixels = useResponsiveProp(sizePixels);
|
|
57
|
+
const spacingScaleValue = typeof pixels === 'number' ? // Size by an exact number of pixels
|
|
58
|
+
{
|
|
59
|
+
options: {
|
|
60
|
+
size: pixels
|
|
61
|
+
}
|
|
62
|
+
} : // Size by an index on the spacing scale (getting default index from theme if none provided)
|
|
63
|
+
sizeIndex || themeTokens.size;
|
|
64
|
+
const skeletonHeight = useSpacingScale(spacingScaleValue);
|
|
55
65
|
const nativeAnimation = useSkeletonNativeAnimation();
|
|
56
66
|
|
|
57
67
|
const getAnimationBaseOnPlatform = () => {
|
|
@@ -109,9 +119,45 @@ Skeleton.displayName = 'Skeleton';
|
|
|
109
119
|
Skeleton.propTypes = { ...selectedSystemPropTypes,
|
|
110
120
|
tokens: getTokensPropType('Skeleton'),
|
|
111
121
|
variant: variantProp.propType,
|
|
112
|
-
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Sets the size of Skeleton lines or shape according to the theme's spacing scale. For example, size={1} gives the smallest non-zero theme-defined spacing size.
|
|
125
|
+
*
|
|
126
|
+
* May also accept an object with responsive viewport keys or spacing scale options - see `useSpacingScale` for details.
|
|
127
|
+
*/
|
|
128
|
+
sizeIndex: spacingProps.types.spacingValue,
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @deprecated alias for `sizeIndex`
|
|
132
|
+
*/
|
|
133
|
+
size: spacingProps.types.spacingValue,
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Sets the size of Skeleton lines or shape to an exact number of pixels. Use when it's necessary to exactly match sizes of images or other boxes.
|
|
137
|
+
*
|
|
138
|
+
* Accepts a number or an object with responsive viewport keys, e.g. { xs: 32, lg: 64 } would be 32px at xs, sm and md and 64 at lg and xl viewports.
|
|
139
|
+
*/
|
|
140
|
+
sizePixels: responsiveProps.getTypeOptionallyByViewport(propTypes.number),
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Determines the width of simulated lines of text if the Skeleton's shape is 'line' (the default shape).
|
|
144
|
+
*
|
|
145
|
+
* Only has any affect if shape is line (the default). If unset, takes a default value from the theme.
|
|
146
|
+
*/
|
|
113
147
|
characters: propTypes.number,
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Determines how many Skeleton items are rendered (default 1).
|
|
151
|
+
*
|
|
152
|
+
* Recommended usage is to simulate paragraphs of text when Skeleton's shape is 'line' (the default shape).
|
|
153
|
+
*
|
|
154
|
+
* The amount of spacing between multiple lines is controlled by theme tokens.
|
|
155
|
+
*/
|
|
114
156
|
lines: propTypes.number,
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Determines if the skeleton should resemble lines of text (default), a circle, or a square box with themed rounded corners.
|
|
160
|
+
*/
|
|
115
161
|
shape: propTypes.oneOf(['line', 'circle', 'box'])
|
|
116
162
|
};
|
|
117
163
|
export default Skeleton;
|
|
@@ -83,6 +83,7 @@ const selectLabelTokens = ({
|
|
|
83
83
|
});
|
|
84
84
|
|
|
85
85
|
const ToggleSwitch = /*#__PURE__*/forwardRef(({
|
|
86
|
+
copy = 'en',
|
|
86
87
|
value,
|
|
87
88
|
initialValue,
|
|
88
89
|
onChange,
|
|
@@ -119,6 +120,7 @@ const ToggleSwitch = /*#__PURE__*/forwardRef(({
|
|
|
119
120
|
children: [Boolean(label) && /*#__PURE__*/_jsx(View, {
|
|
120
121
|
style: [selectLabelStyles(themeTokens), staticStyles.containText],
|
|
121
122
|
children: /*#__PURE__*/_jsx(InputLabel, {
|
|
123
|
+
copy: copy,
|
|
122
124
|
forId: inputId,
|
|
123
125
|
label: label,
|
|
124
126
|
tokens: selectLabelTokens(themeTokens),
|
|
@@ -167,6 +169,11 @@ const ToggleSwitch = /*#__PURE__*/forwardRef(({
|
|
|
167
169
|
});
|
|
168
170
|
ToggleSwitch.displayName = 'ToggleSwitch';
|
|
169
171
|
ToggleSwitch.propTypes = { ...selectedSystemPropTypes,
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Whether the English or French copy will be used (e.g. for accessibility labels).
|
|
175
|
+
*/
|
|
176
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
170
177
|
tokens: getTokensPropType('ToggleSwitch'),
|
|
171
178
|
variant: variantProp.propType,
|
|
172
179
|
|
|
@@ -12,6 +12,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
12
12
|
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
13
13
|
const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, viewProps]);
|
|
14
14
|
const ToggleSwitchGroup = /*#__PURE__*/forwardRef(({
|
|
15
|
+
copy = 'en',
|
|
15
16
|
variant,
|
|
16
17
|
tokens,
|
|
17
18
|
items = [],
|
|
@@ -88,6 +89,7 @@ const ToggleSwitchGroup = /*#__PURE__*/forwardRef(({
|
|
|
88
89
|
...a11yProps.getPositionInSet(items.length, index)
|
|
89
90
|
};
|
|
90
91
|
return /*#__PURE__*/_jsx(ToggleSwitch, {
|
|
92
|
+
copy: copy,
|
|
91
93
|
id: id,
|
|
92
94
|
ref: itemRef,
|
|
93
95
|
onChange: handleChange,
|
|
@@ -119,6 +121,11 @@ const ToggleSwitchGroup = /*#__PURE__*/forwardRef(({
|
|
|
119
121
|
});
|
|
120
122
|
ToggleSwitchGroup.displayName = 'ToggleSwitchGroup';
|
|
121
123
|
ToggleSwitchGroup.propTypes = { ...selectedSystemPropTypes,
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Whether the English or French copy will be used (e.g. for accessibility labels).
|
|
127
|
+
*/
|
|
128
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
122
129
|
tokens: getTokensPropType('ToggleSwitchGroup'),
|
|
123
130
|
variant: variantProp.propType,
|
|
124
131
|
|
|
@@ -301,7 +301,7 @@ Tooltip.propTypes = { ...selectedSystemPropTypes,
|
|
|
301
301
|
content: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
|
|
302
302
|
|
|
303
303
|
/**
|
|
304
|
-
* Select
|
|
304
|
+
* Select English or French copy for the accessible label.
|
|
305
305
|
*/
|
|
306
306
|
copy: PropTypes.oneOf(['en', 'fr']),
|
|
307
307
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect, useRef } from 'react';
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
2
|
import Animated from "react-native-web/dist/exports/Animated";
|
|
3
3
|
import Easing from "react-native-web/dist/exports/Easing";
|
|
4
4
|
import Platform from "react-native-web/dist/exports/Platform"; // TODO: systematise animations
|
|
@@ -9,14 +9,25 @@ function useVerticalExpandAnimation({
|
|
|
9
9
|
isExpanded,
|
|
10
10
|
tokens
|
|
11
11
|
}) {
|
|
12
|
+
const [isAnimating, setIsAnimating] = useState(false);
|
|
12
13
|
const expandAnimatedValue = useRef(new Animated.Value(0)).current;
|
|
14
|
+
const elementRef = useRef(null);
|
|
13
15
|
const {
|
|
14
16
|
expandDuration,
|
|
15
17
|
collapseDuration
|
|
16
|
-
} = tokens;
|
|
18
|
+
} = tokens; // Treat as animating from when expanded state changes, until animation completes
|
|
19
|
+
|
|
20
|
+
useEffect(() => setIsAnimating(true), [isExpanded]);
|
|
17
21
|
useEffect(() => {
|
|
22
|
+
const onComplete = () => !isExpanded && setIsAnimating(false);
|
|
23
|
+
|
|
18
24
|
if (Platform.OS === 'web') {
|
|
19
|
-
return;
|
|
25
|
+
if (!elementRef.current) return () => {}; // React Native Web does not pass `onTransitionEnd` through, must attach manually.
|
|
26
|
+
// https://github.com/necolas/react-native-web/pull/1713
|
|
27
|
+
|
|
28
|
+
const element = elementRef.current;
|
|
29
|
+
element.addEventListener('transitionend', onComplete);
|
|
30
|
+
return () => element.removeEventListener('transitionend', onComplete);
|
|
20
31
|
}
|
|
21
32
|
|
|
22
33
|
const animationConfig = {
|
|
@@ -25,25 +36,26 @@ function useVerticalExpandAnimation({
|
|
|
25
36
|
toValue: isExpanded ? containerHeight : 0,
|
|
26
37
|
useNativeDriver: false
|
|
27
38
|
};
|
|
28
|
-
Animated.timing(expandAnimatedValue, animationConfig)
|
|
29
|
-
|
|
30
|
-
|
|
39
|
+
const animation = Animated.timing(expandAnimatedValue, animationConfig);
|
|
40
|
+
animation.start(onComplete);
|
|
41
|
+
return () => animation.stop();
|
|
42
|
+
}, [isExpanded, expandAnimatedValue, containerHeight, expandDuration, collapseDuration]); // Without `visibility: 'hidden', descendents are focusable on web even when collapsed
|
|
43
|
+
|
|
44
|
+
const containerStyles = !isExpanded && !isAnimating ? {
|
|
45
|
+
visibility: 'hidden'
|
|
46
|
+
} : {}; // don't visually collapse the container until we have it measured
|
|
31
47
|
|
|
32
48
|
if (containerHeight !== null) {
|
|
33
49
|
if (Platform.OS === 'web') {
|
|
34
50
|
const transitionDuration = isExpanded ? expandDuration : collapseDuration;
|
|
35
|
-
containerStyles = {
|
|
36
|
-
|
|
37
|
-
height: isExpanded ? containerHeight : 0
|
|
38
|
-
};
|
|
51
|
+
containerStyles.transition = `height ${transitionDuration}ms ease-in-out`;
|
|
52
|
+
containerStyles.height = isExpanded ? containerHeight : 0;
|
|
39
53
|
} else {
|
|
40
|
-
containerStyles =
|
|
41
|
-
height: expandAnimatedValue
|
|
42
|
-
};
|
|
54
|
+
containerStyles.height = expandAnimatedValue;
|
|
43
55
|
}
|
|
44
56
|
}
|
|
45
57
|
|
|
46
|
-
return containerStyles;
|
|
58
|
+
return [containerStyles, elementRef];
|
|
47
59
|
}
|
|
48
60
|
|
|
49
61
|
export default useVerticalExpandAnimation;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
export default {
|
|
3
3
|
types: {
|
|
4
|
+
/**
|
|
5
|
+
* Whether the English or French copy will be used (e.g. for accessibility labels).
|
|
6
|
+
*/
|
|
7
|
+
copy: PropTypes.oneOf(['en', 'fr']),
|
|
8
|
+
|
|
4
9
|
/**
|
|
5
10
|
* The input label.
|
|
6
11
|
*/
|
|
@@ -33,6 +38,7 @@ export default {
|
|
|
33
38
|
validation: PropTypes.oneOf(['error', 'success'])
|
|
34
39
|
},
|
|
35
40
|
select: ({
|
|
41
|
+
copy,
|
|
36
42
|
label,
|
|
37
43
|
hint,
|
|
38
44
|
hintPosition,
|
|
@@ -41,6 +47,7 @@ export default {
|
|
|
41
47
|
validation
|
|
42
48
|
}) => ({
|
|
43
49
|
supportsProps: {
|
|
50
|
+
copy,
|
|
44
51
|
label,
|
|
45
52
|
hint,
|
|
46
53
|
hintPosition,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telus-uds/components-base",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Base components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"base"
|
|
@@ -31,8 +31,7 @@
|
|
|
31
31
|
"build:code": "yarn build:main && yarn build:module",
|
|
32
32
|
"build:docs": "babel-node --plugins=@nearform/babel-plugin-react-docgen generate-component-docs.js",
|
|
33
33
|
"storybook": "start-storybook",
|
|
34
|
-
"dev": "yarn build:code --watch"
|
|
35
|
-
"release": "standard-version"
|
|
34
|
+
"dev": "yarn build:code --watch"
|
|
36
35
|
},
|
|
37
36
|
"bugs": {
|
|
38
37
|
"url": "https://github.com/telus/universal-design-system/issues"
|
|
@@ -50,6 +49,12 @@
|
|
|
50
49
|
"react-native-web": "^0.17.0"
|
|
51
50
|
},
|
|
52
51
|
"devDependencies": {
|
|
52
|
+
"@storybook/addon-a11y": "^6.5.6",
|
|
53
|
+
"@storybook/addon-essentials": "^6.5.6",
|
|
54
|
+
"@storybook/cli": "^6.5.6",
|
|
55
|
+
"@storybook/react": "^6.5.6",
|
|
56
|
+
"@storybook/builder-webpack5": "^6.5.6",
|
|
57
|
+
"@storybook/manager-webpack5": "^6.5.6",
|
|
53
58
|
"@telus-uds/browserslist-config": "^1.0.1",
|
|
54
59
|
"@testing-library/jest-native": "^4.0.1",
|
|
55
60
|
"@testing-library/react-hooks": "^7.0.1",
|
|
@@ -59,7 +64,7 @@
|
|
|
59
64
|
"dependencies": {
|
|
60
65
|
"airbnb-prop-types": "^2.16.0",
|
|
61
66
|
"@telus-uds/system-constants": "^1.0.2",
|
|
62
|
-
"@telus-uds/system-theme-tokens": "^
|
|
67
|
+
"@telus-uds/system-theme-tokens": "^2.0.0",
|
|
63
68
|
"lodash.debounce": "^4.0.8",
|
|
64
69
|
"lodash.merge": "^4.6.2",
|
|
65
70
|
"prop-types": "^15.7.2",
|