@telus-uds/components-base 1.4.0 → 1.6.1
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 +140 -1
- package/CHANGELOG.md +42 -2
- package/__tests__/FlexGrid/Row.test.jsx +100 -25
- package/__tests__/utils/containUniqueFields.test.js +25 -0
- package/component-docs.json +94 -16
- 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/HorizontalScroll/HorizontalScroll.js +0 -1
- package/lib/HorizontalScroll/HorizontalScrollButton.js +23 -49
- package/lib/InputLabel/InputLabel.js +27 -25
- package/lib/Link/LinkBase.js +19 -6
- package/lib/Link/TextButton.js +1 -10
- 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/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/utils/containUniqueFields.js +34 -0
- package/lib/utils/index.js +10 -1
- package/lib/utils/props/handlerProps.js +72 -0
- package/lib/utils/props/index.js +14 -0
- package/lib/utils/props/inputSupportsProps.js +3 -5
- package/lib/utils/props/linkProps.js +3 -7
- 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/HorizontalScroll/HorizontalScroll.js +0 -1
- package/lib-module/HorizontalScroll/HorizontalScrollButton.js +24 -49
- 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/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/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/utils/containUniqueFields.js +26 -0
- package/lib-module/utils/index.js +2 -1
- package/lib-module/utils/props/handlerProps.js +59 -0
- package/lib-module/utils/props/index.js +1 -0
- package/lib-module/utils/props/inputSupportsProps.js +3 -5
- package/lib-module/utils/props/linkProps.js +3 -7
- 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/HorizontalScroll/HorizontalScroll.jsx +1 -1
- package/src/HorizontalScroll/HorizontalScrollButton.jsx +21 -58
- package/src/InputLabel/InputLabel.jsx +36 -27
- package/src/Link/LinkBase.jsx +20 -4
- package/src/Link/TextButton.jsx +1 -19
- 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/Select/Select.jsx +2 -2
- package/src/Tags/Tags.jsx +23 -9
- package/src/TextInput/TextArea.jsx +5 -1
- package/src/TextInput/TextInput.jsx +13 -3
- package/src/TextInput/TextInputBase.jsx +6 -1
- package/src/TextInput/propTypes.js +7 -1
- package/src/ToggleSwitch/ToggleSwitch.jsx +11 -2
- package/src/ToggleSwitch/ToggleSwitchGroup.jsx +19 -6
- package/src/utils/containUniqueFields.js +32 -0
- package/src/utils/index.js +1 -0
- package/src/utils/props/handlerProps.js +47 -0
- package/src/utils/props/index.js +1 -0
- package/src/utils/props/inputSupportsProps.js +3 -4
- package/src/utils/props/linkProps.js +3 -6
- package/stories/InputLabel/InputLabel.stories.jsx +25 -28
- package/stories/Modal/Modal.stories.jsx +25 -0
- package/stories/Search/Search.stories.jsx +4 -1
- package/stories/TextInput/TextInput.stories.jsx +40 -2
- package/__tests__/Link/LinkBase.test.jsx +0 -22
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
|
-
import
|
|
2
|
+
import Platform from "react-native-web/dist/exports/Platform";
|
|
3
|
+
import { a11yProps, focusHandlerProps, getTokensPropType, inputSupportsProps, selectSystemProps, textInputHandlerProps, variantProp, viewProps } from '../utils';
|
|
3
4
|
import InputSupports from '../InputSupports';
|
|
4
5
|
import TextInputBase from './TextInputBase';
|
|
5
6
|
import textInputPropTypes from './propTypes';
|
|
6
7
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
7
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, inputSupportsProps, viewProps]);
|
|
8
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, inputSupportsProps, textInputHandlerProps, viewProps]);
|
|
8
9
|
/**
|
|
9
10
|
* A basic text input component. Use in forms or individually to receive user's input.
|
|
10
11
|
* Due to React Native's implementation of `TextInput` it's not possible to access the current value by passing a ref.
|
|
@@ -27,10 +28,17 @@ const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, inp
|
|
|
27
28
|
const TextInput = /*#__PURE__*/forwardRef(({
|
|
28
29
|
tokens,
|
|
29
30
|
variant = {},
|
|
31
|
+
pattern,
|
|
30
32
|
...rest
|
|
31
33
|
}, ref) => {
|
|
34
|
+
React.useEffect(() => {
|
|
35
|
+
if (Platform.OS === 'web' && pattern && ref.current) {
|
|
36
|
+
// eslint-disable-next-line no-param-reassign
|
|
37
|
+
ref.current.pattern = pattern;
|
|
38
|
+
}
|
|
39
|
+
}, [ref, pattern]);
|
|
32
40
|
const {
|
|
33
|
-
|
|
41
|
+
supportsProps,
|
|
34
42
|
...selectedProps
|
|
35
43
|
} = selectProps(rest);
|
|
36
44
|
const inputProps = { ...selectedProps,
|
|
@@ -5,10 +5,10 @@ import NativeTextInput from "react-native-web/dist/exports/TextInput";
|
|
|
5
5
|
import View from "react-native-web/dist/exports/View";
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
7
|
import { applyTextStyles, useThemeTokens, applyOuterBorder } from '../ThemeProvider';
|
|
8
|
-
import { a11yProps, getTokensPropType, selectSystemProps, useInputValue, variantProp, viewProps } from '../utils';
|
|
8
|
+
import { a11yProps, getTokensPropType, selectSystemProps, textInputHandlerProps, useInputValue, variantProp, viewProps } from '../utils';
|
|
9
9
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
10
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
11
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, textInputHandlerProps, viewProps]);
|
|
12
12
|
|
|
13
13
|
const selectInputStyles = ({
|
|
14
14
|
backgroundColor,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
|
+
import Platform from "react-native-web/dist/exports/Platform";
|
|
2
3
|
const textInputPropTypes = {
|
|
3
4
|
/**
|
|
4
5
|
* If the input's state is to be controlled by a parent component, use this prop
|
|
@@ -26,6 +27,11 @@ const textInputPropTypes = {
|
|
|
26
27
|
* Use to react upon input's value changes. Required when the `value` prop is set.
|
|
27
28
|
* Will receive the input's value as an argument.
|
|
28
29
|
*/
|
|
29
|
-
onChange: PropTypes.func
|
|
30
|
+
onChange: PropTypes.func,
|
|
31
|
+
...Platform.select({
|
|
32
|
+
web: {
|
|
33
|
+
pattern: PropTypes.string
|
|
34
|
+
}
|
|
35
|
+
})
|
|
30
36
|
};
|
|
31
37
|
export default textInputPropTypes;
|
|
@@ -7,11 +7,11 @@ import InputLabel from '../InputLabel';
|
|
|
7
7
|
import ButtonBase from '../Button/ButtonBase';
|
|
8
8
|
import StackView from '../StackView';
|
|
9
9
|
import { useThemeTokensCallback, applyShadowToken } from '../ThemeProvider';
|
|
10
|
-
import { a11yProps, getTokensPropType, selectTokens, pressProps, selectSystemProps, useUniqueId, variantProp, viewProps } from '../utils';
|
|
10
|
+
import { a11yProps, focusHandlerProps, getTokensPropType, selectTokens, pressProps, selectSystemProps, useUniqueId, variantProp, viewProps } from '../utils';
|
|
11
11
|
import { useInputValue } from '../utils/input';
|
|
12
12
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
13
|
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, pressProps, viewProps]);
|
|
14
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, pressProps, viewProps]);
|
|
15
15
|
|
|
16
16
|
const selectButtonTokens = tokens => selectTokens('Button', { ...tokens,
|
|
17
17
|
// Width tokens are applied to our inner track. Disable Button width token so it wraps our track width.
|
|
@@ -117,7 +117,7 @@ const ToggleSwitch = /*#__PURE__*/forwardRef(({
|
|
|
117
117
|
space: 2,
|
|
118
118
|
direction: "row",
|
|
119
119
|
children: [Boolean(label) && /*#__PURE__*/_jsx(View, {
|
|
120
|
-
style: selectLabelStyles(themeTokens),
|
|
120
|
+
style: [selectLabelStyles(themeTokens), staticStyles.containText],
|
|
121
121
|
children: /*#__PURE__*/_jsx(InputLabel, {
|
|
122
122
|
forId: inputId,
|
|
123
123
|
label: label,
|
|
@@ -219,6 +219,9 @@ const staticStyles = StyleSheet.create({
|
|
|
219
219
|
switch: {
|
|
220
220
|
alignItems: 'center',
|
|
221
221
|
justifyContent: 'center'
|
|
222
|
+
},
|
|
223
|
+
containText: {
|
|
224
|
+
flexShrink: 1
|
|
222
225
|
}
|
|
223
226
|
});
|
|
224
227
|
export default ToggleSwitch;
|
|
@@ -7,10 +7,10 @@ import Fieldset from '../Fieldset';
|
|
|
7
7
|
import { getStackedContent } from '../StackView';
|
|
8
8
|
import { useViewport } from '../ViewportProvider';
|
|
9
9
|
import { useThemeTokens } from '../ThemeProvider';
|
|
10
|
-
import { a11yProps,
|
|
11
|
-
import { useMultipleInputValues } from '../utils/input';
|
|
10
|
+
import { a11yProps, containUniqueFields, focusHandlerProps, getTokensPropType, selectSystemProps, useMultipleInputValues, variantProp, viewProps } from '../utils';
|
|
12
11
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps,
|
|
12
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
13
|
+
const [selectItemProps, selectedItemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, viewProps]);
|
|
14
14
|
const ToggleSwitchGroup = /*#__PURE__*/forwardRef(({
|
|
15
15
|
variant,
|
|
16
16
|
tokens,
|
|
@@ -57,13 +57,20 @@ const ToggleSwitchGroup = /*#__PURE__*/forwardRef(({
|
|
|
57
57
|
...rest
|
|
58
58
|
});
|
|
59
59
|
const itemA11yRole = selectedProps.accessibilityRole === 'radiogroup' ? 'radio' : 'switch';
|
|
60
|
+
const uniqueFields = ['id', 'label'];
|
|
61
|
+
|
|
62
|
+
if (!containUniqueFields(items, uniqueFields)) {
|
|
63
|
+
throw new Error(`ToggleSwitchGroup items must have unique ${uniqueFields.join(', ')}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
60
66
|
const toggleSwitches = items.map(({
|
|
61
67
|
label,
|
|
62
68
|
id = label,
|
|
63
69
|
accessibilityLabel = label,
|
|
64
70
|
onChange: itemOnChange,
|
|
65
71
|
ref: itemRef,
|
|
66
|
-
tooltip: itemTooltip
|
|
72
|
+
tooltip: itemTooltip,
|
|
73
|
+
...itemRest
|
|
67
74
|
}, index) => {
|
|
68
75
|
const isSelected = currentValues.includes(id);
|
|
69
76
|
|
|
@@ -89,7 +96,8 @@ const ToggleSwitchGroup = /*#__PURE__*/forwardRef(({
|
|
|
89
96
|
inactive: inactive,
|
|
90
97
|
label: label,
|
|
91
98
|
tooltip: itemTooltip,
|
|
92
|
-
...itemA11y
|
|
99
|
+
...itemA11y,
|
|
100
|
+
...selectItemProps(itemRest)
|
|
93
101
|
}, id);
|
|
94
102
|
});
|
|
95
103
|
return /*#__PURE__*/_jsx(Fieldset, {
|
|
@@ -123,7 +131,8 @@ ToggleSwitchGroup.propTypes = { ...selectedSystemPropTypes,
|
|
|
123
131
|
/**
|
|
124
132
|
* The options a user may select
|
|
125
133
|
*/
|
|
126
|
-
items: PropTypes.arrayOf(PropTypes.shape({
|
|
134
|
+
items: PropTypes.arrayOf(PropTypes.shape({ ...selectedItemPropTypes,
|
|
135
|
+
|
|
127
136
|
/**
|
|
128
137
|
* The text displayed to the user on the label.
|
|
129
138
|
*/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Returns true if there are no duplicate values of the fields listed
|
|
2
|
+
// in the `fields` array across the objects in the `items` array, false
|
|
3
|
+
// otherwise.
|
|
4
|
+
// Note that if a value of a field in an item is not set, it will be
|
|
5
|
+
// excluded from comparison.
|
|
6
|
+
const containUniqueFields = (items, fields) => {
|
|
7
|
+
const map = [];
|
|
8
|
+
const itemsHaveDuplicateFields = items.some(item => fields.some(field => {
|
|
9
|
+
if (!map[field]) {
|
|
10
|
+
map[field] = [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (!item[field]) {
|
|
14
|
+
// We exclude empty values from comparison
|
|
15
|
+
return false;
|
|
16
|
+
} // Duplicate found!
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
if (map[field][item[field]]) return true;
|
|
20
|
+
map[field][item[field]] = true;
|
|
21
|
+
return false;
|
|
22
|
+
}));
|
|
23
|
+
return !itemsHaveDuplicateFields;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default containUniqueFields;
|
|
@@ -12,4 +12,5 @@ export { default as useResponsiveProp } from './useResponsiveProp';
|
|
|
12
12
|
export * from './useResponsiveProp';
|
|
13
13
|
export { default as useUniqueId } from './useUniqueId';
|
|
14
14
|
export { default as withLinkRouter } from './withLinkRouter';
|
|
15
|
-
export * from './ssr';
|
|
15
|
+
export * from './ssr';
|
|
16
|
+
export { default as containUniqueFields } from './containUniqueFields';
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
export const focusHandlerProps = {
|
|
3
|
+
types: {
|
|
4
|
+
/**
|
|
5
|
+
* onBlur handler
|
|
6
|
+
*/
|
|
7
|
+
onBlur: PropTypes.func,
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* onFocus handler
|
|
11
|
+
*/
|
|
12
|
+
onFocus: PropTypes.func
|
|
13
|
+
},
|
|
14
|
+
select: ({
|
|
15
|
+
onBlur,
|
|
16
|
+
onFocus
|
|
17
|
+
}) => ({
|
|
18
|
+
onBlur,
|
|
19
|
+
onFocus
|
|
20
|
+
})
|
|
21
|
+
};
|
|
22
|
+
export const textInputHandlerProps = {
|
|
23
|
+
types: {
|
|
24
|
+
/**
|
|
25
|
+
* onChange handler
|
|
26
|
+
*/
|
|
27
|
+
onChange: PropTypes.func,
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* onChangeText handler
|
|
31
|
+
*/
|
|
32
|
+
onChangeText: PropTypes.func,
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* onSubmit handler
|
|
36
|
+
*/
|
|
37
|
+
onSubmit: PropTypes.func,
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* onSubmitEditing handler
|
|
41
|
+
*/
|
|
42
|
+
onSubmitEditing: PropTypes.func
|
|
43
|
+
},
|
|
44
|
+
select: ({
|
|
45
|
+
onChange,
|
|
46
|
+
onChangeText,
|
|
47
|
+
onSubmit,
|
|
48
|
+
onSubmitEditing
|
|
49
|
+
}) => ({
|
|
50
|
+
onChange,
|
|
51
|
+
onChangeText,
|
|
52
|
+
onSubmit,
|
|
53
|
+
onSubmitEditing
|
|
54
|
+
})
|
|
55
|
+
};
|
|
56
|
+
export default {
|
|
57
|
+
focusHandlerProps,
|
|
58
|
+
textInputHandlerProps
|
|
59
|
+
};
|
|
@@ -38,17 +38,15 @@ export default {
|
|
|
38
38
|
hintPosition,
|
|
39
39
|
feedback,
|
|
40
40
|
tooltip,
|
|
41
|
-
validation
|
|
42
|
-
...rest
|
|
41
|
+
validation
|
|
43
42
|
}) => ({
|
|
44
|
-
|
|
43
|
+
supportsProps: {
|
|
45
44
|
label,
|
|
46
45
|
hint,
|
|
47
46
|
hintPosition,
|
|
48
47
|
feedback,
|
|
49
48
|
tooltip,
|
|
50
49
|
validation
|
|
51
|
-
}
|
|
52
|
-
...rest
|
|
50
|
+
}
|
|
53
51
|
})
|
|
54
52
|
};
|
|
@@ -22,20 +22,16 @@ export default {
|
|
|
22
22
|
select: getPropSelector(linkPropTypes),
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
* Turn hrefs into press handlers
|
|
25
|
+
* Turn hrefs into press handlers that open links on Native.
|
|
26
26
|
*
|
|
27
27
|
* @param {({ onPress?: () => void, href?: string })}
|
|
28
|
-
* @returns {(() => void)|undefined} Returns a press handler, or undefined on web if
|
|
29
|
-
*
|
|
28
|
+
* @returns {(() => void)|undefined} Returns a press handler, or undefined on web if no press
|
|
29
|
+
* handler is provided (expects calling component to render as `<a href={href}>` on web).
|
|
30
30
|
*/
|
|
31
31
|
handleHref: ({
|
|
32
32
|
onPress,
|
|
33
33
|
href
|
|
34
34
|
}) => {
|
|
35
|
-
if (!href && !onPress) {
|
|
36
|
-
throw new Error('handleHref requires either href or onPress');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
35
|
return Platform.select({
|
|
40
36
|
web: onPress,
|
|
41
37
|
default: (...args) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telus-uds/components-base",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "Base components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"base"
|
|
@@ -22,14 +22,14 @@
|
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
24
|
"test": "jest",
|
|
25
|
-
"lint": "
|
|
26
|
-
"lint:fix": "
|
|
25
|
+
"lint": "yarn --cwd ../.. lint:path --color packages/components-base",
|
|
26
|
+
"lint:fix": "yarn --cwd ../.. lint:path --fix packages/components-base",
|
|
27
27
|
"format": "prettier --write .",
|
|
28
28
|
"build": "yarn build:code && yarn build:docs",
|
|
29
29
|
"build:main": "babel src -d lib",
|
|
30
30
|
"build:module": "babel src -d lib-module --env-name module",
|
|
31
31
|
"build:code": "yarn build:main && yarn build:module",
|
|
32
|
-
"build:docs": "babel-node --plugins
|
|
32
|
+
"build:docs": "babel-node --plugins=@nearform/babel-plugin-react-docgen generate-component-docs.js",
|
|
33
33
|
"storybook": "start-storybook",
|
|
34
34
|
"dev": "yarn build:code --watch",
|
|
35
35
|
"release": "standard-version"
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"airbnb-prop-types": "^2.16.0",
|
|
61
61
|
"@telus-uds/system-constants": "^1.0.2",
|
|
62
|
-
"@telus-uds/system-theme-tokens": "^1.
|
|
62
|
+
"@telus-uds/system-theme-tokens": "^1.5.0",
|
|
63
63
|
"lodash.debounce": "^4.0.8",
|
|
64
64
|
"lodash.merge": "^4.6.2",
|
|
65
65
|
"prop-types": "^15.7.2",
|
|
@@ -6,8 +6,9 @@ import { applyTextStyles, applyShadowToken, applyOuterBorder } from '../ThemePro
|
|
|
6
6
|
import buttonPropTypes from './propTypes'
|
|
7
7
|
import {
|
|
8
8
|
a11yProps,
|
|
9
|
-
getCursorStyle,
|
|
10
9
|
clickProps,
|
|
10
|
+
focusHandlerProps,
|
|
11
|
+
getCursorStyle,
|
|
11
12
|
linkProps,
|
|
12
13
|
resolvePressableState,
|
|
13
14
|
resolvePressableTokens,
|
|
@@ -17,7 +18,12 @@ import {
|
|
|
17
18
|
withLinkRouter
|
|
18
19
|
} from '../utils'
|
|
19
20
|
|
|
20
|
-
const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
21
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([
|
|
22
|
+
a11yProps,
|
|
23
|
+
focusHandlerProps,
|
|
24
|
+
linkProps,
|
|
25
|
+
viewProps
|
|
26
|
+
])
|
|
21
27
|
|
|
22
28
|
const getOuterBorderOffset = ({ outerBorderGap = 0, outerBorderWidth = 0 }) =>
|
|
23
29
|
outerBorderGap + outerBorderWidth
|
|
@@ -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
|
})
|