@planningcenter/tapestry-react 2.9.0-rc.7 → 2.9.0-rc.8
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/dist/cjs/Button/Button.js +9 -5
- package/dist/cjs/TimeField/TimeField.js +23 -23
- package/dist/cjs/ToggleSwitch/ToggleSwitch.js +5 -5
- package/dist/cjs/ToggleSwitch/ToggleSwitch.test.js +64 -5
- package/dist/esm/Button/Button.js +9 -5
- package/dist/esm/TimeField/TimeField.js +23 -23
- package/dist/esm/ToggleSwitch/ToggleSwitch.js +5 -5
- package/dist/esm/ToggleSwitch/ToggleSwitch.test.js +62 -5
- package/dist/types/ToggleSwitch/ToggleSwitch.d.ts +3 -3
- package/package.json +1 -1
- package/src/Button/Button.tsx +7 -8
- package/src/TimeField/TimeField.tsx +22 -22
- package/src/ToggleSwitch/ToggleSwitch.mdx +8 -8
- package/src/ToggleSwitch/ToggleSwitch.test.tsx +69 -5
- package/src/ToggleSwitch/ToggleSwitch.tsx +5 -7
|
@@ -178,12 +178,16 @@ function Button(_ref) {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
if (disabled) {
|
|
181
|
-
var
|
|
181
|
+
var themeData = buttonThemes[theme];
|
|
182
182
|
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
183
|
+
if (themeData) {
|
|
184
|
+
var variantData = themeData[variant];
|
|
185
|
+
|
|
186
|
+
if (variantData && variantData.disabled) {
|
|
187
|
+
buttonProps = _objectSpread(_objectSpread({}, buttonProps), variantData.disabled);
|
|
188
|
+
} else {
|
|
189
|
+
buttonProps.opacity = 0.65;
|
|
190
|
+
}
|
|
187
191
|
}
|
|
188
192
|
|
|
189
193
|
buttonProps['aria-disabled'] = true;
|
|
@@ -271,20 +271,20 @@ var TimeField = function TimeField(_ref) {
|
|
|
271
271
|
ref: ref,
|
|
272
272
|
inline: true
|
|
273
273
|
}, restProps), /*#__PURE__*/_react["default"].createElement(_NumberField["default"], {
|
|
274
|
+
"aria-label": "Hours",
|
|
274
275
|
autoWidth: false,
|
|
275
276
|
fontVariantNumeric: "tabular-nums",
|
|
276
|
-
moveFocusOnMax: true,
|
|
277
|
-
value: hoursDisplay,
|
|
278
|
-
min: 0,
|
|
279
|
-
max: twelveHourClock ? 12 : 23,
|
|
280
|
-
pad: 2,
|
|
281
277
|
grow: 0,
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
278
|
+
max: twelveHourClock ? 12 : 23,
|
|
279
|
+
min: 0,
|
|
280
|
+
moveFocusOnMax: true,
|
|
281
|
+
onBlur: handleHoursBlur,
|
|
285
282
|
onChange: handleHoursChange,
|
|
286
283
|
onKeyDown: handleHoursKeyDown,
|
|
287
|
-
|
|
284
|
+
pad: 2,
|
|
285
|
+
textAlign: "center",
|
|
286
|
+
value: hoursDisplay,
|
|
287
|
+
width: "2ch",
|
|
288
288
|
ignoredKeys: ignoredKeys
|
|
289
289
|
}), /*#__PURE__*/_react["default"].createElement(_Box["default"], {
|
|
290
290
|
as: "span",
|
|
@@ -292,31 +292,31 @@ var TimeField = function TimeField(_ref) {
|
|
|
292
292
|
textAlign: "center",
|
|
293
293
|
userSelect: "none"
|
|
294
294
|
}, ":"), /*#__PURE__*/_react["default"].createElement(_NumberField["default"], {
|
|
295
|
+
"aria-label": "Minutes",
|
|
295
296
|
autoWidth: false,
|
|
296
297
|
fontVariantNumeric: "tabular-nums",
|
|
297
|
-
moveFocusOnMax: true,
|
|
298
|
-
value: minutes,
|
|
299
|
-
min: 0,
|
|
300
|
-
max: 59,
|
|
301
|
-
pad: 2,
|
|
302
298
|
grow: 0,
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
299
|
+
max: 59,
|
|
300
|
+
min: 0,
|
|
301
|
+
moveFocusOnMax: true,
|
|
306
302
|
onChange: function onChange(e) {
|
|
307
303
|
return setMinutes(e);
|
|
308
304
|
},
|
|
309
305
|
onKeyDown: handleMinutesKeyDown,
|
|
306
|
+
pad: 2,
|
|
307
|
+
textAlign: "center",
|
|
308
|
+
value: minutes,
|
|
309
|
+
width: "2ch",
|
|
310
310
|
ignoredKeys: ignoredKeys
|
|
311
311
|
}), twelveHourClock && /*#__PURE__*/_react["default"].createElement(_InputField["default"], {
|
|
312
|
-
highlightOnInteraction: true,
|
|
313
|
-
value: meridiem,
|
|
314
|
-
grow: 0,
|
|
315
|
-
width: "2em",
|
|
316
|
-
textAlign: "center",
|
|
317
312
|
"aria-label": "AM/PM",
|
|
313
|
+
grow: 0,
|
|
314
|
+
highlightOnInteraction: true,
|
|
318
315
|
onChange: _utils.noop,
|
|
319
|
-
onKeyDown: handleAMPMKeyDown
|
|
316
|
+
onKeyDown: handleAMPMKeyDown,
|
|
317
|
+
textAlign: "center",
|
|
318
|
+
value: meridiem,
|
|
319
|
+
width: "2em"
|
|
320
320
|
}));
|
|
321
321
|
};
|
|
322
322
|
|
|
@@ -27,13 +27,13 @@ var _system = require("../system");
|
|
|
27
27
|
function ToggleSwitch(props) {
|
|
28
28
|
var _props$disabled = props.disabled,
|
|
29
29
|
disabled = _props$disabled === void 0 ? false : _props$disabled,
|
|
30
|
-
|
|
30
|
+
isChecked = props.isChecked,
|
|
31
31
|
label = props.label,
|
|
32
32
|
onClick = props.onClick,
|
|
33
33
|
_props$size = props.size,
|
|
34
34
|
size = _props$size === void 0 ? 'md' : _props$size,
|
|
35
35
|
tooltip = props.tooltip,
|
|
36
|
-
restProps = (0, _objectWithoutPropertiesLoose2["default"])(props, ["disabled", "
|
|
36
|
+
restProps = (0, _objectWithoutPropertiesLoose2["default"])(props, ["disabled", "isChecked", "label", "onClick", "size", "tooltip"]);
|
|
37
37
|
|
|
38
38
|
var _useThemeProps = (0, _system.useThemeProps)('toggleSwitch', restProps),
|
|
39
39
|
backgroundColor = _useThemeProps.backgroundColor;
|
|
@@ -73,7 +73,7 @@ function ToggleSwitch(props) {
|
|
|
73
73
|
spacing: size === 'xs' ? 0.5 : size === 'sm' ? 0.75 : 1
|
|
74
74
|
}, /*#__PURE__*/_react["default"].createElement(_Button["default"], (0, _extends2["default"])({
|
|
75
75
|
as: "button",
|
|
76
|
-
backgroundColor: disabled ? _colors.colors.grays.light.neutral81 :
|
|
76
|
+
backgroundColor: disabled ? _colors.colors.grays.light.neutral81 : isChecked ? backgroundColor : _colors.colors.grays.light.neutral62,
|
|
77
77
|
onClick: onClick,
|
|
78
78
|
opacity: 1,
|
|
79
79
|
position: "relative",
|
|
@@ -81,14 +81,14 @@ function ToggleSwitch(props) {
|
|
|
81
81
|
theme: false,
|
|
82
82
|
disabled: disabled,
|
|
83
83
|
tooltip: tooltip
|
|
84
|
-
}, toggleButtonProps
|
|
84
|
+
}, toggleButtonProps), /*#__PURE__*/_react["default"].createElement(_Box.Box, (0, _extends2["default"])({
|
|
85
85
|
background: "#fff",
|
|
86
86
|
left: 0.25,
|
|
87
87
|
pointerEvents: "none",
|
|
88
88
|
position: "absolute",
|
|
89
89
|
radius: "circle",
|
|
90
90
|
top: 0.25,
|
|
91
|
-
transform: "translateX(" + (
|
|
91
|
+
transform: "translateX(" + (isChecked ? 'calc(100% - 1px)' : '0%') + ")",
|
|
92
92
|
transition: "120ms"
|
|
93
93
|
}, toggleNotchProps))), label && /*#__PURE__*/_react["default"].createElement(_Text["default"], {
|
|
94
94
|
size: size === 'xs' ? 5 : size === 'sm' ? 4 : 3
|
|
@@ -10,10 +10,11 @@ require("@testing-library/jest-dom/extend-expect");
|
|
|
10
10
|
|
|
11
11
|
var _ToggleSwitch = _interopRequireDefault(require("./ToggleSwitch"));
|
|
12
12
|
|
|
13
|
+
var base = 8;
|
|
13
14
|
describe('ToggleSwitch component', function () {
|
|
14
15
|
it('should render with default properties', function () {
|
|
15
16
|
var _render = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_ToggleSwitch["default"], {
|
|
16
|
-
|
|
17
|
+
isChecked: false,
|
|
17
18
|
label: "Toggle me",
|
|
18
19
|
onClick: function onClick() {}
|
|
19
20
|
})),
|
|
@@ -26,7 +27,7 @@ describe('ToggleSwitch component', function () {
|
|
|
26
27
|
var mockOnClick = jest.fn();
|
|
27
28
|
|
|
28
29
|
var _render2 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_ToggleSwitch["default"], {
|
|
29
|
-
|
|
30
|
+
isChecked: false,
|
|
30
31
|
label: "Toggle me",
|
|
31
32
|
onClick: mockOnClick
|
|
32
33
|
})),
|
|
@@ -42,7 +43,7 @@ describe('ToggleSwitch component', function () {
|
|
|
42
43
|
var label = 'Toggle me';
|
|
43
44
|
|
|
44
45
|
var _render3 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_ToggleSwitch["default"], {
|
|
45
|
-
|
|
46
|
+
isChecked: false,
|
|
46
47
|
label: label,
|
|
47
48
|
onClick: function onClick() {}
|
|
48
49
|
})),
|
|
@@ -50,12 +51,12 @@ describe('ToggleSwitch component', function () {
|
|
|
50
51
|
|
|
51
52
|
expect(getByText(label)).toBeInTheDocument();
|
|
52
53
|
});
|
|
53
|
-
it('should apply active color when
|
|
54
|
+
it('should apply active color when isChecked is true', function () {
|
|
54
55
|
var activeColor = 'green';
|
|
55
56
|
|
|
56
57
|
var _render4 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_ToggleSwitch["default"], {
|
|
57
58
|
backgroundColor: activeColor,
|
|
58
|
-
|
|
59
|
+
isChecked: true,
|
|
59
60
|
label: "Toggle me",
|
|
60
61
|
onClick: function onClick() {}
|
|
61
62
|
})),
|
|
@@ -64,4 +65,62 @@ describe('ToggleSwitch component', function () {
|
|
|
64
65
|
var toggleButton = getByRole('button');
|
|
65
66
|
expect(toggleButton).toHaveStyle("background-color: " + activeColor);
|
|
66
67
|
});
|
|
68
|
+
it('should not be clickable when disabled', function () {
|
|
69
|
+
var mockOnClick = jest.fn();
|
|
70
|
+
|
|
71
|
+
var _render5 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_ToggleSwitch["default"], {
|
|
72
|
+
disabled: true,
|
|
73
|
+
isChecked: false,
|
|
74
|
+
label: "Toggle me",
|
|
75
|
+
onClick: mockOnClick
|
|
76
|
+
})),
|
|
77
|
+
getByRole = _render5.getByRole;
|
|
78
|
+
|
|
79
|
+
var toggleButton = getByRole('button');
|
|
80
|
+
|
|
81
|
+
_react2.fireEvent.click(toggleButton);
|
|
82
|
+
|
|
83
|
+
expect(mockOnClick).not.toHaveBeenCalled();
|
|
84
|
+
});
|
|
85
|
+
describe('it should apply the correct size', function () {
|
|
86
|
+
it("should apply the correct size for xs", function () {
|
|
87
|
+
var _render6 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_ToggleSwitch["default"], {
|
|
88
|
+
isChecked: false,
|
|
89
|
+
label: "Toggle me",
|
|
90
|
+
onClick: function onClick() {},
|
|
91
|
+
size: "xs"
|
|
92
|
+
})),
|
|
93
|
+
getByRole = _render6.getByRole;
|
|
94
|
+
|
|
95
|
+
var toggleButton = getByRole('button');
|
|
96
|
+
expect(toggleButton).toHaveStyle("height: " + base * 2 + "px");
|
|
97
|
+
expect(toggleButton).toHaveStyle("width: " + base * 3.5 + "px");
|
|
98
|
+
});
|
|
99
|
+
it("should apply the correct size for sm", function () {
|
|
100
|
+
var _render7 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_ToggleSwitch["default"], {
|
|
101
|
+
isChecked: false,
|
|
102
|
+
label: "Toggle me",
|
|
103
|
+
onClick: function onClick() {},
|
|
104
|
+
size: "sm"
|
|
105
|
+
})),
|
|
106
|
+
getByRole = _render7.getByRole;
|
|
107
|
+
|
|
108
|
+
var toggleButton = getByRole('button');
|
|
109
|
+
expect(toggleButton).toHaveStyle("height: " + base * 2.25 + "px");
|
|
110
|
+
expect(toggleButton).toHaveStyle("width: " + base * 4 + "px");
|
|
111
|
+
});
|
|
112
|
+
it("should apply the correct default size (md)", function () {
|
|
113
|
+
var _render8 = (0, _react2.render)( /*#__PURE__*/_react["default"].createElement(_ToggleSwitch["default"], {
|
|
114
|
+
isChecked: false,
|
|
115
|
+
label: "Toggle me",
|
|
116
|
+
onClick: function onClick() {},
|
|
117
|
+
size: "md"
|
|
118
|
+
})),
|
|
119
|
+
getByRole = _render8.getByRole;
|
|
120
|
+
|
|
121
|
+
var toggleButton = getByRole('button');
|
|
122
|
+
expect(toggleButton).toHaveStyle("height: " + base * 2.5 + "px");
|
|
123
|
+
expect(toggleButton).toHaveStyle("width: " + base * 4.375 + "px");
|
|
124
|
+
});
|
|
125
|
+
});
|
|
67
126
|
});
|
|
@@ -171,12 +171,16 @@ export function Button(_ref) {
|
|
|
171
171
|
}
|
|
172
172
|
|
|
173
173
|
if (disabled) {
|
|
174
|
-
var
|
|
174
|
+
var themeData = buttonThemes[theme];
|
|
175
175
|
|
|
176
|
-
if (
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
176
|
+
if (themeData) {
|
|
177
|
+
var variantData = themeData[variant];
|
|
178
|
+
|
|
179
|
+
if (variantData && variantData.disabled) {
|
|
180
|
+
buttonProps = _objectSpread(_objectSpread({}, buttonProps), variantData.disabled);
|
|
181
|
+
} else {
|
|
182
|
+
buttonProps.opacity = 0.65;
|
|
183
|
+
}
|
|
180
184
|
}
|
|
181
185
|
|
|
182
186
|
buttonProps['aria-disabled'] = true;
|
|
@@ -260,47 +260,47 @@ var TimeField = function TimeField(_ref) {
|
|
|
260
260
|
ref: ref,
|
|
261
261
|
inline: true
|
|
262
262
|
}, restProps), /*#__PURE__*/React.createElement(NumberField, {
|
|
263
|
+
"aria-label": "Hours",
|
|
263
264
|
autoWidth: false,
|
|
264
265
|
fontVariantNumeric: "tabular-nums",
|
|
265
|
-
moveFocusOnMax: true,
|
|
266
|
-
value: hoursDisplay,
|
|
267
|
-
min: 0,
|
|
268
|
-
max: twelveHourClock ? 12 : 23,
|
|
269
|
-
pad: 2,
|
|
270
266
|
grow: 0,
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
267
|
+
max: twelveHourClock ? 12 : 23,
|
|
268
|
+
min: 0,
|
|
269
|
+
moveFocusOnMax: true,
|
|
270
|
+
onBlur: handleHoursBlur,
|
|
274
271
|
onChange: handleHoursChange,
|
|
275
272
|
onKeyDown: handleHoursKeyDown,
|
|
276
|
-
|
|
273
|
+
pad: 2,
|
|
274
|
+
textAlign: "center",
|
|
275
|
+
value: hoursDisplay,
|
|
276
|
+
width: "2ch",
|
|
277
277
|
ignoredKeys: ignoredKeys
|
|
278
278
|
}), _ref2, /*#__PURE__*/React.createElement(NumberField, {
|
|
279
|
+
"aria-label": "Minutes",
|
|
279
280
|
autoWidth: false,
|
|
280
281
|
fontVariantNumeric: "tabular-nums",
|
|
281
|
-
moveFocusOnMax: true,
|
|
282
|
-
value: minutes,
|
|
283
|
-
min: 0,
|
|
284
|
-
max: 59,
|
|
285
|
-
pad: 2,
|
|
286
282
|
grow: 0,
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
283
|
+
max: 59,
|
|
284
|
+
min: 0,
|
|
285
|
+
moveFocusOnMax: true,
|
|
290
286
|
onChange: function onChange(e) {
|
|
291
287
|
return setMinutes(e);
|
|
292
288
|
},
|
|
293
289
|
onKeyDown: handleMinutesKeyDown,
|
|
290
|
+
pad: 2,
|
|
291
|
+
textAlign: "center",
|
|
292
|
+
value: minutes,
|
|
293
|
+
width: "2ch",
|
|
294
294
|
ignoredKeys: ignoredKeys
|
|
295
295
|
}), twelveHourClock && /*#__PURE__*/React.createElement(InputField, {
|
|
296
|
-
highlightOnInteraction: true,
|
|
297
|
-
value: meridiem,
|
|
298
|
-
grow: 0,
|
|
299
|
-
width: "2em",
|
|
300
|
-
textAlign: "center",
|
|
301
296
|
"aria-label": "AM/PM",
|
|
297
|
+
grow: 0,
|
|
298
|
+
highlightOnInteraction: true,
|
|
302
299
|
onChange: noop,
|
|
303
|
-
onKeyDown: handleAMPMKeyDown
|
|
300
|
+
onKeyDown: handleAMPMKeyDown,
|
|
301
|
+
textAlign: "center",
|
|
302
|
+
value: meridiem,
|
|
303
|
+
width: "2em"
|
|
304
304
|
}));
|
|
305
305
|
};
|
|
306
306
|
|
|
@@ -10,13 +10,13 @@ import { useThemeProps } from '../system';
|
|
|
10
10
|
export function ToggleSwitch(props) {
|
|
11
11
|
var _props$disabled = props.disabled,
|
|
12
12
|
disabled = _props$disabled === void 0 ? false : _props$disabled,
|
|
13
|
-
|
|
13
|
+
isChecked = props.isChecked,
|
|
14
14
|
label = props.label,
|
|
15
15
|
onClick = props.onClick,
|
|
16
16
|
_props$size = props.size,
|
|
17
17
|
size = _props$size === void 0 ? 'md' : _props$size,
|
|
18
18
|
tooltip = props.tooltip,
|
|
19
|
-
restProps = _objectWithoutPropertiesLoose(props, ["disabled", "
|
|
19
|
+
restProps = _objectWithoutPropertiesLoose(props, ["disabled", "isChecked", "label", "onClick", "size", "tooltip"]);
|
|
20
20
|
|
|
21
21
|
var _useThemeProps = useThemeProps('toggleSwitch', restProps),
|
|
22
22
|
backgroundColor = _useThemeProps.backgroundColor;
|
|
@@ -56,7 +56,7 @@ export function ToggleSwitch(props) {
|
|
|
56
56
|
spacing: size === 'xs' ? 0.5 : size === 'sm' ? 0.75 : 1
|
|
57
57
|
}, /*#__PURE__*/React.createElement(Button, _extends({
|
|
58
58
|
as: "button",
|
|
59
|
-
backgroundColor: disabled ? colors.grays.light.neutral81 :
|
|
59
|
+
backgroundColor: disabled ? colors.grays.light.neutral81 : isChecked ? backgroundColor : colors.grays.light.neutral62,
|
|
60
60
|
onClick: onClick,
|
|
61
61
|
opacity: 1,
|
|
62
62
|
position: "relative",
|
|
@@ -64,14 +64,14 @@ export function ToggleSwitch(props) {
|
|
|
64
64
|
theme: false,
|
|
65
65
|
disabled: disabled,
|
|
66
66
|
tooltip: tooltip
|
|
67
|
-
}, toggleButtonProps
|
|
67
|
+
}, toggleButtonProps), /*#__PURE__*/React.createElement(Box, _extends({
|
|
68
68
|
background: "#fff",
|
|
69
69
|
left: 0.25,
|
|
70
70
|
pointerEvents: "none",
|
|
71
71
|
position: "absolute",
|
|
72
72
|
radius: "circle",
|
|
73
73
|
top: 0.25,
|
|
74
|
-
transform: "translateX(" + (
|
|
74
|
+
transform: "translateX(" + (isChecked ? 'calc(100% - 1px)' : '0%') + ")",
|
|
75
75
|
transition: "120ms"
|
|
76
76
|
}, toggleNotchProps))), label && /*#__PURE__*/React.createElement(Text, {
|
|
77
77
|
size: size === 'xs' ? 5 : size === 'sm' ? 4 : 3
|
|
@@ -2,10 +2,11 @@ import React from 'react';
|
|
|
2
2
|
import { render, fireEvent } from '@testing-library/react';
|
|
3
3
|
import '@testing-library/jest-dom/extend-expect';
|
|
4
4
|
import ToggleSwitch from './ToggleSwitch';
|
|
5
|
+
var base = 8;
|
|
5
6
|
describe('ToggleSwitch component', function () {
|
|
6
7
|
it('should render with default properties', function () {
|
|
7
8
|
var _render = render( /*#__PURE__*/React.createElement(ToggleSwitch, {
|
|
8
|
-
|
|
9
|
+
isChecked: false,
|
|
9
10
|
label: "Toggle me",
|
|
10
11
|
onClick: function onClick() {}
|
|
11
12
|
})),
|
|
@@ -18,7 +19,7 @@ describe('ToggleSwitch component', function () {
|
|
|
18
19
|
var mockOnClick = jest.fn();
|
|
19
20
|
|
|
20
21
|
var _render2 = render( /*#__PURE__*/React.createElement(ToggleSwitch, {
|
|
21
|
-
|
|
22
|
+
isChecked: false,
|
|
22
23
|
label: "Toggle me",
|
|
23
24
|
onClick: mockOnClick
|
|
24
25
|
})),
|
|
@@ -32,7 +33,7 @@ describe('ToggleSwitch component', function () {
|
|
|
32
33
|
var label = 'Toggle me';
|
|
33
34
|
|
|
34
35
|
var _render3 = render( /*#__PURE__*/React.createElement(ToggleSwitch, {
|
|
35
|
-
|
|
36
|
+
isChecked: false,
|
|
36
37
|
label: label,
|
|
37
38
|
onClick: function onClick() {}
|
|
38
39
|
})),
|
|
@@ -40,12 +41,12 @@ describe('ToggleSwitch component', function () {
|
|
|
40
41
|
|
|
41
42
|
expect(getByText(label)).toBeInTheDocument();
|
|
42
43
|
});
|
|
43
|
-
it('should apply active color when
|
|
44
|
+
it('should apply active color when isChecked is true', function () {
|
|
44
45
|
var activeColor = 'green';
|
|
45
46
|
|
|
46
47
|
var _render4 = render( /*#__PURE__*/React.createElement(ToggleSwitch, {
|
|
47
48
|
backgroundColor: activeColor,
|
|
48
|
-
|
|
49
|
+
isChecked: true,
|
|
49
50
|
label: "Toggle me",
|
|
50
51
|
onClick: function onClick() {}
|
|
51
52
|
})),
|
|
@@ -54,4 +55,60 @@ describe('ToggleSwitch component', function () {
|
|
|
54
55
|
var toggleButton = getByRole('button');
|
|
55
56
|
expect(toggleButton).toHaveStyle("background-color: " + activeColor);
|
|
56
57
|
});
|
|
58
|
+
it('should not be clickable when disabled', function () {
|
|
59
|
+
var mockOnClick = jest.fn();
|
|
60
|
+
|
|
61
|
+
var _render5 = render( /*#__PURE__*/React.createElement(ToggleSwitch, {
|
|
62
|
+
disabled: true,
|
|
63
|
+
isChecked: false,
|
|
64
|
+
label: "Toggle me",
|
|
65
|
+
onClick: mockOnClick
|
|
66
|
+
})),
|
|
67
|
+
getByRole = _render5.getByRole;
|
|
68
|
+
|
|
69
|
+
var toggleButton = getByRole('button');
|
|
70
|
+
fireEvent.click(toggleButton);
|
|
71
|
+
expect(mockOnClick).not.toHaveBeenCalled();
|
|
72
|
+
});
|
|
73
|
+
describe('it should apply the correct size', function () {
|
|
74
|
+
it("should apply the correct size for xs", function () {
|
|
75
|
+
var _render6 = render( /*#__PURE__*/React.createElement(ToggleSwitch, {
|
|
76
|
+
isChecked: false,
|
|
77
|
+
label: "Toggle me",
|
|
78
|
+
onClick: function onClick() {},
|
|
79
|
+
size: "xs"
|
|
80
|
+
})),
|
|
81
|
+
getByRole = _render6.getByRole;
|
|
82
|
+
|
|
83
|
+
var toggleButton = getByRole('button');
|
|
84
|
+
expect(toggleButton).toHaveStyle("height: " + base * 2 + "px");
|
|
85
|
+
expect(toggleButton).toHaveStyle("width: " + base * 3.5 + "px");
|
|
86
|
+
});
|
|
87
|
+
it("should apply the correct size for sm", function () {
|
|
88
|
+
var _render7 = render( /*#__PURE__*/React.createElement(ToggleSwitch, {
|
|
89
|
+
isChecked: false,
|
|
90
|
+
label: "Toggle me",
|
|
91
|
+
onClick: function onClick() {},
|
|
92
|
+
size: "sm"
|
|
93
|
+
})),
|
|
94
|
+
getByRole = _render7.getByRole;
|
|
95
|
+
|
|
96
|
+
var toggleButton = getByRole('button');
|
|
97
|
+
expect(toggleButton).toHaveStyle("height: " + base * 2.25 + "px");
|
|
98
|
+
expect(toggleButton).toHaveStyle("width: " + base * 4 + "px");
|
|
99
|
+
});
|
|
100
|
+
it("should apply the correct default size (md)", function () {
|
|
101
|
+
var _render8 = render( /*#__PURE__*/React.createElement(ToggleSwitch, {
|
|
102
|
+
isChecked: false,
|
|
103
|
+
label: "Toggle me",
|
|
104
|
+
onClick: function onClick() {},
|
|
105
|
+
size: "md"
|
|
106
|
+
})),
|
|
107
|
+
getByRole = _render8.getByRole;
|
|
108
|
+
|
|
109
|
+
var toggleButton = getByRole('button');
|
|
110
|
+
expect(toggleButton).toHaveStyle("height: " + base * 2.5 + "px");
|
|
111
|
+
expect(toggleButton).toHaveStyle("width: " + base * 4.375 + "px");
|
|
112
|
+
});
|
|
113
|
+
});
|
|
57
114
|
});
|
|
@@ -6,8 +6,8 @@ export declare type ToggleSwitchProps = {
|
|
|
6
6
|
backgroundColor?: string;
|
|
7
7
|
/** Whether the toggle is disabled. */
|
|
8
8
|
disabled?: boolean;
|
|
9
|
-
/** Whether the toggle is
|
|
10
|
-
|
|
9
|
+
/** Whether the toggle is checked. */
|
|
10
|
+
isChecked: boolean;
|
|
11
11
|
/** The label for the toggle. */
|
|
12
12
|
label: string;
|
|
13
13
|
/** The function to call when the toggle is clicked. */
|
|
@@ -17,6 +17,6 @@ export declare type ToggleSwitchProps = {
|
|
|
17
17
|
/** The tooltip to display when the toggle is hovered. */
|
|
18
18
|
tooltip?: string;
|
|
19
19
|
} & StackViewProps;
|
|
20
|
-
declare type Props = React.RefAttributes<any> &
|
|
20
|
+
declare type Props = React.RefAttributes<any> & ToggleSwitchProps & MediaQueries<ToggleSwitchProps>;
|
|
21
21
|
export declare function ToggleSwitch(props: Props): JSX.Element;
|
|
22
22
|
export default ToggleSwitch;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/tapestry-react",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "v2.9.0-rc.8",
|
|
4
4
|
"description": "A collection of flexible React components to help you build resilient, accessible user interfaces quickly and effectively.",
|
|
5
5
|
"author": "Front End Systems Engineering <frontend@pco.bz>",
|
|
6
6
|
"main": "dist/cjs/index.js",
|
package/src/Button/Button.tsx
CHANGED
|
@@ -260,15 +260,14 @@ export function Button({
|
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
if (disabled) {
|
|
263
|
-
const
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
...buttonProps,
|
|
268
|
-
|
|
263
|
+
const themeData = buttonThemes[theme]
|
|
264
|
+
if (themeData) {
|
|
265
|
+
const variantData = themeData[variant]
|
|
266
|
+
if (variantData && variantData.disabled) {
|
|
267
|
+
buttonProps = { ...buttonProps, ...variantData.disabled }
|
|
268
|
+
} else {
|
|
269
|
+
buttonProps.opacity = 0.65
|
|
269
270
|
}
|
|
270
|
-
} else {
|
|
271
|
-
buttonProps.opacity = 0.65
|
|
272
271
|
}
|
|
273
272
|
|
|
274
273
|
buttonProps['aria-disabled'] = true
|
|
@@ -280,51 +280,51 @@ const TimeField = ({
|
|
|
280
280
|
) : (
|
|
281
281
|
<InputBox ref={ref} inline {...restProps}>
|
|
282
282
|
<NumberField
|
|
283
|
+
aria-label="Hours"
|
|
283
284
|
autoWidth={false}
|
|
284
285
|
fontVariantNumeric="tabular-nums"
|
|
285
|
-
moveFocusOnMax
|
|
286
|
-
value={hoursDisplay}
|
|
287
|
-
min={0}
|
|
288
|
-
max={twelveHourClock ? 12 : 23}
|
|
289
|
-
pad={2}
|
|
290
286
|
grow={0}
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
287
|
+
max={twelveHourClock ? 12 : 23}
|
|
288
|
+
min={0}
|
|
289
|
+
moveFocusOnMax
|
|
290
|
+
onBlur={handleHoursBlur}
|
|
294
291
|
onChange={handleHoursChange}
|
|
295
292
|
onKeyDown={handleHoursKeyDown}
|
|
296
|
-
|
|
293
|
+
pad={2}
|
|
294
|
+
textAlign="center"
|
|
295
|
+
value={hoursDisplay}
|
|
296
|
+
width="2ch"
|
|
297
297
|
{...{ ignoredKeys }}
|
|
298
298
|
/>
|
|
299
299
|
<Box as="span" width={0.5} textAlign="center" userSelect="none">
|
|
300
300
|
:
|
|
301
301
|
</Box>
|
|
302
302
|
<NumberField
|
|
303
|
+
aria-label="Minutes"
|
|
303
304
|
autoWidth={false}
|
|
304
305
|
fontVariantNumeric="tabular-nums"
|
|
305
|
-
moveFocusOnMax
|
|
306
|
-
value={minutes}
|
|
307
|
-
min={0}
|
|
308
|
-
max={59}
|
|
309
|
-
pad={2}
|
|
310
306
|
grow={0}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
307
|
+
max={59}
|
|
308
|
+
min={0}
|
|
309
|
+
moveFocusOnMax
|
|
314
310
|
onChange={(e) => setMinutes(e)}
|
|
315
311
|
onKeyDown={handleMinutesKeyDown}
|
|
312
|
+
pad={2}
|
|
313
|
+
textAlign="center"
|
|
314
|
+
value={minutes}
|
|
315
|
+
width="2ch"
|
|
316
316
|
{...{ ignoredKeys }}
|
|
317
317
|
/>
|
|
318
318
|
{twelveHourClock && (
|
|
319
319
|
<InputField
|
|
320
|
-
highlightOnInteraction
|
|
321
|
-
value={meridiem}
|
|
322
|
-
grow={0}
|
|
323
|
-
width="2em"
|
|
324
|
-
textAlign="center"
|
|
325
320
|
aria-label="AM/PM"
|
|
321
|
+
grow={0}
|
|
322
|
+
highlightOnInteraction
|
|
326
323
|
onChange={noop}
|
|
327
324
|
onKeyDown={handleAMPMKeyDown}
|
|
325
|
+
textAlign="center"
|
|
326
|
+
value={meridiem}
|
|
327
|
+
width="2em"
|
|
328
328
|
/>
|
|
329
329
|
)}
|
|
330
330
|
</InputBox>
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
title: ToggleSwitch
|
|
3
3
|
category: General
|
|
4
4
|
summary: ToggleSwitches are used to switch between two states, most commonly on and off, and visually show the current state.
|
|
5
|
-
propsSummary: Accepts [StackView](/stackview) props.
|
|
6
5
|
themeKey: toggleSwitch
|
|
6
|
+
uxCompliant: true
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
```jsx live
|
|
@@ -20,19 +20,19 @@ render(
|
|
|
20
20
|
))}
|
|
21
21
|
</StackView>
|
|
22
22
|
<StackView axis="horizontal" spacing={2}>
|
|
23
|
-
<ToggleSwitch
|
|
23
|
+
<ToggleSwitch isChecked label="On" tooltip="On" />
|
|
24
24
|
<ToggleSwitch disabled label="Disabled, off" tooltip="Disabled, off" />
|
|
25
25
|
<ToggleSwitch
|
|
26
26
|
disabled
|
|
27
|
-
|
|
27
|
+
isChecked
|
|
28
28
|
label="Disabled, On"
|
|
29
29
|
tooltip="Disabled, On"
|
|
30
30
|
/>
|
|
31
31
|
</StackView>
|
|
32
32
|
<StackView axis="horizontal" spacing={2}>
|
|
33
|
-
<ToggleSwitch
|
|
33
|
+
<ToggleSwitch backgroundColor="red-5" isChecked label="Custom color" />
|
|
34
34
|
<ThemeProvider theme={{ toggleSwitch: { backgroundColor: 'create35' } }}>
|
|
35
|
-
<ToggleSwitch
|
|
35
|
+
<ToggleSwitch isChecked label="Theme-provided color" />
|
|
36
36
|
</ThemeProvider>
|
|
37
37
|
</StackView>
|
|
38
38
|
</StackView>
|
|
@@ -41,13 +41,13 @@ render(
|
|
|
41
41
|
|
|
42
42
|
```jsx live
|
|
43
43
|
function App() {
|
|
44
|
-
const [
|
|
44
|
+
const [isChecked, setIsChecked] = React.useState(false)
|
|
45
45
|
return (
|
|
46
46
|
<StackView>
|
|
47
47
|
<ToggleSwitch
|
|
48
|
-
|
|
48
|
+
isChecked={isChecked}
|
|
49
49
|
label="Controlled toggle"
|
|
50
|
-
onClick={() =>
|
|
50
|
+
onClick={() => setIsChecked(!isChecked)}
|
|
51
51
|
/>
|
|
52
52
|
</StackView>
|
|
53
53
|
)
|
|
@@ -3,10 +3,12 @@ import { render, fireEvent } from '@testing-library/react'
|
|
|
3
3
|
import '@testing-library/jest-dom/extend-expect'
|
|
4
4
|
import ToggleSwitch from './ToggleSwitch'
|
|
5
5
|
|
|
6
|
+
const base = 8
|
|
7
|
+
|
|
6
8
|
describe('ToggleSwitch component', () => {
|
|
7
9
|
it('should render with default properties', () => {
|
|
8
10
|
const { getByRole } = render(
|
|
9
|
-
<ToggleSwitch
|
|
11
|
+
<ToggleSwitch isChecked={false} label="Toggle me" onClick={() => {}} />
|
|
10
12
|
)
|
|
11
13
|
|
|
12
14
|
const toggleButton = getByRole('button')
|
|
@@ -16,7 +18,7 @@ describe('ToggleSwitch component', () => {
|
|
|
16
18
|
it('should call onClick when clicked', () => {
|
|
17
19
|
const mockOnClick = jest.fn()
|
|
18
20
|
const { getByRole } = render(
|
|
19
|
-
<ToggleSwitch
|
|
21
|
+
<ToggleSwitch isChecked={false} label="Toggle me" onClick={mockOnClick} />
|
|
20
22
|
)
|
|
21
23
|
|
|
22
24
|
const toggleButton = getByRole('button')
|
|
@@ -28,18 +30,18 @@ describe('ToggleSwitch component', () => {
|
|
|
28
30
|
it('should display the label', () => {
|
|
29
31
|
const label = 'Toggle me'
|
|
30
32
|
const { getByText } = render(
|
|
31
|
-
<ToggleSwitch
|
|
33
|
+
<ToggleSwitch isChecked={false} label={label} onClick={() => {}} />
|
|
32
34
|
)
|
|
33
35
|
|
|
34
36
|
expect(getByText(label)).toBeInTheDocument()
|
|
35
37
|
})
|
|
36
38
|
|
|
37
|
-
it('should apply active color when
|
|
39
|
+
it('should apply active color when isChecked is true', () => {
|
|
38
40
|
const activeColor = 'green'
|
|
39
41
|
const { getByRole } = render(
|
|
40
42
|
<ToggleSwitch
|
|
41
43
|
backgroundColor={activeColor}
|
|
42
|
-
|
|
44
|
+
isChecked={true}
|
|
43
45
|
label="Toggle me"
|
|
44
46
|
onClick={() => {}}
|
|
45
47
|
/>
|
|
@@ -48,4 +50,66 @@ describe('ToggleSwitch component', () => {
|
|
|
48
50
|
const toggleButton = getByRole('button')
|
|
49
51
|
expect(toggleButton).toHaveStyle(`background-color: ${activeColor}`)
|
|
50
52
|
})
|
|
53
|
+
|
|
54
|
+
it('should not be clickable when disabled', () => {
|
|
55
|
+
const mockOnClick = jest.fn()
|
|
56
|
+
const { getByRole } = render(
|
|
57
|
+
<ToggleSwitch
|
|
58
|
+
disabled={true}
|
|
59
|
+
isChecked={false}
|
|
60
|
+
label="Toggle me"
|
|
61
|
+
onClick={mockOnClick}
|
|
62
|
+
/>
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
const toggleButton = getByRole('button')
|
|
66
|
+
fireEvent.click(toggleButton)
|
|
67
|
+
|
|
68
|
+
expect(mockOnClick).not.toHaveBeenCalled()
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
describe('it should apply the correct size', () => {
|
|
72
|
+
it(`should apply the correct size for xs`, () => {
|
|
73
|
+
const { getByRole } = render(
|
|
74
|
+
<ToggleSwitch
|
|
75
|
+
isChecked={false}
|
|
76
|
+
label="Toggle me"
|
|
77
|
+
onClick={() => {}}
|
|
78
|
+
size="xs"
|
|
79
|
+
/>
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
const toggleButton = getByRole('button')
|
|
83
|
+
expect(toggleButton).toHaveStyle(`height: ${base * 2}px`)
|
|
84
|
+
expect(toggleButton).toHaveStyle(`width: ${base * 3.5}px`)
|
|
85
|
+
})
|
|
86
|
+
it(`should apply the correct size for sm`, () => {
|
|
87
|
+
const { getByRole } = render(
|
|
88
|
+
<ToggleSwitch
|
|
89
|
+
isChecked={false}
|
|
90
|
+
label="Toggle me"
|
|
91
|
+
onClick={() => {}}
|
|
92
|
+
size="sm"
|
|
93
|
+
/>
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
const toggleButton = getByRole('button')
|
|
97
|
+
expect(toggleButton).toHaveStyle(`height: ${base * 2.25}px`)
|
|
98
|
+
expect(toggleButton).toHaveStyle(`width: ${base * 4}px`)
|
|
99
|
+
})
|
|
100
|
+
it(`should apply the correct default size (md)`, () => {
|
|
101
|
+
const { getByRole } = render(
|
|
102
|
+
<ToggleSwitch
|
|
103
|
+
isChecked={false}
|
|
104
|
+
label="Toggle me"
|
|
105
|
+
onClick={() => {}}
|
|
106
|
+
size="md"
|
|
107
|
+
/>
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
const toggleButton = getByRole('button')
|
|
111
|
+
expect(toggleButton).toHaveStyle(`height: ${base * 2.5}px`)
|
|
112
|
+
expect(toggleButton).toHaveStyle(`width: ${base * 4.375}px`)
|
|
113
|
+
})
|
|
114
|
+
})
|
|
51
115
|
})
|
|
@@ -15,8 +15,8 @@ export type ToggleSwitchProps = {
|
|
|
15
15
|
/** Whether the toggle is disabled. */
|
|
16
16
|
disabled?: boolean
|
|
17
17
|
|
|
18
|
-
/** Whether the toggle is
|
|
19
|
-
|
|
18
|
+
/** Whether the toggle is checked. */
|
|
19
|
+
isChecked: boolean
|
|
20
20
|
|
|
21
21
|
/** The label for the toggle. */
|
|
22
22
|
label: string
|
|
@@ -32,14 +32,13 @@ export type ToggleSwitchProps = {
|
|
|
32
32
|
} & StackViewProps
|
|
33
33
|
|
|
34
34
|
type Props = React.RefAttributes<any> &
|
|
35
|
-
React.HTMLAttributes<any> &
|
|
36
35
|
ToggleSwitchProps &
|
|
37
36
|
MediaQueries<ToggleSwitchProps>
|
|
38
37
|
|
|
39
38
|
export function ToggleSwitch(props: Props) {
|
|
40
39
|
const {
|
|
41
40
|
disabled = false,
|
|
42
|
-
|
|
41
|
+
isChecked,
|
|
43
42
|
label,
|
|
44
43
|
onClick,
|
|
45
44
|
size = 'md',
|
|
@@ -71,7 +70,7 @@ export function ToggleSwitch(props: Props) {
|
|
|
71
70
|
backgroundColor={
|
|
72
71
|
disabled
|
|
73
72
|
? colors.grays.light.neutral81
|
|
74
|
-
:
|
|
73
|
+
: isChecked
|
|
75
74
|
? backgroundColor
|
|
76
75
|
: colors.grays.light.neutral62
|
|
77
76
|
}
|
|
@@ -82,7 +81,6 @@ export function ToggleSwitch(props: Props) {
|
|
|
82
81
|
theme={false}
|
|
83
82
|
{...{ disabled, tooltip }}
|
|
84
83
|
{...toggleButtonProps}
|
|
85
|
-
{...restProps}
|
|
86
84
|
>
|
|
87
85
|
<Box
|
|
88
86
|
background="#fff"
|
|
@@ -91,7 +89,7 @@ export function ToggleSwitch(props: Props) {
|
|
|
91
89
|
position="absolute"
|
|
92
90
|
radius="circle"
|
|
93
91
|
top={0.25}
|
|
94
|
-
transform={`translateX(${
|
|
92
|
+
transform={`translateX(${isChecked ? 'calc(100% - 1px)' : '0%'})`}
|
|
95
93
|
transition="120ms"
|
|
96
94
|
{...toggleNotchProps}
|
|
97
95
|
/>
|