@telus-uds/components-base 1.63.0 → 1.65.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 +20 -2
- package/lib/Checkbox/CheckboxButton.js +200 -0
- package/lib/CheckboxCard/CheckboxCard.js +225 -0
- package/lib/CheckboxCard/index.js +13 -0
- package/lib/StackView/StackView.js +4 -1
- package/lib/Tabs/Tabs.js +15 -0
- package/lib/index.js +9 -0
- package/lib-module/Checkbox/CheckboxButton.js +174 -0
- package/lib-module/CheckboxCard/CheckboxCard.js +200 -0
- package/lib-module/CheckboxCard/index.js +2 -0
- package/lib-module/StackView/StackView.js +4 -1
- package/lib-module/Tabs/Tabs.js +14 -0
- package/lib-module/index.js +1 -0
- package/package.json +2 -2
- package/src/Checkbox/CheckboxButton.jsx +180 -0
- package/src/CheckboxCard/CheckboxCard.jsx +190 -0
- package/src/CheckboxCard/index.js +3 -0
- package/src/StackView/StackView.jsx +2 -1
- package/src/Tabs/Tabs.jsx +14 -1
- package/src/index.js +1 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import Platform from "react-native-web/dist/exports/Platform";
|
|
4
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
5
|
+
import View from "react-native-web/dist/exports/View";
|
|
6
|
+
import CheckboxInput from './CheckboxInput';
|
|
7
|
+
import { applyShadowToken, useThemeTokens } from '../ThemeProvider';
|
|
8
|
+
import { a11yProps, getTokensSetPropType, selectSystemProps, selectTokens, viewProps } from '../utils';
|
|
9
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
10
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
11
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps]);
|
|
12
|
+
|
|
13
|
+
const selectInputStyles = (_ref, isChecked) => {
|
|
14
|
+
let {
|
|
15
|
+
iconBackgroundColor,
|
|
16
|
+
inputBorderColor,
|
|
17
|
+
inputBorderRadius,
|
|
18
|
+
inputBorderWidth,
|
|
19
|
+
inputBackgroundColor,
|
|
20
|
+
inputHeight,
|
|
21
|
+
inputOutlineColor,
|
|
22
|
+
inputOutlineWidth,
|
|
23
|
+
inputOutlineOffset,
|
|
24
|
+
inputShadow,
|
|
25
|
+
inputWidth
|
|
26
|
+
} = _ref;
|
|
27
|
+
return {
|
|
28
|
+
borderColor: inputBorderColor,
|
|
29
|
+
borderWidth: inputBorderWidth,
|
|
30
|
+
borderRadius: inputBorderRadius,
|
|
31
|
+
backgroundColor: isChecked ? iconBackgroundColor : inputBackgroundColor,
|
|
32
|
+
height: inputHeight,
|
|
33
|
+
width: inputWidth,
|
|
34
|
+
...applyShadowToken(inputShadow),
|
|
35
|
+
...Platform.select({
|
|
36
|
+
web: {
|
|
37
|
+
outlineStyle: 'solid',
|
|
38
|
+
outlineColor: inputOutlineColor,
|
|
39
|
+
outlineWidth: inputOutlineWidth,
|
|
40
|
+
outlineOffset: inputOutlineOffset
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const selectIconTokens = _ref2 => {
|
|
47
|
+
let {
|
|
48
|
+
icon,
|
|
49
|
+
iconColor,
|
|
50
|
+
iconSize
|
|
51
|
+
} = _ref2;
|
|
52
|
+
return {
|
|
53
|
+
icon,
|
|
54
|
+
color: iconColor,
|
|
55
|
+
size: iconSize
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const tokenKeys = ['checkedBackgroundColor', 'checkedSize', 'inputBackgroundColor', 'inputBorderColor', 'inputBorderWidth', 'inputOutlineColor', 'inputOutlineWidth', 'inputSize', 'outerBorderColor', 'outerBorderWidth', 'outerBorderGap', 'inputSize'];
|
|
60
|
+
export const selectCheckboxTokens = (themeTokens, prefix) => selectTokens(tokenKeys, themeTokens, prefix);
|
|
61
|
+
/**
|
|
62
|
+
* The visual toggle of a checkbox input. Is not interactive on its own, should be used inside
|
|
63
|
+
* an interactive parent that passes down props when interacted with. Used in CheckboxCard
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
const CheckboxButton = /*#__PURE__*/forwardRef((_ref3, ref) => {
|
|
67
|
+
let {
|
|
68
|
+
isChecked,
|
|
69
|
+
tokens,
|
|
70
|
+
inactive,
|
|
71
|
+
defaultChecked,
|
|
72
|
+
inputId,
|
|
73
|
+
iconId,
|
|
74
|
+
isControlled,
|
|
75
|
+
handleChange,
|
|
76
|
+
name: inputName,
|
|
77
|
+
value,
|
|
78
|
+
...rest
|
|
79
|
+
} = _ref3;
|
|
80
|
+
const {
|
|
81
|
+
icon: IconComponent,
|
|
82
|
+
...stateTokens
|
|
83
|
+
} = useThemeTokens('Checkbox', {}, {
|
|
84
|
+
checked: isChecked
|
|
85
|
+
});
|
|
86
|
+
const iconTokens = selectIconTokens(stateTokens);
|
|
87
|
+
return /*#__PURE__*/_jsx(View, { ...selectProps(rest),
|
|
88
|
+
children: /*#__PURE__*/_jsxs(View, {
|
|
89
|
+
style: [staticStyles.defaultInputStyles, selectInputStyles(stateTokens, isChecked)],
|
|
90
|
+
testID: inputId,
|
|
91
|
+
children: [/*#__PURE__*/_jsx(CheckboxInput, {
|
|
92
|
+
ref: ref,
|
|
93
|
+
checked: isChecked,
|
|
94
|
+
defaultChecked: defaultChecked,
|
|
95
|
+
disabled: inactive,
|
|
96
|
+
id: inputId,
|
|
97
|
+
isControlled: isControlled,
|
|
98
|
+
onChange: handleChange,
|
|
99
|
+
name: inputName,
|
|
100
|
+
value: value
|
|
101
|
+
}), isChecked && IconComponent && /*#__PURE__*/_jsx(View, {
|
|
102
|
+
testID: iconId,
|
|
103
|
+
children: /*#__PURE__*/_jsx(IconComponent, { ...iconTokens
|
|
104
|
+
})
|
|
105
|
+
})]
|
|
106
|
+
})
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
CheckboxButton.displayName = 'CheckboxButton';
|
|
110
|
+
CheckboxButton.propTypes = { ...selectedSystemPropTypes,
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Use `checked` for controlled Checkbox. For uncontrolled Checkbox, use the `defaultChecked` prop.
|
|
114
|
+
*/
|
|
115
|
+
isChecked: PropTypes.bool,
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Checkbox tokens.
|
|
119
|
+
*/
|
|
120
|
+
tokens: getTokensSetPropType(tokenKeys, {
|
|
121
|
+
allowFunction: true
|
|
122
|
+
}),
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Whether the corresponding input is disabled or active.
|
|
126
|
+
*/
|
|
127
|
+
inactive: PropTypes.bool,
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Use `defaultChecked` to provide the initial value for an uncontrolled Checkbox.
|
|
131
|
+
*/
|
|
132
|
+
defaultChecked: PropTypes.bool,
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Checkbox input ID.
|
|
136
|
+
*/
|
|
137
|
+
inputId: PropTypes.string,
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Checkbox icon ID.
|
|
141
|
+
*/
|
|
142
|
+
iconId: PropTypes.string,
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Can control the checkbox on the card.
|
|
146
|
+
*/
|
|
147
|
+
isControlled: PropTypes.bool,
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Callback called when a controlled checkbox gets interacted with.
|
|
151
|
+
*/
|
|
152
|
+
handleChange: PropTypes.func,
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Associate this checkbox with a group (set as the name attribute).
|
|
156
|
+
*/
|
|
157
|
+
name: PropTypes.string,
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* The value of the checkbox: true or false
|
|
161
|
+
*/
|
|
162
|
+
value: PropTypes.bool
|
|
163
|
+
};
|
|
164
|
+
export default CheckboxButton;
|
|
165
|
+
const staticStyles = StyleSheet.create({
|
|
166
|
+
container: {
|
|
167
|
+
flexDirection: 'row',
|
|
168
|
+
alignItems: 'center'
|
|
169
|
+
},
|
|
170
|
+
defaultInputStyles: {
|
|
171
|
+
alignItems: 'center',
|
|
172
|
+
justifyContent: 'center'
|
|
173
|
+
}
|
|
174
|
+
});
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import StyleSheet from "react-native-web/dist/exports/StyleSheet";
|
|
4
|
+
import Text from "react-native-web/dist/exports/Text";
|
|
5
|
+
import View from "react-native-web/dist/exports/View";
|
|
6
|
+
import { applyTextStyles, useTheme, useThemeTokensCallback } from '../ThemeProvider';
|
|
7
|
+
import { a11yProps, focusHandlerProps, getTokensPropType, selectSystemProps, selectTokens, useInputValue, useUniqueId, variantProp, viewProps } from '../utils';
|
|
8
|
+
import { PressableCardBase, selectPressableCardTokens } from '../Card';
|
|
9
|
+
import StackView from '../StackView';
|
|
10
|
+
import CheckboxButton, { selectCheckboxTokens } from '../Checkbox/CheckboxButton';
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, focusHandlerProps, viewProps]);
|
|
14
|
+
const CheckboxCard = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
15
|
+
let {
|
|
16
|
+
tokens,
|
|
17
|
+
variant,
|
|
18
|
+
title,
|
|
19
|
+
children,
|
|
20
|
+
inactive,
|
|
21
|
+
defaultChecked,
|
|
22
|
+
checked,
|
|
23
|
+
name: inputName,
|
|
24
|
+
value,
|
|
25
|
+
id,
|
|
26
|
+
iconId,
|
|
27
|
+
onChange,
|
|
28
|
+
...rest
|
|
29
|
+
} = _ref;
|
|
30
|
+
const {
|
|
31
|
+
currentValue: isChecked,
|
|
32
|
+
setValue: setIsChecked,
|
|
33
|
+
isControlled
|
|
34
|
+
} = useInputValue({
|
|
35
|
+
value: checked,
|
|
36
|
+
initialValue: defaultChecked,
|
|
37
|
+
onChange
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const handleChange = event => {
|
|
41
|
+
if (!inactive) {
|
|
42
|
+
setIsChecked(!isChecked, event);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const uniqueId = useUniqueId('CheckboxCard');
|
|
47
|
+
const inputId = id ?? uniqueId;
|
|
48
|
+
const uniqueIconId = useUniqueId('CheckboxIcon');
|
|
49
|
+
const iconCheckboxId = iconId ?? uniqueIconId;
|
|
50
|
+
const getTokens = useThemeTokensCallback('CheckboxCard', tokens, variant);
|
|
51
|
+
|
|
52
|
+
const getCardTokens = cardState => selectPressableCardTokens(getTokens(cardState));
|
|
53
|
+
|
|
54
|
+
const {
|
|
55
|
+
themeOptions
|
|
56
|
+
} = useTheme();
|
|
57
|
+
const selectedProps = selectProps({
|
|
58
|
+
accessibilityRole: 'checkbox',
|
|
59
|
+
accessibilityState: {
|
|
60
|
+
checked: isChecked,
|
|
61
|
+
disabled: inactive
|
|
62
|
+
},
|
|
63
|
+
...rest
|
|
64
|
+
});
|
|
65
|
+
return /*#__PURE__*/_jsx(PressableCardBase, {
|
|
66
|
+
ref: ref,
|
|
67
|
+
inactive: inactive,
|
|
68
|
+
checked: isChecked,
|
|
69
|
+
tokens: getCardTokens,
|
|
70
|
+
onPress: handleChange,
|
|
71
|
+
...selectedProps,
|
|
72
|
+
children: cardState => {
|
|
73
|
+
const {
|
|
74
|
+
checkboxSpace,
|
|
75
|
+
contentSpace,
|
|
76
|
+
...themeTokens
|
|
77
|
+
} = getTokens(cardState);
|
|
78
|
+
const checkboxTokens = selectCheckboxTokens(themeTokens, 'checkbox');
|
|
79
|
+
const titleTokens = selectTokens('Typography', themeTokens);
|
|
80
|
+
const textStyle = applyTextStyles({ ...titleTokens,
|
|
81
|
+
themeOptions
|
|
82
|
+
});
|
|
83
|
+
return /*#__PURE__*/_jsxs(StackView, {
|
|
84
|
+
direction: "row",
|
|
85
|
+
space: checkboxSpace,
|
|
86
|
+
children: [/*#__PURE__*/_jsx(View, {
|
|
87
|
+
style: [staticStyles.alignWithText, {
|
|
88
|
+
height: textStyle.lineHeight
|
|
89
|
+
}],
|
|
90
|
+
children: /*#__PURE__*/_jsx(CheckboxButton, {
|
|
91
|
+
tokens: checkboxTokens,
|
|
92
|
+
isControlled: isControlled,
|
|
93
|
+
isChecked: isChecked,
|
|
94
|
+
inactive: inactive,
|
|
95
|
+
defaultChecked: defaultChecked,
|
|
96
|
+
inputId: inputId,
|
|
97
|
+
iconId: iconCheckboxId,
|
|
98
|
+
handleChange: handleChange,
|
|
99
|
+
name: inputName,
|
|
100
|
+
value: value
|
|
101
|
+
})
|
|
102
|
+
}), /*#__PURE__*/_jsxs(StackView, {
|
|
103
|
+
direction: "column",
|
|
104
|
+
space: contentSpace,
|
|
105
|
+
tokens: {
|
|
106
|
+
flexShrink: 1
|
|
107
|
+
},
|
|
108
|
+
children: [title ? /*#__PURE__*/_jsx(Text, {
|
|
109
|
+
style: textStyle,
|
|
110
|
+
children: title
|
|
111
|
+
}) : null, typeof children === 'function' ? children(cardState, textStyle) : children]
|
|
112
|
+
})]
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
CheckboxCard.displayName = 'CheckboxCard';
|
|
118
|
+
CheckboxCard.propTypes = { ...selectedSystemPropTypes,
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Content to be displayed at the top of the card alongside the checkbox
|
|
122
|
+
*/
|
|
123
|
+
title: PropTypes.string,
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Additional content to be displayed below the checkbox.
|
|
127
|
+
*/
|
|
128
|
+
children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]),
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Use `checked` for controlled checkbox. For uncontrolled checkbox, use the `defaultChecked` prop.
|
|
132
|
+
*/
|
|
133
|
+
checked: PropTypes.bool,
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Use `defaultChecked` to provide the initial value for an uncontrolled checkbox.
|
|
137
|
+
*/
|
|
138
|
+
defaultChecked: PropTypes.bool,
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* An optional checkboxdescription.
|
|
142
|
+
*/
|
|
143
|
+
description: PropTypes.string,
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Checkbox card ID.
|
|
147
|
+
*/
|
|
148
|
+
id: PropTypes.string,
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Checkbox icon ID.
|
|
152
|
+
*/
|
|
153
|
+
iconId: PropTypes.string,
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Whether the corresponding input is disabled or active.
|
|
157
|
+
*/
|
|
158
|
+
inactive: PropTypes.bool,
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* The label.
|
|
162
|
+
*/
|
|
163
|
+
label: PropTypes.string,
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Associate this checkbox card with a group (set as the name attribute).
|
|
167
|
+
*/
|
|
168
|
+
name: PropTypes.string,
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Whether the underlying input triggered a validation error or not.
|
|
172
|
+
*/
|
|
173
|
+
error: PropTypes.bool,
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* The value. Must be unique within the group.
|
|
177
|
+
*/
|
|
178
|
+
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.bool]),
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Callback called when a controlled checkbox card gets interacted with.
|
|
182
|
+
*/
|
|
183
|
+
onChange: PropTypes.func,
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* checkbox card tokens.
|
|
187
|
+
*/
|
|
188
|
+
tokens: getTokensPropType('CheckboxCard'),
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* checkbox variant.
|
|
192
|
+
*/
|
|
193
|
+
variant: variantProp.propType
|
|
194
|
+
};
|
|
195
|
+
export default CheckboxCard;
|
|
196
|
+
const staticStyles = StyleSheet.create({
|
|
197
|
+
alignWithText: {
|
|
198
|
+
justifyContent: 'center'
|
|
199
|
+
}
|
|
200
|
+
});
|
|
@@ -80,10 +80,13 @@ const StackView = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
80
80
|
viewport
|
|
81
81
|
});
|
|
82
82
|
const flexStyles = selectFlexStyles(themeTokens);
|
|
83
|
+
const size = {
|
|
84
|
+
width: themeTokens.width
|
|
85
|
+
};
|
|
83
86
|
return /*#__PURE__*/_jsx(View, {
|
|
84
87
|
ref: ref,
|
|
85
88
|
...selectedProps,
|
|
86
|
-
style: [flexStyles, staticStyles[direction]],
|
|
89
|
+
style: [flexStyles, staticStyles[direction], size],
|
|
87
90
|
children: content
|
|
88
91
|
});
|
|
89
92
|
});
|
package/lib-module/Tabs/Tabs.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { forwardRef, useCallback } from 'react';
|
|
2
|
+
import Platform from "react-native-web/dist/exports/Platform";
|
|
2
3
|
import PropTypes from 'prop-types';
|
|
3
4
|
import ABBPropTypes from 'airbnb-prop-types';
|
|
4
5
|
import { useThemeTokens } from '../ThemeProvider';
|
|
@@ -26,6 +27,17 @@ const getDefaultTabItemAccessibilityRole = parentRole => {
|
|
|
26
27
|
return undefined;
|
|
27
28
|
}
|
|
28
29
|
};
|
|
30
|
+
|
|
31
|
+
const getStackViewTokens = variant => {
|
|
32
|
+
const equalWidth = variant === null || variant === void 0 ? void 0 : variant.equalWidth;
|
|
33
|
+
return Platform.select({
|
|
34
|
+
web: {
|
|
35
|
+
justifyContent: equalWidth ? 'space-evenly' : 'flex-start',
|
|
36
|
+
width: equalWidth ? '100%' : 'auto'
|
|
37
|
+
},
|
|
38
|
+
default: {}
|
|
39
|
+
});
|
|
40
|
+
};
|
|
29
41
|
/**
|
|
30
42
|
* Tabs renders a horizontally-scrolling menu of selectable buttons which may link
|
|
31
43
|
* to a page or control what content is displayed on this page.
|
|
@@ -76,6 +88,7 @@ const Tabs = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
76
88
|
const restProps = selectProps(rest);
|
|
77
89
|
const parentAccessibilityRole = restProps.accessibilityRole ?? 'tablist';
|
|
78
90
|
const defaultTabItemAccessibiltyRole = getDefaultTabItemAccessibilityRole(parentAccessibilityRole);
|
|
91
|
+
const stackViewTokens = getStackViewTokens(variant);
|
|
79
92
|
return /*#__PURE__*/_jsx(HorizontalScroll, {
|
|
80
93
|
ref: ref,
|
|
81
94
|
ScrollButton: HorizontalScrollButton,
|
|
@@ -87,6 +100,7 @@ const Tabs = /*#__PURE__*/forwardRef((_ref, ref) => {
|
|
|
87
100
|
children: /*#__PURE__*/_jsx(StackView, {
|
|
88
101
|
space: space,
|
|
89
102
|
direction: "row",
|
|
103
|
+
tokens: stackViewTokens,
|
|
90
104
|
children: items.map((_ref3, index) => {
|
|
91
105
|
let {
|
|
92
106
|
href,
|
package/lib-module/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export * from './Carousel';
|
|
|
8
8
|
export { default as Listbox } from './Listbox';
|
|
9
9
|
export { default as Checkbox } from './Checkbox';
|
|
10
10
|
export * from './Checkbox';
|
|
11
|
+
export { default as CheckboxCard } from './CheckboxCard';
|
|
11
12
|
export { default as Divider } from './Divider';
|
|
12
13
|
export { default as ExpandCollapse, Accordion } from './ExpandCollapse';
|
|
13
14
|
export { default as Feedback } from './Feedback';
|
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.3.0",
|
|
14
|
-
"@telus-uds/system-theme-tokens": "^2.
|
|
14
|
+
"@telus-uds/system-theme-tokens": "^2.42.0",
|
|
15
15
|
"airbnb-prop-types": "^2.16.0",
|
|
16
16
|
"lodash.debounce": "^4.0.8",
|
|
17
17
|
"lodash.merge": "^4.6.2",
|
|
@@ -73,5 +73,5 @@
|
|
|
73
73
|
"standard-engine": {
|
|
74
74
|
"skip": true
|
|
75
75
|
},
|
|
76
|
-
"version": "1.
|
|
76
|
+
"version": "1.65.0"
|
|
77
77
|
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import React, { forwardRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
3
|
+
import { Platform, StyleSheet, View } from 'react-native'
|
|
4
|
+
|
|
5
|
+
import CheckboxInput from './CheckboxInput'
|
|
6
|
+
import { applyShadowToken, useThemeTokens } from '../ThemeProvider'
|
|
7
|
+
import {
|
|
8
|
+
a11yProps,
|
|
9
|
+
getTokensSetPropType,
|
|
10
|
+
selectSystemProps,
|
|
11
|
+
selectTokens,
|
|
12
|
+
viewProps
|
|
13
|
+
} from '../utils'
|
|
14
|
+
|
|
15
|
+
const [selectProps, selectedSystemPropTypes] = selectSystemProps([a11yProps, viewProps])
|
|
16
|
+
|
|
17
|
+
const selectInputStyles = (
|
|
18
|
+
{
|
|
19
|
+
iconBackgroundColor,
|
|
20
|
+
inputBorderColor,
|
|
21
|
+
inputBorderRadius,
|
|
22
|
+
inputBorderWidth,
|
|
23
|
+
inputBackgroundColor,
|
|
24
|
+
inputHeight,
|
|
25
|
+
inputOutlineColor,
|
|
26
|
+
inputOutlineWidth,
|
|
27
|
+
inputOutlineOffset,
|
|
28
|
+
inputShadow,
|
|
29
|
+
inputWidth
|
|
30
|
+
},
|
|
31
|
+
isChecked
|
|
32
|
+
) => ({
|
|
33
|
+
borderColor: inputBorderColor,
|
|
34
|
+
borderWidth: inputBorderWidth,
|
|
35
|
+
borderRadius: inputBorderRadius,
|
|
36
|
+
backgroundColor: isChecked ? iconBackgroundColor : inputBackgroundColor,
|
|
37
|
+
height: inputHeight,
|
|
38
|
+
width: inputWidth,
|
|
39
|
+
...applyShadowToken(inputShadow),
|
|
40
|
+
...Platform.select({
|
|
41
|
+
web: {
|
|
42
|
+
outlineStyle: 'solid',
|
|
43
|
+
outlineColor: inputOutlineColor,
|
|
44
|
+
outlineWidth: inputOutlineWidth,
|
|
45
|
+
outlineOffset: inputOutlineOffset
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const selectIconTokens = ({ icon, iconColor, iconSize }) => ({
|
|
51
|
+
icon,
|
|
52
|
+
color: iconColor,
|
|
53
|
+
size: iconSize
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const tokenKeys = [
|
|
57
|
+
'checkedBackgroundColor',
|
|
58
|
+
'checkedSize',
|
|
59
|
+
'inputBackgroundColor',
|
|
60
|
+
'inputBorderColor',
|
|
61
|
+
'inputBorderWidth',
|
|
62
|
+
'inputOutlineColor',
|
|
63
|
+
'inputOutlineWidth',
|
|
64
|
+
'inputSize',
|
|
65
|
+
'outerBorderColor',
|
|
66
|
+
'outerBorderWidth',
|
|
67
|
+
'outerBorderGap',
|
|
68
|
+
'inputSize'
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
export const selectCheckboxTokens = (themeTokens, prefix) =>
|
|
72
|
+
selectTokens(tokenKeys, themeTokens, prefix)
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The visual toggle of a checkbox input. Is not interactive on its own, should be used inside
|
|
76
|
+
* an interactive parent that passes down props when interacted with. Used in CheckboxCard
|
|
77
|
+
*/
|
|
78
|
+
const CheckboxButton = forwardRef(
|
|
79
|
+
(
|
|
80
|
+
{
|
|
81
|
+
isChecked,
|
|
82
|
+
tokens,
|
|
83
|
+
inactive,
|
|
84
|
+
defaultChecked,
|
|
85
|
+
inputId,
|
|
86
|
+
iconId,
|
|
87
|
+
isControlled,
|
|
88
|
+
handleChange,
|
|
89
|
+
name: inputName,
|
|
90
|
+
value,
|
|
91
|
+
...rest
|
|
92
|
+
},
|
|
93
|
+
ref
|
|
94
|
+
) => {
|
|
95
|
+
const { icon: IconComponent, ...stateTokens } = useThemeTokens(
|
|
96
|
+
'Checkbox',
|
|
97
|
+
{},
|
|
98
|
+
{ checked: isChecked }
|
|
99
|
+
)
|
|
100
|
+
const iconTokens = selectIconTokens(stateTokens)
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
<View {...selectProps(rest)}>
|
|
104
|
+
<View
|
|
105
|
+
style={[staticStyles.defaultInputStyles, selectInputStyles(stateTokens, isChecked)]}
|
|
106
|
+
testID={inputId}
|
|
107
|
+
>
|
|
108
|
+
<CheckboxInput
|
|
109
|
+
ref={ref}
|
|
110
|
+
checked={isChecked}
|
|
111
|
+
defaultChecked={defaultChecked}
|
|
112
|
+
disabled={inactive}
|
|
113
|
+
id={inputId}
|
|
114
|
+
isControlled={isControlled}
|
|
115
|
+
onChange={handleChange}
|
|
116
|
+
name={inputName}
|
|
117
|
+
value={value}
|
|
118
|
+
/>
|
|
119
|
+
{isChecked && IconComponent && (
|
|
120
|
+
<View testID={iconId}>
|
|
121
|
+
<IconComponent {...iconTokens} />
|
|
122
|
+
</View>
|
|
123
|
+
)}
|
|
124
|
+
</View>
|
|
125
|
+
</View>
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
CheckboxButton.displayName = 'CheckboxButton'
|
|
130
|
+
|
|
131
|
+
CheckboxButton.propTypes = {
|
|
132
|
+
...selectedSystemPropTypes,
|
|
133
|
+
/**
|
|
134
|
+
* Use `checked` for controlled Checkbox. For uncontrolled Checkbox, use the `defaultChecked` prop.
|
|
135
|
+
*/
|
|
136
|
+
isChecked: PropTypes.bool,
|
|
137
|
+
/**
|
|
138
|
+
* Checkbox tokens.
|
|
139
|
+
*/
|
|
140
|
+
tokens: getTokensSetPropType(tokenKeys, { allowFunction: true }),
|
|
141
|
+
/**
|
|
142
|
+
* Whether the corresponding input is disabled or active.
|
|
143
|
+
*/
|
|
144
|
+
inactive: PropTypes.bool,
|
|
145
|
+
/**
|
|
146
|
+
* Use `defaultChecked` to provide the initial value for an uncontrolled Checkbox.
|
|
147
|
+
*/
|
|
148
|
+
defaultChecked: PropTypes.bool,
|
|
149
|
+
/**
|
|
150
|
+
* Checkbox input ID.
|
|
151
|
+
*/
|
|
152
|
+
inputId: PropTypes.string,
|
|
153
|
+
/**
|
|
154
|
+
* Checkbox icon ID.
|
|
155
|
+
*/
|
|
156
|
+
iconId: PropTypes.string,
|
|
157
|
+
/**
|
|
158
|
+
* Can control the checkbox on the card.
|
|
159
|
+
*/
|
|
160
|
+
isControlled: PropTypes.bool,
|
|
161
|
+
/**
|
|
162
|
+
* Callback called when a controlled checkbox gets interacted with.
|
|
163
|
+
*/
|
|
164
|
+
handleChange: PropTypes.func,
|
|
165
|
+
/**
|
|
166
|
+
* Associate this checkbox with a group (set as the name attribute).
|
|
167
|
+
*/
|
|
168
|
+
name: PropTypes.string,
|
|
169
|
+
/**
|
|
170
|
+
* The value of the checkbox: true or false
|
|
171
|
+
*/
|
|
172
|
+
value: PropTypes.bool
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export default CheckboxButton
|
|
176
|
+
|
|
177
|
+
const staticStyles = StyleSheet.create({
|
|
178
|
+
container: { flexDirection: 'row', alignItems: 'center' },
|
|
179
|
+
defaultInputStyles: { alignItems: 'center', justifyContent: 'center' }
|
|
180
|
+
})
|