@pingux/astro 2.207.0-alpha.0 → 2.207.1-alpha.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/lib/cjs/components/Checkbox/CheckboxBase.js +4 -2
- package/lib/cjs/components/CheckboxField/CheckboxField.js +18 -1
- package/lib/cjs/components/CheckboxField/CheckboxField.test.js +82 -0
- package/lib/cjs/components/LinkSelectField/LinkSelectField.js +0 -6
- package/lib/components/Checkbox/CheckboxBase.js +4 -2
- package/lib/components/CheckboxField/CheckboxField.js +19 -2
- package/lib/components/CheckboxField/CheckboxField.test.js +83 -1
- package/lib/components/LinkSelectField/LinkSelectField.js +0 -6
- package/package.json +1 -1
|
@@ -31,13 +31,14 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof _WeakMap) var
|
|
|
31
31
|
}, props));
|
|
32
32
|
});
|
|
33
33
|
var IndeterminateCheckboxIcon = function IndeterminateCheckboxIcon(props) {
|
|
34
|
+
console.log('🚀 ~ IndeterminateCheckboxIcon ~ props:', props);
|
|
34
35
|
return (0, _react2.jsx)("svg", (0, _extends2["default"])({
|
|
35
36
|
viewBox: "0 0 24 24",
|
|
36
37
|
fill: "none",
|
|
37
38
|
xmlns: "http://www.w3.org/2000/svg",
|
|
38
39
|
"aria-labelledby": "checkbox-icon-title",
|
|
39
40
|
"data-testid": "checkbox-icon-indeterminate"
|
|
40
|
-
}, (0, _lodash.omit)(props, 'id', 'aria-checked', 'data-testid')), (0, _react2.jsx)("title", {
|
|
41
|
+
}, (0, _lodash.omit)(props, 'id', 'aria-checked', 'data-testid', 'onFocus')), (0, _react2.jsx)("title", {
|
|
41
42
|
id: "checkbox-icon-title"
|
|
42
43
|
}, "Indeterminate Checkbox Icon"), (0, _react2.jsx)("rect", {
|
|
43
44
|
x: "3.5",
|
|
@@ -75,7 +76,8 @@ var IndeterminateCheckbox = /*#__PURE__*/(0, _react.forwardRef)(function (props,
|
|
|
75
76
|
variant: "variants.box.indeterminateCheckboxIcon",
|
|
76
77
|
mr: 2
|
|
77
78
|
}, props, {
|
|
78
|
-
opacity: 1
|
|
79
|
+
opacity: 1,
|
|
80
|
+
tabIndex: -1
|
|
79
81
|
})));
|
|
80
82
|
});
|
|
81
83
|
var CheckboxBase = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
|
|
@@ -16,6 +16,7 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
16
16
|
});
|
|
17
17
|
exports["default"] = void 0;
|
|
18
18
|
var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));
|
|
19
|
+
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/objectWithoutProperties"));
|
|
19
20
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/defineProperty"));
|
|
20
21
|
var _react = _interopRequireWildcard(require("react"));
|
|
21
22
|
var _reactAria = require("react-aria");
|
|
@@ -27,6 +28,7 @@ var _hooks = require("../../hooks");
|
|
|
27
28
|
var _pendoID = require("../../utils/devUtils/constants/pendoID");
|
|
28
29
|
var _statuses = _interopRequireDefault(require("../../utils/devUtils/constants/statuses"));
|
|
29
30
|
var _react2 = require("@emotion/react");
|
|
31
|
+
var _excluded = ["onKeyDown", "onKeyUp"];
|
|
30
32
|
function _interopRequireWildcard(e, t) { if ("function" == typeof _WeakMap) var r = new _WeakMap(), n = new _WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = _Object$defineProperty) && _Object$getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
31
33
|
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
32
34
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(t), !0)).call(_context, function (r) { (0, _defineProperty2["default"])(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -56,16 +58,31 @@ var CheckboxField = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
|
|
|
56
58
|
ref: checkboxRef
|
|
57
59
|
})),
|
|
58
60
|
containerPressProps = _usePress.pressProps;
|
|
61
|
+
// usePress onKeyDown registers a global keyup listener and when isIndeterminate changes during
|
|
62
|
+
// a press, usePress creates a new state machine instance but old global keyup
|
|
63
|
+
// listener never fires cleanly and the state machine gets out of sync, causing
|
|
64
|
+
// subsequent Space presses to be ignored. The checkbox input already handles Space natively.
|
|
65
|
+
var _kd = containerPressProps.onKeyDown,
|
|
66
|
+
_ku = containerPressProps.onKeyUp,
|
|
67
|
+
safeContainerPressProps = (0, _objectWithoutProperties2["default"])(containerPressProps, _excluded);
|
|
68
|
+
var prevIsIndeterminate = (0, _react.useRef)(isIndeterminate);
|
|
59
69
|
(0, _react.useEffect)(function () {
|
|
60
70
|
if (checkboxRef.current && isIndeterminate) {
|
|
61
71
|
checkboxRef.current.indeterminate = true;
|
|
62
72
|
} else if (checkboxRef.current && !isIndeterminate) {
|
|
63
73
|
checkboxRef.current.indeterminate = false;
|
|
74
|
+
|
|
75
|
+
// Restore focus to the new input when the transition from indeterminate to default
|
|
76
|
+
// occurs and focus has landed on <body> (meaning it was on the old input before the swap).
|
|
77
|
+
if (prevIsIndeterminate.current && document.activeElement === document.body) {
|
|
78
|
+
checkboxRef.current.focus();
|
|
79
|
+
}
|
|
64
80
|
}
|
|
81
|
+
prevIsIndeterminate.current = isIndeterminate;
|
|
65
82
|
}, [isIndeterminate]);
|
|
66
83
|
var _useCheckbox = (0, _reactAria.useCheckbox)(checkboxProps, state, checkboxRef),
|
|
67
84
|
inputProps = _useCheckbox.inputProps;
|
|
68
|
-
var _useField = (0, _hooks.useField)(_objectSpread(_objectSpread(_objectSpread({},
|
|
85
|
+
var _useField = (0, _hooks.useField)(_objectSpread(_objectSpread(_objectSpread({}, safeContainerPressProps), props), {}, {
|
|
69
86
|
statusClasses: {
|
|
70
87
|
isIndeterminate: isIndeterminate
|
|
71
88
|
},
|
|
@@ -12,6 +12,7 @@ var _Promise = require("@babel/runtime-corejs3/core-js-stable/promise");
|
|
|
12
12
|
var _Symbol$iterator = require("@babel/runtime-corejs3/core-js-stable/symbol/iterator");
|
|
13
13
|
var _reverseInstanceProperty = require("@babel/runtime-corejs3/core-js-stable/instance/reverse");
|
|
14
14
|
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
|
|
15
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/slicedToArray"));
|
|
15
16
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/asyncToGenerator"));
|
|
16
17
|
var _extends2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/extends"));
|
|
17
18
|
var _react = _interopRequireDefault(require("react"));
|
|
@@ -335,4 +336,85 @@ test('indeterminate checkbox, clicking svg', /*#__PURE__*/(0, _asyncToGenerator2
|
|
|
335
336
|
return _context8.stop();
|
|
336
337
|
}
|
|
337
338
|
}, _callee8);
|
|
339
|
+
})));
|
|
340
|
+
test('controlled indeterminate checkbox retains focus and toggles correctly across keyboard Space presses', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regeneratorRuntime().mark(function _callee9() {
|
|
341
|
+
var onChange, IndeterminateParent, input, input2;
|
|
342
|
+
return _regeneratorRuntime().wrap(function _callee9$(_context9) {
|
|
343
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
344
|
+
case 0:
|
|
345
|
+
onChange = jest.fn();
|
|
346
|
+
IndeterminateParent = function IndeterminateParent() {
|
|
347
|
+
var _React$useState = _react["default"].useState(true),
|
|
348
|
+
_React$useState2 = (0, _slicedToArray2["default"])(_React$useState, 2),
|
|
349
|
+
isIndeterminate = _React$useState2[0],
|
|
350
|
+
setIsIndeterminate = _React$useState2[1];
|
|
351
|
+
var _React$useState3 = _react["default"].useState(false),
|
|
352
|
+
_React$useState4 = (0, _slicedToArray2["default"])(_React$useState3, 2),
|
|
353
|
+
isSelected = _React$useState4[0],
|
|
354
|
+
setIsSelected = _React$useState4[1];
|
|
355
|
+
var handleChange = function handleChange(selected) {
|
|
356
|
+
onChange(selected);
|
|
357
|
+
setIsIndeterminate(false);
|
|
358
|
+
setIsSelected(selected);
|
|
359
|
+
};
|
|
360
|
+
return (0, _react2.jsx)(_["default"], {
|
|
361
|
+
label: testLabel,
|
|
362
|
+
isIndeterminate: isIndeterminate,
|
|
363
|
+
isSelected: isSelected,
|
|
364
|
+
onChange: handleChange
|
|
365
|
+
});
|
|
366
|
+
};
|
|
367
|
+
(0, _testWrapper.render)((0, _react2.jsx)(IndeterminateParent, null));
|
|
368
|
+
|
|
369
|
+
// Initial: indeterminate
|
|
370
|
+
expect(_testWrapper.screen.getByRole('checkbox')).toHaveAttribute('aria-checked', 'mixed');
|
|
371
|
+
|
|
372
|
+
// First Space: focus the input, then simulate Space press
|
|
373
|
+
input = _testWrapper.screen.getByRole('checkbox');
|
|
374
|
+
(0, _testWrapper.act)(function () {
|
|
375
|
+
input.focus();
|
|
376
|
+
});
|
|
377
|
+
expect(input).toHaveFocus();
|
|
378
|
+
|
|
379
|
+
// Simulate keyboard Space: keydown triggers native change on checkbox, then keyup
|
|
380
|
+
_testWrapper.fireEvent.keyDown(input, {
|
|
381
|
+
key: ' ',
|
|
382
|
+
code: 'Space',
|
|
383
|
+
charCode: 32
|
|
384
|
+
});
|
|
385
|
+
_testWrapper.fireEvent.click(input); // keyboard Space on checkbox fires a click event in browsers
|
|
386
|
+
_testWrapper.fireEvent.keyUp(input, {
|
|
387
|
+
key: ' ',
|
|
388
|
+
code: 'Space',
|
|
389
|
+
charCode: 32
|
|
390
|
+
});
|
|
391
|
+
expect(onChange).toHaveBeenNthCalledWith(1, true);
|
|
392
|
+
// Re-query after re-render: isIndeterminate=false now
|
|
393
|
+
expect(_testWrapper.screen.getByRole('checkbox')).not.toHaveAttribute('aria-checked', 'mixed');
|
|
394
|
+
expect(_testWrapper.screen.getByRole('checkbox')).toBeChecked();
|
|
395
|
+
|
|
396
|
+
// After the indeterminate->checked transition, the input should still have focus
|
|
397
|
+
// (the old IndeterminateCheckbox input was unmounted, so focus may be lost)
|
|
398
|
+
expect(_testWrapper.screen.getByRole('checkbox')).toHaveFocus();
|
|
399
|
+
|
|
400
|
+
// Second Space: checked -> unchecked
|
|
401
|
+
input2 = _testWrapper.screen.getByRole('checkbox');
|
|
402
|
+
_testWrapper.fireEvent.keyDown(input2, {
|
|
403
|
+
key: ' ',
|
|
404
|
+
code: 'Space',
|
|
405
|
+
charCode: 32
|
|
406
|
+
});
|
|
407
|
+
_testWrapper.fireEvent.click(input2);
|
|
408
|
+
_testWrapper.fireEvent.keyUp(input2, {
|
|
409
|
+
key: ' ',
|
|
410
|
+
code: 'Space',
|
|
411
|
+
charCode: 32
|
|
412
|
+
});
|
|
413
|
+
expect(onChange).toHaveBeenNthCalledWith(2, false);
|
|
414
|
+
expect(_testWrapper.screen.getByRole('checkbox')).not.toBeChecked();
|
|
415
|
+
case 20:
|
|
416
|
+
case "end":
|
|
417
|
+
return _context9.stop();
|
|
418
|
+
}
|
|
419
|
+
}, _callee9);
|
|
338
420
|
})));
|
|
@@ -93,16 +93,10 @@ var LinkSelectField = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref)
|
|
|
93
93
|
variant: "forms.select.arrow"
|
|
94
94
|
}, (0, _react2.jsx)(_.Icon, (0, _extends2["default"])({
|
|
95
95
|
icon: MenuDown,
|
|
96
|
-
title: {
|
|
97
|
-
name: 'Menu Down Icon'
|
|
98
|
-
},
|
|
99
96
|
sx: _objectSpread(_objectSpread({}, state.isOpen ? {
|
|
100
97
|
transform: 'rotate(180deg)'
|
|
101
98
|
} : null), iconPropsSx)
|
|
102
99
|
}, restIconProps, {
|
|
103
|
-
title: {
|
|
104
|
-
name: ''
|
|
105
|
-
},
|
|
106
100
|
color: isOnyx ? 'font.link' : 'active',
|
|
107
101
|
size: linkSelectFieldIcon,
|
|
108
102
|
"aria-hidden": "true"
|
|
@@ -21,13 +21,14 @@ var DefaultCheckbox = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
21
21
|
}, props));
|
|
22
22
|
});
|
|
23
23
|
var IndeterminateCheckboxIcon = function IndeterminateCheckboxIcon(props) {
|
|
24
|
+
console.log('🚀 ~ IndeterminateCheckboxIcon ~ props:', props);
|
|
24
25
|
return ___EmotionJSX("svg", _extends({
|
|
25
26
|
viewBox: "0 0 24 24",
|
|
26
27
|
fill: "none",
|
|
27
28
|
xmlns: "http://www.w3.org/2000/svg",
|
|
28
29
|
"aria-labelledby": "checkbox-icon-title",
|
|
29
30
|
"data-testid": "checkbox-icon-indeterminate"
|
|
30
|
-
}, omit(props, 'id', 'aria-checked', 'data-testid')), ___EmotionJSX("title", {
|
|
31
|
+
}, omit(props, 'id', 'aria-checked', 'data-testid', 'onFocus')), ___EmotionJSX("title", {
|
|
31
32
|
id: "checkbox-icon-title"
|
|
32
33
|
}, "Indeterminate Checkbox Icon"), ___EmotionJSX("rect", {
|
|
33
34
|
x: "3.5",
|
|
@@ -65,7 +66,8 @@ var IndeterminateCheckbox = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
65
66
|
variant: "variants.box.indeterminateCheckboxIcon",
|
|
66
67
|
mr: 2
|
|
67
68
|
}, props, {
|
|
68
|
-
opacity: 1
|
|
69
|
+
opacity: 1,
|
|
70
|
+
tabIndex: -1
|
|
69
71
|
})));
|
|
70
72
|
});
|
|
71
73
|
var CheckboxBase = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
@@ -7,10 +7,12 @@ import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-st
|
|
|
7
7
|
import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
|
|
8
8
|
import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
|
|
9
9
|
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
|
10
|
+
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
|
10
11
|
import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
|
|
12
|
+
var _excluded = ["onKeyDown", "onKeyUp"];
|
|
11
13
|
function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
12
14
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
13
|
-
import React, { forwardRef, useEffect, useMemo } from 'react';
|
|
15
|
+
import React, { forwardRef, useEffect, useMemo, useRef } from 'react';
|
|
14
16
|
import { mergeProps, useCheckbox } from 'react-aria';
|
|
15
17
|
import { useToggleState } from 'react-stately';
|
|
16
18
|
import { usePress } from '@react-aria/interactions';
|
|
@@ -46,16 +48,31 @@ var CheckboxField = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
46
48
|
ref: checkboxRef
|
|
47
49
|
})),
|
|
48
50
|
containerPressProps = _usePress.pressProps;
|
|
51
|
+
// usePress onKeyDown registers a global keyup listener and when isIndeterminate changes during
|
|
52
|
+
// a press, usePress creates a new state machine instance but old global keyup
|
|
53
|
+
// listener never fires cleanly and the state machine gets out of sync, causing
|
|
54
|
+
// subsequent Space presses to be ignored. The checkbox input already handles Space natively.
|
|
55
|
+
var _kd = containerPressProps.onKeyDown,
|
|
56
|
+
_ku = containerPressProps.onKeyUp,
|
|
57
|
+
safeContainerPressProps = _objectWithoutProperties(containerPressProps, _excluded);
|
|
58
|
+
var prevIsIndeterminate = useRef(isIndeterminate);
|
|
49
59
|
useEffect(function () {
|
|
50
60
|
if (checkboxRef.current && isIndeterminate) {
|
|
51
61
|
checkboxRef.current.indeterminate = true;
|
|
52
62
|
} else if (checkboxRef.current && !isIndeterminate) {
|
|
53
63
|
checkboxRef.current.indeterminate = false;
|
|
64
|
+
|
|
65
|
+
// Restore focus to the new input when the transition from indeterminate to default
|
|
66
|
+
// occurs and focus has landed on <body> (meaning it was on the old input before the swap).
|
|
67
|
+
if (prevIsIndeterminate.current && document.activeElement === document.body) {
|
|
68
|
+
checkboxRef.current.focus();
|
|
69
|
+
}
|
|
54
70
|
}
|
|
71
|
+
prevIsIndeterminate.current = isIndeterminate;
|
|
55
72
|
}, [isIndeterminate]);
|
|
56
73
|
var _useCheckbox = useCheckbox(checkboxProps, state, checkboxRef),
|
|
57
74
|
inputProps = _useCheckbox.inputProps;
|
|
58
|
-
var _useField = useField(_objectSpread(_objectSpread(_objectSpread({},
|
|
75
|
+
var _useField = useField(_objectSpread(_objectSpread(_objectSpread({}, safeContainerPressProps), props), {}, {
|
|
59
76
|
statusClasses: {
|
|
60
77
|
isIndeterminate: isIndeterminate
|
|
61
78
|
},
|
|
@@ -9,6 +9,7 @@ import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
|
|
|
9
9
|
import _Symbol$iterator from "@babel/runtime-corejs3/core-js-stable/symbol/iterator";
|
|
10
10
|
import _reverseInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/reverse";
|
|
11
11
|
import _typeof from "@babel/runtime-corejs3/helpers/esm/typeof";
|
|
12
|
+
import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
|
|
12
13
|
import _asyncToGenerator from "@babel/runtime-corejs3/helpers/esm/asyncToGenerator";
|
|
13
14
|
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
|
14
15
|
function _regeneratorRuntime() { "use strict"; var r = _regenerator(), e = r.m(_regeneratorRuntime), t = (_Object$getPrototypeOf ? _Object$getPrototypeOf(e) : e.__proto__).constructor; function n(r) { var e = "function" == typeof r && r.constructor; return !!e && (e === t || "GeneratorFunction" === (e.displayName || e.name)); } var o = { "throw": 1, "return": 2, "break": 3, "continue": 3 }; function a(r) { var e, t; return function (n) { e || (e = { stop: function stop() { return t(n.a, 2); }, "catch": function _catch() { return n.v; }, abrupt: function abrupt(r, e) { return t(n.a, o[r], e); }, delegateYield: function delegateYield(r, o, a) { return e.resultName = o, t(n.d, _regeneratorValues(r), a); }, finish: function finish(r) { return t(n.f, r); } }, t = function t(r, _t, o) { n.p = e.prev, n.n = e.next; try { return r(_t, o); } finally { e.next = n.n; } }), e.resultName && (e[e.resultName] = n.v, e.resultName = void 0), e.sent = n.v, e.next = n.n; try { return r.call(this, e); } finally { n.p = e.prev, n.n = e.next; } }; } return (_regeneratorRuntime = function _regeneratorRuntime() { return { wrap: function wrap(e, t, n, o) { return r.w(a(e), t, n, o && _reverseInstanceProperty(o).call(o)); }, isGeneratorFunction: n, mark: r.m, awrap: function awrap(r, e) { return new _OverloadYield(r, e); }, AsyncIterator: _regeneratorAsyncIterator, async: function async(r, e, t, o, u) { return (n(e) ? _regeneratorAsyncGen : _regeneratorAsync)(a(r), e, t, o, u); }, keys: _regeneratorKeys, values: _regeneratorValues }; })(); }
|
|
@@ -23,7 +24,7 @@ function _OverloadYield(e, d) { this.v = e, this.k = d; }
|
|
|
23
24
|
import React from 'react';
|
|
24
25
|
import userEvent from '@testing-library/user-event';
|
|
25
26
|
import statuses from '../../utils/devUtils/constants/statuses';
|
|
26
|
-
import { render, screen } from '../../utils/testUtils/testWrapper';
|
|
27
|
+
import { act, fireEvent, render, screen } from '../../utils/testUtils/testWrapper';
|
|
27
28
|
import { universalComponentTests } from '../../utils/testUtils/universalComponentTest';
|
|
28
29
|
import { universalFieldComponentTests } from '../../utils/testUtils/universalFormSubmitTest';
|
|
29
30
|
import CheckboxField from '.';
|
|
@@ -332,4 +333,85 @@ test('indeterminate checkbox, clicking svg', /*#__PURE__*/_asyncToGenerator(/*#_
|
|
|
332
333
|
return _context8.stop();
|
|
333
334
|
}
|
|
334
335
|
}, _callee8);
|
|
336
|
+
})));
|
|
337
|
+
test('controlled indeterminate checkbox retains focus and toggles correctly across keyboard Space presses', /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee9() {
|
|
338
|
+
var onChange, IndeterminateParent, input, input2;
|
|
339
|
+
return _regeneratorRuntime().wrap(function _callee9$(_context9) {
|
|
340
|
+
while (1) switch (_context9.prev = _context9.next) {
|
|
341
|
+
case 0:
|
|
342
|
+
onChange = jest.fn();
|
|
343
|
+
IndeterminateParent = function IndeterminateParent() {
|
|
344
|
+
var _React$useState = React.useState(true),
|
|
345
|
+
_React$useState2 = _slicedToArray(_React$useState, 2),
|
|
346
|
+
isIndeterminate = _React$useState2[0],
|
|
347
|
+
setIsIndeterminate = _React$useState2[1];
|
|
348
|
+
var _React$useState3 = React.useState(false),
|
|
349
|
+
_React$useState4 = _slicedToArray(_React$useState3, 2),
|
|
350
|
+
isSelected = _React$useState4[0],
|
|
351
|
+
setIsSelected = _React$useState4[1];
|
|
352
|
+
var handleChange = function handleChange(selected) {
|
|
353
|
+
onChange(selected);
|
|
354
|
+
setIsIndeterminate(false);
|
|
355
|
+
setIsSelected(selected);
|
|
356
|
+
};
|
|
357
|
+
return ___EmotionJSX(CheckboxField, {
|
|
358
|
+
label: testLabel,
|
|
359
|
+
isIndeterminate: isIndeterminate,
|
|
360
|
+
isSelected: isSelected,
|
|
361
|
+
onChange: handleChange
|
|
362
|
+
});
|
|
363
|
+
};
|
|
364
|
+
render(___EmotionJSX(IndeterminateParent, null));
|
|
365
|
+
|
|
366
|
+
// Initial: indeterminate
|
|
367
|
+
expect(screen.getByRole('checkbox')).toHaveAttribute('aria-checked', 'mixed');
|
|
368
|
+
|
|
369
|
+
// First Space: focus the input, then simulate Space press
|
|
370
|
+
input = screen.getByRole('checkbox');
|
|
371
|
+
act(function () {
|
|
372
|
+
input.focus();
|
|
373
|
+
});
|
|
374
|
+
expect(input).toHaveFocus();
|
|
375
|
+
|
|
376
|
+
// Simulate keyboard Space: keydown triggers native change on checkbox, then keyup
|
|
377
|
+
fireEvent.keyDown(input, {
|
|
378
|
+
key: ' ',
|
|
379
|
+
code: 'Space',
|
|
380
|
+
charCode: 32
|
|
381
|
+
});
|
|
382
|
+
fireEvent.click(input); // keyboard Space on checkbox fires a click event in browsers
|
|
383
|
+
fireEvent.keyUp(input, {
|
|
384
|
+
key: ' ',
|
|
385
|
+
code: 'Space',
|
|
386
|
+
charCode: 32
|
|
387
|
+
});
|
|
388
|
+
expect(onChange).toHaveBeenNthCalledWith(1, true);
|
|
389
|
+
// Re-query after re-render: isIndeterminate=false now
|
|
390
|
+
expect(screen.getByRole('checkbox')).not.toHaveAttribute('aria-checked', 'mixed');
|
|
391
|
+
expect(screen.getByRole('checkbox')).toBeChecked();
|
|
392
|
+
|
|
393
|
+
// After the indeterminate->checked transition, the input should still have focus
|
|
394
|
+
// (the old IndeterminateCheckbox input was unmounted, so focus may be lost)
|
|
395
|
+
expect(screen.getByRole('checkbox')).toHaveFocus();
|
|
396
|
+
|
|
397
|
+
// Second Space: checked -> unchecked
|
|
398
|
+
input2 = screen.getByRole('checkbox');
|
|
399
|
+
fireEvent.keyDown(input2, {
|
|
400
|
+
key: ' ',
|
|
401
|
+
code: 'Space',
|
|
402
|
+
charCode: 32
|
|
403
|
+
});
|
|
404
|
+
fireEvent.click(input2);
|
|
405
|
+
fireEvent.keyUp(input2, {
|
|
406
|
+
key: ' ',
|
|
407
|
+
code: 'Space',
|
|
408
|
+
charCode: 32
|
|
409
|
+
});
|
|
410
|
+
expect(onChange).toHaveBeenNthCalledWith(2, false);
|
|
411
|
+
expect(screen.getByRole('checkbox')).not.toBeChecked();
|
|
412
|
+
case 20:
|
|
413
|
+
case "end":
|
|
414
|
+
return _context9.stop();
|
|
415
|
+
}
|
|
416
|
+
}, _callee9);
|
|
335
417
|
})));
|
|
@@ -83,16 +83,10 @@ var LinkSelectField = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
83
83
|
variant: "forms.select.arrow"
|
|
84
84
|
}, ___EmotionJSX(Icon, _extends({
|
|
85
85
|
icon: MenuDown,
|
|
86
|
-
title: {
|
|
87
|
-
name: 'Menu Down Icon'
|
|
88
|
-
},
|
|
89
86
|
sx: _objectSpread(_objectSpread({}, state.isOpen ? {
|
|
90
87
|
transform: 'rotate(180deg)'
|
|
91
88
|
} : null), iconPropsSx)
|
|
92
89
|
}, restIconProps, {
|
|
93
|
-
title: {
|
|
94
|
-
name: ''
|
|
95
|
-
},
|
|
96
90
|
color: isOnyx ? 'font.link' : 'active',
|
|
97
91
|
size: linkSelectFieldIcon,
|
|
98
92
|
"aria-hidden": "true"
|