@telus-uds/components-base 1.1.0 → 1.2.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/.ultra.cache.json +1 -1
- package/CHANGELOG.md +8 -0
- package/__fixtures__/Accessible.js +4 -2
- package/__fixtures__/Accessible.native.js +5 -2
- package/__fixtures__/testTheme.js +9 -0
- package/__tests__/HorizontalScroll/HorizontalScroll.test.jsx +1 -0
- package/__tests__/ToggleSwitch/ToggleSwitch.test.jsx +10 -0
- package/__tests__/ToggleSwitch/ToggleSwitchGroup.test.jsx +192 -0
- package/component-docs.json +614 -796
- package/lib/Button/ButtonBase.js +20 -6
- package/lib/Card/PressableCardBase.js +9 -3
- package/lib/Checkbox/Checkbox.js +0 -2
- package/lib/IconButton/IconButton.js +8 -3
- package/lib/Link/LinkBase.js +10 -3
- package/lib/Pagination/PageButton.js +3 -1
- package/lib/Pagination/Pagination.js +16 -4
- package/lib/Pagination/SideButton.js +3 -1
- package/lib/Radio/Radio.js +0 -2
- package/lib/Tabs/Tabs.js +12 -4
- package/lib/Tabs/TabsItem.js +12 -6
- package/lib/ToggleSwitch/ToggleSwitch.js +99 -37
- package/lib/ToggleSwitch/ToggleSwitchGroup.js +230 -0
- package/lib/ToggleSwitch/index.js +14 -4
- package/lib/index.js +13 -8
- package/lib/utils/index.js +10 -1
- package/lib/utils/propTypes.js +26 -1
- package/lib/utils/withLinkRouter.js +98 -0
- package/package.json +2 -2
- package/release-context.json +4 -4
- package/src/Button/ButtonBase.jsx +11 -4
- package/src/Card/PressableCardBase.jsx +6 -4
- package/src/Checkbox/Checkbox.jsx +0 -2
- package/src/IconButton/IconButton.jsx +6 -4
- package/src/Link/LinkBase.jsx +6 -4
- package/src/Pagination/PageButton.jsx +3 -2
- package/src/Pagination/Pagination.jsx +29 -2
- package/src/Pagination/SideButton.jsx +2 -2
- package/src/Radio/Radio.jsx +0 -2
- package/src/Tabs/Tabs.jsx +49 -22
- package/src/Tabs/TabsItem.jsx +11 -7
- package/src/ToggleSwitch/ToggleSwitch.jsx +92 -34
- package/src/ToggleSwitch/ToggleSwitchGroup.jsx +203 -0
- package/src/ToggleSwitch/index.js +2 -1
- package/src/index.js +1 -1
- package/src/utils/index.js +1 -0
- package/src/utils/propTypes.js +30 -0
- package/src/utils/withLinkRouter.jsx +68 -0
- package/stories/TextInput/TextArea.stories.jsx +1 -0
- package/stories/ToggleSwitch/ToggleSwitch.stories.jsx +5 -1
- package/stories/ToggleSwitch/ToggleSwitchGroup.stories.jsx +81 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
|
|
12
|
+
var _airbnbPropTypes = _interopRequireDefault(require("airbnb-prop-types"));
|
|
13
|
+
|
|
14
|
+
var _Platform = _interopRequireDefault(require("react-native-web/dist/cjs/exports/Platform"));
|
|
15
|
+
|
|
16
|
+
var _ToggleSwitch = _interopRequireDefault(require("./ToggleSwitch"));
|
|
17
|
+
|
|
18
|
+
var _Fieldset = _interopRequireDefault(require("../Fieldset"));
|
|
19
|
+
|
|
20
|
+
var _StackView = require("../StackView");
|
|
21
|
+
|
|
22
|
+
var _ViewportProvider = require("../ViewportProvider");
|
|
23
|
+
|
|
24
|
+
var _ThemeProvider = require("../ThemeProvider");
|
|
25
|
+
|
|
26
|
+
var _propTypes2 = require("../utils/propTypes");
|
|
27
|
+
|
|
28
|
+
var _input = require("../utils/input");
|
|
29
|
+
|
|
30
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
31
|
+
|
|
32
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
33
|
+
|
|
34
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
35
|
+
|
|
36
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
37
|
+
|
|
38
|
+
const ToggleSwitchGroup = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
39
|
+
variant,
|
|
40
|
+
tokens,
|
|
41
|
+
items = [],
|
|
42
|
+
values,
|
|
43
|
+
initialValues,
|
|
44
|
+
maxValues = 1,
|
|
45
|
+
onChange,
|
|
46
|
+
readOnly = false,
|
|
47
|
+
inactive = false,
|
|
48
|
+
feedback,
|
|
49
|
+
hint,
|
|
50
|
+
tooltip,
|
|
51
|
+
legend,
|
|
52
|
+
name: inputGroupName,
|
|
53
|
+
accessibilityRole = maxValues === 1 ? 'radiogroup' // radiogroup is cross-platform; only web aria has generic groups
|
|
54
|
+
: _Platform.default.select({
|
|
55
|
+
web: 'group',
|
|
56
|
+
default: 'none'
|
|
57
|
+
}),
|
|
58
|
+
toggleSwitchTokens,
|
|
59
|
+
validation,
|
|
60
|
+
...rest
|
|
61
|
+
}, ref) => {
|
|
62
|
+
const viewport = (0, _ViewportProvider.useViewport)();
|
|
63
|
+
const {
|
|
64
|
+
space,
|
|
65
|
+
fieldSpace
|
|
66
|
+
} = (0, _ThemeProvider.useThemeTokens)('ToggleSwitchGroup', tokens, variant, {
|
|
67
|
+
viewport
|
|
68
|
+
});
|
|
69
|
+
const {
|
|
70
|
+
currentValues,
|
|
71
|
+
toggleOneValue
|
|
72
|
+
} = (0, _input.useMultipleInputValues)({
|
|
73
|
+
initialValues,
|
|
74
|
+
values,
|
|
75
|
+
maxValues,
|
|
76
|
+
onChange,
|
|
77
|
+
readOnly
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const a11y = _propTypes2.a11yProps.select({
|
|
81
|
+
accessibilityRole,
|
|
82
|
+
...rest
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const itemA11yRole = a11y.accessibilityRole === 'radiogroup' ? 'radio' : 'switch';
|
|
86
|
+
const toggleSwitches = items.map(({
|
|
87
|
+
label,
|
|
88
|
+
id = label,
|
|
89
|
+
accessibilityLabel = label,
|
|
90
|
+
onChange: itemOnChange,
|
|
91
|
+
ref: itemRef,
|
|
92
|
+
tooltip: itemTooltip
|
|
93
|
+
}, index) => {
|
|
94
|
+
const isSelected = currentValues.includes(id);
|
|
95
|
+
|
|
96
|
+
const handleChange = (newCheckedState, event) => {
|
|
97
|
+
if (typeof itemOnChange === 'function') itemOnChange(newCheckedState, event);
|
|
98
|
+
toggleOneValue(id, event);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const itemA11y = {
|
|
102
|
+
accessibilityState: {
|
|
103
|
+
checked: isSelected
|
|
104
|
+
},
|
|
105
|
+
accessibilityRole: itemA11yRole,
|
|
106
|
+
accessibilityLabel,
|
|
107
|
+
..._propTypes2.a11yProps.getPositionInSet(items.length, index)
|
|
108
|
+
};
|
|
109
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ToggleSwitch.default, {
|
|
110
|
+
id: id,
|
|
111
|
+
ref: itemRef,
|
|
112
|
+
onChange: handleChange,
|
|
113
|
+
tokens: toggleSwitchTokens,
|
|
114
|
+
value: isSelected,
|
|
115
|
+
inactive: inactive,
|
|
116
|
+
label: label,
|
|
117
|
+
tooltip: itemTooltip,
|
|
118
|
+
...itemA11y
|
|
119
|
+
}, id);
|
|
120
|
+
});
|
|
121
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Fieldset.default, {
|
|
122
|
+
ref: ref,
|
|
123
|
+
name: inputGroupName,
|
|
124
|
+
legend: legend,
|
|
125
|
+
tooltip: tooltip,
|
|
126
|
+
hint: hint,
|
|
127
|
+
space: fieldSpace,
|
|
128
|
+
feedback: feedback,
|
|
129
|
+
inactive: inactive,
|
|
130
|
+
validation: validation,
|
|
131
|
+
...a11y,
|
|
132
|
+
children: (0, _StackView.getStackedContent)(toggleSwitches, {
|
|
133
|
+
space,
|
|
134
|
+
direction: 'column'
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
ToggleSwitchGroup.displayName = 'ToggleSwitchGroup';
|
|
139
|
+
ToggleSwitchGroup.propTypes = { ..._propTypes2.a11yProps.propTypes,
|
|
140
|
+
..._propTypes2.pressProps.propTypes,
|
|
141
|
+
tokens: (0, _propTypes2.getTokensPropType)('ToggleSwitchGroup'),
|
|
142
|
+
variant: _propTypes2.variantProp.propType,
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The maximum number of items a user may select at once. Defaults to 1 and behaves
|
|
146
|
+
* like radio buttons. To have no limit and allow any number of selections, pass `null`.
|
|
147
|
+
*/
|
|
148
|
+
maxValues: _propTypes.default.number,
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* The options a user may select
|
|
152
|
+
*/
|
|
153
|
+
items: _propTypes.default.arrayOf(_propTypes.default.shape({
|
|
154
|
+
/**
|
|
155
|
+
* The text displayed to the user on the label.
|
|
156
|
+
*/
|
|
157
|
+
label: _propTypes.default.string.isRequired,
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* An optional accessibility label may be passed to each ToggleSwitch
|
|
161
|
+
* and will be applied as normal for a React Native accessibilityLabel prop.
|
|
162
|
+
*/
|
|
163
|
+
accessibilityLabel: _propTypes.default.string,
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* An optional unique string may be provided to identify this option,
|
|
167
|
+
* which will be used in code and passed to any onChange function.
|
|
168
|
+
* If not provided, the label is used.
|
|
169
|
+
*/
|
|
170
|
+
id: _propTypes.default.string,
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* An optional ref for one individual ToggleSwitch in the ToggleSwitchGroup
|
|
174
|
+
*/
|
|
175
|
+
ref: _airbnbPropTypes.default.ref()
|
|
176
|
+
})),
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* If provided, this function is called when the current selection is changed
|
|
180
|
+
* and is passed an array of the `id`s of all currently selected `items`.
|
|
181
|
+
*/
|
|
182
|
+
onChange: _propTypes.default.func,
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* If the selected item(s) in the toggle switch group are to be controlled externally by
|
|
186
|
+
* a parent component, pass an array of strings as well as an `onChange` handler.
|
|
187
|
+
* Passing an array for "values" makes the ToggleSwitchGroup a "controlled" component that
|
|
188
|
+
* expects its state to be handled via `onChange` and so doesn't handle it itself.
|
|
189
|
+
*/
|
|
190
|
+
values: _propTypes.default.arrayOf(_propTypes.default.string),
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* If `values` is not passed, making the ToggleSwitchGroup an "uncontrolled" component
|
|
194
|
+
* managing its own selected state, a default set of selections may be provided.
|
|
195
|
+
* Changing the `initialValues` does not change the user's selections.
|
|
196
|
+
*/
|
|
197
|
+
initialValues: _propTypes.default.arrayOf(_propTypes.default.string),
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Optional additional text giving more detail to help a user make a choice.
|
|
201
|
+
*/
|
|
202
|
+
hint: _propTypes.default.string,
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Optional tooltip text content to include alongside the legend and hint.
|
|
206
|
+
*/
|
|
207
|
+
tooltip: _propTypes.default.string,
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* If provided, a Feedback element is rendered containing this text.
|
|
211
|
+
*/
|
|
212
|
+
feedback: _propTypes.default.string,
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Main text used to describe this group, used in Fieldset's Legend element.
|
|
216
|
+
*/
|
|
217
|
+
legend: _propTypes.default.string,
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Toggle switch token overrides.
|
|
221
|
+
*/
|
|
222
|
+
toggleSwitchTokens: (0, _propTypes2.getTokensPropType)('ToggleSwitch'),
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Current validation status of the group, passed to the feedback element if there is one.
|
|
226
|
+
*/
|
|
227
|
+
validation: _propTypes.default.oneOf(['error', 'success'])
|
|
228
|
+
};
|
|
229
|
+
var _default = ToggleSwitchGroup;
|
|
230
|
+
exports.default = _default;
|
|
@@ -3,11 +3,21 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports
|
|
6
|
+
Object.defineProperty(exports, "ToggleSwitch", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _ToggleSwitch.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "ToggleSwitchGroup", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _ToggleSwitchGroup.default;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
7
18
|
|
|
8
19
|
var _ToggleSwitch = _interopRequireDefault(require("./ToggleSwitch"));
|
|
9
20
|
|
|
10
|
-
|
|
21
|
+
var _ToggleSwitchGroup = _interopRequireDefault(require("./ToggleSwitchGroup"));
|
|
11
22
|
|
|
12
|
-
|
|
13
|
-
exports.default = _default;
|
|
23
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
package/lib/index.js
CHANGED
|
@@ -38,7 +38,6 @@ var _exportNames = {
|
|
|
38
38
|
StepTracker: true,
|
|
39
39
|
Tabs: true,
|
|
40
40
|
Tags: true,
|
|
41
|
-
ToggleSwitch: true,
|
|
42
41
|
Tooltip: true,
|
|
43
42
|
TooltipButton: true,
|
|
44
43
|
Typography: true,
|
|
@@ -257,12 +256,6 @@ Object.defineProperty(exports, "Tags", {
|
|
|
257
256
|
return _Tags.default;
|
|
258
257
|
}
|
|
259
258
|
});
|
|
260
|
-
Object.defineProperty(exports, "ToggleSwitch", {
|
|
261
|
-
enumerable: true,
|
|
262
|
-
get: function () {
|
|
263
|
-
return _ToggleSwitch.default;
|
|
264
|
-
}
|
|
265
|
-
});
|
|
266
259
|
Object.defineProperty(exports, "Tooltip", {
|
|
267
260
|
enumerable: true,
|
|
268
261
|
get: function () {
|
|
@@ -516,7 +509,19 @@ Object.keys(_TextInput).forEach(function (key) {
|
|
|
516
509
|
});
|
|
517
510
|
});
|
|
518
511
|
|
|
519
|
-
var _ToggleSwitch =
|
|
512
|
+
var _ToggleSwitch = require("./ToggleSwitch");
|
|
513
|
+
|
|
514
|
+
Object.keys(_ToggleSwitch).forEach(function (key) {
|
|
515
|
+
if (key === "default" || key === "__esModule") return;
|
|
516
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
517
|
+
if (key in exports && exports[key] === _ToggleSwitch[key]) return;
|
|
518
|
+
Object.defineProperty(exports, key, {
|
|
519
|
+
enumerable: true,
|
|
520
|
+
get: function () {
|
|
521
|
+
return _ToggleSwitch[key];
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
});
|
|
520
525
|
|
|
521
526
|
var _Tooltip = _interopRequireDefault(require("./Tooltip"));
|
|
522
527
|
|
package/lib/utils/index.js
CHANGED
|
@@ -9,7 +9,8 @@ var _exportNames = {
|
|
|
9
9
|
useHash: true,
|
|
10
10
|
useSpacingScale: true,
|
|
11
11
|
useResponsiveProp: true,
|
|
12
|
-
useUniqueId: true
|
|
12
|
+
useUniqueId: true,
|
|
13
|
+
withLinkRouter: true
|
|
13
14
|
};
|
|
14
15
|
Object.defineProperty(exports, "info", {
|
|
15
16
|
enumerable: true,
|
|
@@ -47,6 +48,12 @@ Object.defineProperty(exports, "useUniqueId", {
|
|
|
47
48
|
return _useUniqueId.default;
|
|
48
49
|
}
|
|
49
50
|
});
|
|
51
|
+
Object.defineProperty(exports, "withLinkRouter", {
|
|
52
|
+
enumerable: true,
|
|
53
|
+
get: function () {
|
|
54
|
+
return _withLinkRouter.default;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
50
57
|
|
|
51
58
|
var _a11y = require("./a11y");
|
|
52
59
|
|
|
@@ -156,6 +163,8 @@ Object.keys(_useResponsiveProp).forEach(function (key) {
|
|
|
156
163
|
|
|
157
164
|
var _useUniqueId = _interopRequireDefault(require("./useUniqueId"));
|
|
158
165
|
|
|
166
|
+
var _withLinkRouter = _interopRequireDefault(require("./withLinkRouter"));
|
|
167
|
+
|
|
159
168
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
160
169
|
|
|
161
170
|
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
package/lib/utils/propTypes.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.copyPropTypes = exports.componentPropType = exports.spacingProps = exports.responsiveProps = exports.viewProps = exports.linkProps = exports.pressProps = exports.hrefAttrsProp = exports.a11yProps = exports.getTokensSetPropType = exports.getTokensPropType = exports.selectTokens = exports.getTokenNames = exports.variantProp = exports.rectProp = exports.paddingProp = void 0;
|
|
6
|
+
exports.copyPropTypes = exports.componentPropType = exports.spacingProps = exports.responsiveProps = exports.viewProps = exports.linkProps = exports.clickProps = exports.pressProps = exports.hrefAttrsProp = exports.a11yProps = exports.getTokensSetPropType = exports.getTokensPropType = exports.selectTokens = exports.getTokenNames = exports.variantProp = exports.rectProp = exports.paddingProp = void 0;
|
|
7
7
|
|
|
8
8
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
9
9
|
|
|
@@ -319,6 +319,31 @@ const pressProps = {
|
|
|
319
319
|
selectHandlers: getPropSelector(pressHandlerPropTypes)
|
|
320
320
|
};
|
|
321
321
|
exports.pressProps = pressProps;
|
|
322
|
+
const clickHandlerMapping = {
|
|
323
|
+
onClick: 'onPress',
|
|
324
|
+
mouseDown: 'onPressIn',
|
|
325
|
+
mouseUp: 'onPressOut'
|
|
326
|
+
};
|
|
327
|
+
const clickProps = {
|
|
328
|
+
/**
|
|
329
|
+
* Web-oriented HTML click handlers that may be mapped to React Native press handlers
|
|
330
|
+
*/
|
|
331
|
+
types: Object.fromEntries(Object.keys(clickHandlerMapping).map(mouseName => [mouseName, _propTypes.default.func])),
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Takes a set of props and converts HTML mouse click oriented event handlers to closest
|
|
335
|
+
* equivalent React Native press event handler.
|
|
336
|
+
*
|
|
337
|
+
* Use this when a component that expects press-oriented props may need to support third-party
|
|
338
|
+
* web-oriented tooling that injects web-oriented event handlers directly. For example, for
|
|
339
|
+
* to support use with NextJS's 'next/link' component, which injects `onClick` prop into its child.
|
|
340
|
+
*/
|
|
341
|
+
toPressProps: props => Object.fromEntries(Object.entries(props).map(([originalName, value]) => {
|
|
342
|
+
const translatedName = clickHandlerMapping[originalName];
|
|
343
|
+
return translatedName ? [translatedName, value] : [originalName, value];
|
|
344
|
+
}))
|
|
345
|
+
};
|
|
346
|
+
exports.clickProps = clickProps;
|
|
322
347
|
const linkPropTypes = { ...pressPropTypes,
|
|
323
348
|
href: _propTypes.default.string,
|
|
324
349
|
hrefAttrs: _propTypes.default.shape(hrefAttrsProp.types),
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
|
|
12
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
13
|
+
|
|
14
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
+
|
|
16
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
17
|
+
|
|
18
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
19
|
+
|
|
20
|
+
// Prototype-safe alternative to (linter-forbidden) someObject.hasOwnProperty()
|
|
21
|
+
const hasOwnProperty = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop);
|
|
22
|
+
/**
|
|
23
|
+
* Higher-order component that has no effect unless an additional prop `LinkRouter` is passed.
|
|
24
|
+
* This may be used to provide custom wrappers for integrations with third party libraries.
|
|
25
|
+
*
|
|
26
|
+
* If LinkRouter is passed, LinkRouter is rendered in place of the main component and is passed:
|
|
27
|
+
*
|
|
28
|
+
* - `linkRouterProps`: an optional object passed alongside LinkRouter, for props needed by the wrapper
|
|
29
|
+
* that are not valid props for the wrapped component.
|
|
30
|
+
* - `Component`: automatically provided, the original component to render inside the wrapper.
|
|
31
|
+
* - `ref`: forwarded `ref` passed down to `Component`
|
|
32
|
+
* - All other props passed to the outer component
|
|
33
|
+
*
|
|
34
|
+
* @example A LinkRouter component to be used with link-like components might look like:
|
|
35
|
+
*
|
|
36
|
+
* ```jsx
|
|
37
|
+
* const LinkLinkRouter = forwardRef(({ Component, linkRouterProps: { to, options }, href, ...rest }, ref) => {
|
|
38
|
+
* const { href: resolvedHref, onClick } = useSomeRouterHook({ to, href, options })
|
|
39
|
+
* return <Component href={resolvedHref} onPress={onClick} {...rest} />
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* Any component that takes href and onPress props may then use this wrapper:
|
|
44
|
+
*
|
|
45
|
+
* ```jsx
|
|
46
|
+
* <Link href={href} LinkRouter={LinkLinkRouter} linkRouterProps={{ to, options }}>Some link</Link>
|
|
47
|
+
* <IconButton icon={SomeIcon} LinkRouter={LinkLinkRouter} linkRouterProps={{ to, options }} ref={iconRef} />
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
const withLinkRouter = Component => {
|
|
53
|
+
const wrappedComponent = /*#__PURE__*/(0, _react.forwardRef)(({
|
|
54
|
+
LinkRouter,
|
|
55
|
+
linkRouterProps,
|
|
56
|
+
...props
|
|
57
|
+
}, ref) => {
|
|
58
|
+
if (!LinkRouter) return /*#__PURE__*/(0, _jsxRuntime.jsx)(Component, { ...props,
|
|
59
|
+
ref: ref
|
|
60
|
+
});
|
|
61
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(LinkRouter, {
|
|
62
|
+
linkRouterProps: linkRouterProps,
|
|
63
|
+
Component: Component,
|
|
64
|
+
ref: ref,
|
|
65
|
+
...props
|
|
66
|
+
});
|
|
67
|
+
}); // Ensure the returned component has appropriate outer properties set:
|
|
68
|
+
|
|
69
|
+
/* eslint-disable-next-line react/forbid-foreign-prop-types */
|
|
70
|
+
|
|
71
|
+
const {
|
|
72
|
+
displayName,
|
|
73
|
+
name,
|
|
74
|
+
propTypes,
|
|
75
|
+
...otherProperties
|
|
76
|
+
} = Component; // Apply unique component name as a displayName
|
|
77
|
+
|
|
78
|
+
wrappedComponent.displayName = Component.displayName || Component.name; // Apply proptypes including wrapper props - is safely { ...undefined, ...undefined } in prod
|
|
79
|
+
|
|
80
|
+
wrappedComponent.propTypes = { ...Component.propTypes,
|
|
81
|
+
...withLinkRouter.propTypes
|
|
82
|
+
}; // Forward any other properties explicitly set e.g. Component.SubComponent
|
|
83
|
+
|
|
84
|
+
Object.keys(otherProperties).forEach(key => {
|
|
85
|
+
// Skip internal React properties from wrappedComponent's forwardRef (render, $$typeof, etc)
|
|
86
|
+
if (hasOwnProperty(Component, key) && !hasOwnProperty(wrappedComponent, key)) {
|
|
87
|
+
wrappedComponent[key] = Component[key];
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
return wrappedComponent;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
withLinkRouter.propTypes = {
|
|
94
|
+
LinkRouter: _propTypes.default.elementType,
|
|
95
|
+
linkRouterProps: _propTypes.default.object
|
|
96
|
+
};
|
|
97
|
+
var _default = withLinkRouter;
|
|
98
|
+
exports.default = _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telus-uds/components-base",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Base components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"base"
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"airbnb-prop-types": "^2.16.0",
|
|
57
57
|
"@telus-uds/system-constants": "^1.0.1-prerelease.0",
|
|
58
|
-
"@telus-uds/system-theme-tokens": "^1.
|
|
58
|
+
"@telus-uds/system-theme-tokens": "^1.2.0",
|
|
59
59
|
"lodash.debounce": "^4.0.8",
|
|
60
60
|
"lodash.merge": "^4.6.2",
|
|
61
61
|
"prop-types": "^15.7.2",
|
package/release-context.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"previousReleaseTag": "@telus-uds/components-base/v1.0
|
|
3
|
-
"changelog": "## [1.
|
|
4
|
-
"releaseTag": "@telus-uds/components-base/v1.
|
|
5
|
-
"newVersion": "1.
|
|
2
|
+
"previousReleaseTag": "@telus-uds/components-base/v1.1.0",
|
|
3
|
+
"changelog": "## [1.2.0](https://github.com/telus/universal-design-system/compare/@telus-uds/components-base/v1.1.0...@telus-uds/components-base/v1.2.0) (2022-03-02)\n\n\n### Features\n\n* add withLinkRouter to support router integration ([#1324](https://github.com/telus/universal-design-system/issues/1324)) ([e56f491](https://github.com/telus/universal-design-system/commit/e56f491ac088a005f364330cfc70901532df7cea))\n* **component-base:** refactor ToggleSwitch to use input label and add tooltip support ([#1341](https://github.com/telus/universal-design-system/issues/1341)) ([979da1a](https://github.com/telus/universal-design-system/commit/979da1afb5b319df51026f44299d363f50f1be7d))\n* **components-base:** add ToggleSwitchGroup ([#1307](https://github.com/telus/universal-design-system/issues/1307)) ([402630a](https://github.com/telus/universal-design-system/commit/402630ad04c2d81c4f882fed564cf4ae33096cea))\n",
|
|
4
|
+
"releaseTag": "@telus-uds/components-base/v1.2.0",
|
|
5
|
+
"newVersion": "1.2.0",
|
|
6
6
|
"packageName": "@telus-uds/components-base"
|
|
7
7
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react'
|
|
2
|
+
import PropTypes from 'prop-types'
|
|
2
3
|
import { Pressable, View, StyleSheet, Platform } from 'react-native'
|
|
3
4
|
|
|
4
5
|
import { applyTextStyles, applyShadowToken, applyOuterBorder } from '../ThemeProvider/utils'
|
|
@@ -6,10 +7,12 @@ import buttonPropTypes from './propTypes'
|
|
|
6
7
|
import {
|
|
7
8
|
a11yProps,
|
|
8
9
|
getCursorStyle,
|
|
10
|
+
clickProps,
|
|
9
11
|
linkProps,
|
|
10
12
|
resolvePressableState,
|
|
11
13
|
resolvePressableTokens,
|
|
12
|
-
wrapStringsInText
|
|
14
|
+
wrapStringsInText,
|
|
15
|
+
withLinkRouter
|
|
13
16
|
} from '../utils'
|
|
14
17
|
|
|
15
18
|
const getOuterBorderOffset = ({ outerBorderGap = 0, outerBorderWidth = 0 }) =>
|
|
@@ -133,19 +136,20 @@ const selectWebOnlyStyles = (inactive, themeTokens, { accessibilityRole }) => {
|
|
|
133
136
|
const ButtonBase = forwardRef(
|
|
134
137
|
(
|
|
135
138
|
{
|
|
139
|
+
id,
|
|
136
140
|
href,
|
|
137
141
|
hrefAttrs,
|
|
138
142
|
children,
|
|
139
|
-
onPress,
|
|
140
143
|
tokens = {},
|
|
141
144
|
disabled = false, // alias for inactive
|
|
142
145
|
inactive = disabled,
|
|
143
146
|
selected = false,
|
|
144
147
|
dataSet,
|
|
145
|
-
...
|
|
148
|
+
...rawRest
|
|
146
149
|
},
|
|
147
150
|
ref
|
|
148
151
|
) => {
|
|
152
|
+
const { onPress, ...rest } = clickProps.toPressProps(rawRest)
|
|
149
153
|
const extraButtonState = { inactive, selected }
|
|
150
154
|
const resolveButtonTokens = (pressableState) =>
|
|
151
155
|
resolvePressableTokens(tokens, pressableState, extraButtonState)
|
|
@@ -185,6 +189,7 @@ const ButtonBase = forwardRef(
|
|
|
185
189
|
|
|
186
190
|
return (
|
|
187
191
|
<View
|
|
192
|
+
id={id}
|
|
188
193
|
style={[
|
|
189
194
|
containerStyles,
|
|
190
195
|
borderStyles,
|
|
@@ -218,10 +223,12 @@ const ButtonBase = forwardRef(
|
|
|
218
223
|
ButtonBase.displayName = 'ButtonBase'
|
|
219
224
|
|
|
220
225
|
ButtonBase.propTypes = {
|
|
226
|
+
id: PropTypes.string,
|
|
221
227
|
...a11yProps.types,
|
|
222
228
|
...buttonPropTypes,
|
|
223
229
|
...linkProps.types
|
|
224
230
|
}
|
|
231
|
+
ButtonBase.defaultProps = { id: undefined }
|
|
225
232
|
|
|
226
233
|
const staticStyles = StyleSheet.create({
|
|
227
234
|
row: {
|
|
@@ -245,4 +252,4 @@ const staticStyles = StyleSheet.create({
|
|
|
245
252
|
}
|
|
246
253
|
})
|
|
247
254
|
|
|
248
|
-
export default ButtonBase
|
|
255
|
+
export default withLinkRouter(ButtonBase)
|
|
@@ -11,7 +11,9 @@ import {
|
|
|
11
11
|
getTokenNames,
|
|
12
12
|
getTokensSetPropType,
|
|
13
13
|
variantProp,
|
|
14
|
-
linkProps
|
|
14
|
+
linkProps,
|
|
15
|
+
clickProps,
|
|
16
|
+
withLinkRouter
|
|
15
17
|
} from '../utils'
|
|
16
18
|
import { a11yProps } from '../utils/propTypes'
|
|
17
19
|
import CardBase from './CardBase'
|
|
@@ -43,12 +45,12 @@ const PressableCardBase = forwardRef(
|
|
|
43
45
|
inactive,
|
|
44
46
|
href,
|
|
45
47
|
hrefAttrs,
|
|
46
|
-
onPress,
|
|
47
48
|
accessibilityRole = href ? 'link' : undefined,
|
|
48
|
-
...
|
|
49
|
+
...rawRest
|
|
49
50
|
},
|
|
50
51
|
ref
|
|
51
52
|
) => {
|
|
53
|
+
const { onPress, ...rest } = clickProps.toPressProps(rawRest)
|
|
52
54
|
const viewport = useViewport()
|
|
53
55
|
const a11y = a11yProps.select({
|
|
54
56
|
...rest,
|
|
@@ -116,4 +118,4 @@ PressableCardBase.propTypes = {
|
|
|
116
118
|
...a11yProps.types
|
|
117
119
|
}
|
|
118
120
|
|
|
119
|
-
export default PressableCardBase
|
|
121
|
+
export default withLinkRouter(PressableCardBase)
|
|
@@ -3,8 +3,6 @@ import PropTypes from 'prop-types'
|
|
|
3
3
|
import { Platform, Pressable, StyleSheet, Text, View } from 'react-native'
|
|
4
4
|
|
|
5
5
|
import CheckboxInput from './CheckboxInput'
|
|
6
|
-
// @todo move `LabelContent` outside of the `InputLabel` and fix
|
|
7
|
-
// the issue with the cursor not being pointer on Web
|
|
8
6
|
import CheckboxLabel from '../InputLabel/LabelContent'
|
|
9
7
|
import Feedback from '../Feedback'
|
|
10
8
|
import StackView from '../StackView'
|
|
@@ -5,11 +5,13 @@ import { Pressable, Platform, StyleSheet, View } from 'react-native'
|
|
|
5
5
|
import { applyOuterBorder, useThemeTokensCallback, applyShadowToken } from '../ThemeProvider'
|
|
6
6
|
import {
|
|
7
7
|
variantProp,
|
|
8
|
+
clickProps,
|
|
8
9
|
linkProps,
|
|
9
10
|
resolvePressableState,
|
|
10
11
|
hrefAttrsProp,
|
|
11
12
|
getTokensPropType,
|
|
12
|
-
selectTokens
|
|
13
|
+
selectTokens,
|
|
14
|
+
withLinkRouter
|
|
13
15
|
} from '../utils'
|
|
14
16
|
import { a11yProps } from '../utils/propTypes'
|
|
15
17
|
import Icon from '../Icon'
|
|
@@ -52,12 +54,12 @@ const IconButton = forwardRef(
|
|
|
52
54
|
icon: IconComponent,
|
|
53
55
|
href,
|
|
54
56
|
hrefAttrs,
|
|
55
|
-
onPress,
|
|
56
57
|
accessibilityRole = href ? 'link' : 'button',
|
|
57
|
-
...
|
|
58
|
+
...rawRest
|
|
58
59
|
},
|
|
59
60
|
ref
|
|
60
61
|
) => {
|
|
62
|
+
const { onPress, ...rest } = clickProps.toPressProps(rawRest)
|
|
61
63
|
const a11y = a11yProps.select({
|
|
62
64
|
...rest,
|
|
63
65
|
accessibilityRole
|
|
@@ -111,4 +113,4 @@ const staticStyles = StyleSheet.create({
|
|
|
111
113
|
}
|
|
112
114
|
})
|
|
113
115
|
|
|
114
|
-
export default IconButton
|
|
116
|
+
export default withLinkRouter(IconButton)
|