@planningcenter/tapestry-react 2.0.0-rc.0 → 2.0.1-rc.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/dist/cjs/DataTable/hooks/useCollapsibleRows.js +1 -1
- package/dist/cjs/Dropdown/Dropdown.test.js +194 -19
- package/dist/cjs/Group/Group.js +6 -4
- package/dist/cjs/Modal/Modal.test.js +156 -0
- package/dist/cjs/Popover/Popover.js +4 -0
- package/dist/cjs/Popover/Popover.test.js +65 -0
- package/dist/cjs/Popover/rewireTabOrder.js +13 -30
- package/dist/cjs/Scrim/Scrim.js +1 -1
- package/dist/cjs/Select/Select.js +9 -0
- package/dist/cjs/Sidebar/Sidebar.js +4 -3
- package/dist/cjs/Table/Table.js +3 -5
- package/dist/cjs/ThemeProvider/ThemeProvider.js +5 -5
- package/dist/cjs/hooks/useConstant.js +23 -0
- package/dist/cjs/system/utils.js +2 -2
- package/dist/cjs/utils.js +3 -3
- package/dist/esm/DataTable/hooks/useCollapsibleRows.js +1 -1
- package/dist/esm/Dropdown/Dropdown.test.js +158 -17
- package/dist/esm/Group/Group.js +6 -4
- package/dist/esm/Modal/Modal.test.js +122 -0
- package/dist/esm/Popover/Popover.js +4 -0
- package/dist/esm/Popover/Popover.test.js +51 -0
- package/dist/esm/Popover/rewireTabOrder.js +13 -33
- package/dist/esm/Scrim/Scrim.js +1 -1
- package/dist/esm/Select/Select.js +9 -0
- package/dist/esm/Sidebar/Sidebar.js +4 -2
- package/dist/esm/Table/Table.js +1 -2
- package/dist/esm/ThemeProvider/ThemeProvider.js +1 -1
- package/dist/esm/hooks/useConstant.js +15 -0
- package/dist/esm/system/utils.js +1 -1
- package/dist/esm/utils.js +3 -3
- package/dist/types/Dropdown/Dropdown.test.d.ts +1 -1
- package/dist/types/Group/Group.d.ts +5 -1
- package/dist/types/Modal/Modal.test.d.ts +1 -0
- package/dist/types/Popover/Popover.test.d.ts +1 -0
- package/dist/types/hooks/useConstant.d.ts +1 -0
- package/package.json +15 -24
- package/src/DataTable/hooks/useCollapsibleRows.js +1 -1
- package/src/Dropdown/Dropdown.test.tsx +128 -17
- package/src/Group/Group.tsx +9 -3
- package/src/Modal/Modal.test.tsx +113 -0
- package/src/Popover/Popover.test.tsx +62 -0
- package/src/Popover/Popover.tsx +3 -0
- package/src/Popover/rewireTabOrder.ts +24 -42
- package/src/Scrim/Scrim.tsx +3 -3
- package/src/Select/Select.js +6 -0
- package/src/Sidebar/Sidebar.js +7 -5
- package/src/Table/Table.js +1 -2
- package/src/ThemeProvider/ThemeProvider.tsx +1 -1
- package/src/hooks/useConstant.ts +17 -0
- package/src/system/utils.js +1 -1
- package/src/utils.js +3 -3
- package/src/utils.test.js +29 -0
|
@@ -18,7 +18,7 @@ var _core = require("@emotion/core");
|
|
|
18
18
|
|
|
19
19
|
var _cache = _interopRequireDefault(require("@emotion/cache"));
|
|
20
20
|
|
|
21
|
-
var
|
|
21
|
+
var _lodash = require("lodash");
|
|
22
22
|
|
|
23
23
|
var _defaultTheme = _interopRequireDefault(require("../system/default-theme"));
|
|
24
24
|
|
|
@@ -78,12 +78,12 @@ function mergeThemes(a, b) {
|
|
|
78
78
|
|
|
79
79
|
return _objectSpread(_objectSpread(_objectSpread({}, a), b), {}, {
|
|
80
80
|
button: _objectSpread(_objectSpread(_objectSpread({}, a.button), b.button), {}, {
|
|
81
|
-
themes: (0,
|
|
81
|
+
themes: (0, _lodash.merge)(((_a$button = a.button) == null ? void 0 : _a$button.themes) || {}, ((_b$button = b.button) == null ? void 0 : _b$button.themes) || {})
|
|
82
82
|
}),
|
|
83
|
-
colors: (0,
|
|
83
|
+
colors: (0, _lodash.merge)((0, _system.flattenPalette)(a.colors || {}), (0, _system.flattenPalette)(b.colors || {})),
|
|
84
84
|
spinner: _objectSpread(_objectSpread(_objectSpread({}, a.spinner), b.spinner), {}, {
|
|
85
|
-
sizes: (0,
|
|
86
|
-
thickness: (0,
|
|
85
|
+
sizes: (0, _lodash.merge)(((_a$spinner = a.spinner) == null ? void 0 : _a$spinner.sizes) || {}, ((_b$spinner = b.spinner) == null ? void 0 : _b$spinner.sizes) || {}),
|
|
86
|
+
thickness: (0, _lodash.merge)(((_a$spinner2 = a.spinner) == null ? void 0 : _a$spinner2.thickness) || {}, ((_b$spinner2 = b.spinner) == null ? void 0 : _b$spinner2.thickness) || {})
|
|
87
87
|
})
|
|
88
88
|
});
|
|
89
89
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
|
|
4
|
+
|
|
5
|
+
exports.__esModule = true;
|
|
6
|
+
exports["default"] = useConstant;
|
|
7
|
+
|
|
8
|
+
var React = _interopRequireWildcard(require("react"));
|
|
9
|
+
|
|
10
|
+
// A copy/paste of the source of the `use-constant` package.
|
|
11
|
+
// https://github.com/Andarist/use-constant/blob/main/src/index.ts
|
|
12
|
+
// This is done to reduce dependencies.
|
|
13
|
+
function useConstant(fn) {
|
|
14
|
+
var ref = React.useRef();
|
|
15
|
+
|
|
16
|
+
if (!ref.current) {
|
|
17
|
+
ref.current = {
|
|
18
|
+
v: fn()
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return ref.current.v;
|
|
23
|
+
}
|
package/dist/cjs/system/utils.js
CHANGED
|
@@ -24,7 +24,7 @@ var _core = require("@emotion/core");
|
|
|
24
24
|
|
|
25
25
|
var _polished = require("polished");
|
|
26
26
|
|
|
27
|
-
var _lodash =
|
|
27
|
+
var _lodash = require("lodash");
|
|
28
28
|
|
|
29
29
|
var _colors = require("./colors");
|
|
30
30
|
|
|
@@ -161,7 +161,7 @@ function getForegroundColor(color) {
|
|
|
161
161
|
|
|
162
162
|
function useThemeValue(path, defaultValue) {
|
|
163
163
|
var userTheme = (0, _react.useContext)(_core.ThemeContext);
|
|
164
|
-
return path ? (0, _lodash
|
|
164
|
+
return path ? (0, _lodash.get)(userTheme, path, defaultValue || (0, _lodash.get)(_defaultTheme["default"], path)) : userTheme || _defaultTheme["default"];
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
function useThemeProps(path, props) {
|
package/dist/cjs/utils.js
CHANGED
|
@@ -46,7 +46,7 @@ var _react = require("react");
|
|
|
46
46
|
|
|
47
47
|
var _tabbable = require("tabbable");
|
|
48
48
|
|
|
49
|
-
var
|
|
49
|
+
var _lodash = require("lodash");
|
|
50
50
|
|
|
51
51
|
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
|
52
52
|
|
|
@@ -785,11 +785,11 @@ function createCSSProperty(key, value) {
|
|
|
785
785
|
createdCSSProperties.add(key);
|
|
786
786
|
}
|
|
787
787
|
|
|
788
|
-
return "--" + (0,
|
|
788
|
+
return "--" + (0, _lodash.kebabCase)(key) + "-" + (0, _lodash.kebabCase)(value);
|
|
789
789
|
}
|
|
790
790
|
|
|
791
791
|
function getCSSProperty(key, value) {
|
|
792
|
-
return key && value ? "var(--" + (0,
|
|
792
|
+
return key && value ? "var(--" + (0, _lodash.kebabCase)(key) + "-" + (0, _lodash.kebabCase)(value) + ")" : undefined;
|
|
793
793
|
}
|
|
794
794
|
|
|
795
795
|
function objectToCSSProperties(themeKey, props) {
|
|
@@ -5,7 +5,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
|
5
5
|
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
6
6
|
|
|
7
7
|
import { createContext, useCallback, useContext, useEffect } from 'react';
|
|
8
|
-
import useConstant from '
|
|
8
|
+
import useConstant from '../../hooks/useConstant';
|
|
9
9
|
import create from 'zustand';
|
|
10
10
|
import { range } from '../../utils';
|
|
11
11
|
export var CollapsibleRowsContext = /*#__PURE__*/createContext(null);
|
|
@@ -1,26 +1,167 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
2
|
import { fireEvent, render, screen } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
5
|
+
import { noop } from 'lodash';
|
|
6
|
+
import { Box, Button, Text, ThemeProvider } from '..';
|
|
3
7
|
import Dropdown from './Dropdown';
|
|
4
|
-
import ThemeProvider from '../ThemeProvider';
|
|
5
8
|
|
|
6
9
|
var _ref = /*#__PURE__*/React.createElement(Dropdown, {
|
|
7
10
|
title: "A menu"
|
|
8
11
|
});
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
13
|
+
describe('Dropdown', function () {
|
|
14
|
+
describe('Text search', function () {
|
|
15
|
+
it("should render title", function () {
|
|
16
|
+
render(_ref);
|
|
17
|
+
screen.getByText('A menu');
|
|
18
|
+
});
|
|
19
|
+
it("calls passed onSearch function when receiving keyboard input", function () {
|
|
20
|
+
var customTextSearch = jest.fn();
|
|
21
|
+
render( /*#__PURE__*/React.createElement(ThemeProvider, null, /*#__PURE__*/React.createElement(Dropdown, {
|
|
22
|
+
title: "A menu",
|
|
23
|
+
onSearch: customTextSearch
|
|
24
|
+
})));
|
|
25
|
+
var dropdown = screen.getByText('A menu');
|
|
26
|
+
fireEvent.keyDown(dropdown, {
|
|
27
|
+
key: 'A',
|
|
28
|
+
code: 'KeyA'
|
|
29
|
+
});
|
|
30
|
+
expect(customTextSearch).toHaveBeenCalled();
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
describe('Keyboard navigation', function () {
|
|
34
|
+
var StatefulDropdown = function StatefulDropdown() {
|
|
35
|
+
var _useState = useState(0),
|
|
36
|
+
count = _useState[0],
|
|
37
|
+
setCount = _useState[1];
|
|
38
|
+
|
|
39
|
+
return /*#__PURE__*/React.createElement(ThemeProvider, null, /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement(Dropdown, null, /*#__PURE__*/React.createElement(Dropdown.Item, null, /*#__PURE__*/React.createElement(Button, {
|
|
40
|
+
title: "One",
|
|
41
|
+
onClick: function onClick() {
|
|
42
|
+
return noop();
|
|
43
|
+
}
|
|
44
|
+
})), /*#__PURE__*/React.createElement(Dropdown.Item, null, /*#__PURE__*/React.createElement(Button, {
|
|
45
|
+
title: "Two",
|
|
46
|
+
onClick: function onClick() {
|
|
47
|
+
return setCount(function (c) {
|
|
48
|
+
return c + 1;
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}), /*#__PURE__*/React.createElement(Text, {
|
|
52
|
+
"data-testid": "count-text"
|
|
53
|
+
}, count)), /*#__PURE__*/React.createElement(Dropdown.Item, null, /*#__PURE__*/React.createElement(Button, {
|
|
54
|
+
title: "Three",
|
|
55
|
+
onClick: function onClick() {
|
|
56
|
+
return noop();
|
|
57
|
+
}
|
|
58
|
+
})))));
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
var _ref2 = /*#__PURE__*/React.createElement(StatefulDropdown, null);
|
|
62
|
+
|
|
63
|
+
it('should trap focus, tab forward through all elements', function () {
|
|
64
|
+
render(_ref2);
|
|
65
|
+
userEvent.tab();
|
|
66
|
+
userEvent.keyboard('{enter}');
|
|
67
|
+
|
|
68
|
+
var _screen$getAllByRole = screen.getAllByRole('button'),
|
|
69
|
+
openPopover = _screen$getAllByRole[0],
|
|
70
|
+
buttonOne = _screen$getAllByRole[1],
|
|
71
|
+
buttonTwo = _screen$getAllByRole[2],
|
|
72
|
+
buttonThree = _screen$getAllByRole[3];
|
|
73
|
+
|
|
74
|
+
expect(openPopover).toHaveFocus();
|
|
75
|
+
userEvent.tab();
|
|
76
|
+
expect(buttonOne).toHaveFocus();
|
|
77
|
+
userEvent.tab();
|
|
78
|
+
expect(buttonTwo).toHaveFocus();
|
|
79
|
+
userEvent.tab();
|
|
80
|
+
expect(buttonThree).toHaveFocus();
|
|
81
|
+
userEvent.tab();
|
|
82
|
+
expect(buttonOne).toHaveFocus();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
var _ref3 = /*#__PURE__*/React.createElement(StatefulDropdown, null);
|
|
86
|
+
|
|
87
|
+
it('should trap focus, tab backwards from first element to last', function () {
|
|
88
|
+
render(_ref3);
|
|
89
|
+
userEvent.tab();
|
|
90
|
+
userEvent.keyboard('{enter}');
|
|
91
|
+
|
|
92
|
+
var _screen$getAllByRole2 = screen.getAllByRole('button'),
|
|
93
|
+
openPopover = _screen$getAllByRole2[0],
|
|
94
|
+
buttonOne = _screen$getAllByRole2[1],
|
|
95
|
+
_buttonTwo = _screen$getAllByRole2[2],
|
|
96
|
+
buttonThree = _screen$getAllByRole2[3];
|
|
97
|
+
|
|
98
|
+
expect(openPopover).toHaveFocus();
|
|
99
|
+
userEvent.tab();
|
|
100
|
+
expect(buttonOne).toHaveFocus();
|
|
101
|
+
userEvent.tab({
|
|
102
|
+
shift: true
|
|
103
|
+
});
|
|
104
|
+
expect(buttonThree).toHaveFocus();
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
var _ref4 = /*#__PURE__*/React.createElement(StatefulDropdown, null);
|
|
108
|
+
|
|
109
|
+
it('should retain tab order after rerender', function () {
|
|
110
|
+
render(_ref4);
|
|
111
|
+
userEvent.tab();
|
|
112
|
+
userEvent.keyboard('{enter}');
|
|
113
|
+
|
|
114
|
+
var _screen$getAllByRole3 = screen.getAllByRole('button'),
|
|
115
|
+
buttonOne = _screen$getAllByRole3[1],
|
|
116
|
+
buttonTwo = _screen$getAllByRole3[2],
|
|
117
|
+
buttonThree = _screen$getAllByRole3[3];
|
|
118
|
+
|
|
119
|
+
userEvent.tab();
|
|
120
|
+
userEvent.tab();
|
|
121
|
+
expect(screen.getByTestId('count-text')).toHaveTextContent('0');
|
|
122
|
+
userEvent.keyboard('{enter}');
|
|
123
|
+
expect(screen.getByTestId('count-text')).toHaveTextContent('1');
|
|
124
|
+
expect(buttonTwo).toHaveFocus();
|
|
125
|
+
userEvent.tab();
|
|
126
|
+
expect(buttonThree).toHaveFocus();
|
|
127
|
+
userEvent.tab({
|
|
128
|
+
shift: true
|
|
129
|
+
});
|
|
130
|
+
userEvent.tab({
|
|
131
|
+
shift: true
|
|
132
|
+
});
|
|
133
|
+
expect(buttonOne).toHaveFocus();
|
|
134
|
+
userEvent.tab();
|
|
135
|
+
userEvent.tab();
|
|
136
|
+
userEvent.tab();
|
|
137
|
+
expect(buttonOne).toHaveFocus();
|
|
138
|
+
userEvent.tab({
|
|
139
|
+
shift: true
|
|
140
|
+
});
|
|
141
|
+
userEvent.tab({
|
|
142
|
+
shift: true
|
|
143
|
+
});
|
|
144
|
+
userEvent.tab({
|
|
145
|
+
shift: true
|
|
146
|
+
});
|
|
147
|
+
expect(buttonOne).toHaveFocus();
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
var _ref5 = /*#__PURE__*/React.createElement(StatefulDropdown, null);
|
|
151
|
+
|
|
152
|
+
it('should focus dropdown toggle when a user presses escape key', function () {
|
|
153
|
+
render(_ref5);
|
|
154
|
+
userEvent.tab();
|
|
155
|
+
userEvent.keyboard('{enter}');
|
|
156
|
+
|
|
157
|
+
var _screen$getAllByRole4 = screen.getAllByRole('button'),
|
|
158
|
+
openPopover = _screen$getAllByRole4[0],
|
|
159
|
+
buttonOne = _screen$getAllByRole4[1];
|
|
160
|
+
|
|
161
|
+
userEvent.tab();
|
|
162
|
+
expect(buttonOne).toHaveFocus();
|
|
163
|
+
userEvent.keyboard("{esc}");
|
|
164
|
+
expect(openPopover).toHaveFocus();
|
|
165
|
+
});
|
|
24
166
|
});
|
|
25
|
-
expect(customTextSearch).toHaveBeenCalled();
|
|
26
167
|
});
|
package/dist/esm/Group/Group.js
CHANGED
|
@@ -16,7 +16,8 @@ export function Group(_ref) {
|
|
|
16
16
|
childProps = _ref.childProps,
|
|
17
17
|
children = _ref.children,
|
|
18
18
|
radius = _ref.radius,
|
|
19
|
-
|
|
19
|
+
spacing = _ref.spacing,
|
|
20
|
+
restProps = _objectWithoutPropertiesLoose(_ref, ["axis", "childProps", "children", "radius", "spacing"]);
|
|
20
21
|
|
|
21
22
|
var themeRadius = useThemeValue('group.radius');
|
|
22
23
|
var radiusValue = radius != null ? radius : themeRadius;
|
|
@@ -26,15 +27,16 @@ export function Group(_ref) {
|
|
|
26
27
|
var marginBottom = isHorizontalLayout ? 0 : '-1px';
|
|
27
28
|
var marginRight = isHorizontalLayout ? '-1px' : 0;
|
|
28
29
|
return /*#__PURE__*/React.createElement(StackView, _extends({
|
|
29
|
-
axis: axis
|
|
30
|
+
axis: axis,
|
|
31
|
+
spacing: spacing
|
|
30
32
|
}, restProps), cloneChildren(children, function (child, _ref2) {
|
|
31
33
|
var _objectSpread2;
|
|
32
34
|
|
|
33
35
|
var firstChild = _ref2.firstChild,
|
|
34
36
|
lastChild = _ref2.lastChild;
|
|
35
|
-
return _objectSpread(_objectSpread(_objectSpread({}, childProps), {}, (_objectSpread2 = {}, _objectSpread2[startRadius] = firstChild ? radiusValue : 0, _objectSpread2[endRadius] = lastChild ? radiusValue : 0, _objectSpread2), !lastChild && {
|
|
37
|
+
return _objectSpread(_objectSpread(_objectSpread({}, childProps), {}, (_objectSpread2 = {}, _objectSpread2[startRadius] = firstChild ? radiusValue : 0, _objectSpread2[endRadius] = lastChild ? radiusValue : 0, _objectSpread2), !spacing && !lastChild && {
|
|
36
38
|
marginBottom: marginBottom
|
|
37
|
-
}), !lastChild && {
|
|
39
|
+
}), !spacing && !lastChild && {
|
|
38
40
|
marginRight: marginRight
|
|
39
41
|
});
|
|
40
42
|
}));
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
5
|
+
import Dropdown from '../Dropdown';
|
|
6
|
+
import Select from '../Select';
|
|
7
|
+
import { Button, Heading, Modal, ThemeProvider } from '../';
|
|
8
|
+
import { noop } from 'lodash';
|
|
9
|
+
|
|
10
|
+
var _ref = /*#__PURE__*/React.createElement(Heading, {
|
|
11
|
+
"data-testid": "modal-header"
|
|
12
|
+
}, "Hello");
|
|
13
|
+
|
|
14
|
+
describe('Modal', function () {
|
|
15
|
+
var TestModal = function TestModal() {
|
|
16
|
+
var _useState = useState(false),
|
|
17
|
+
open = _useState[0],
|
|
18
|
+
setOpen = _useState[1];
|
|
19
|
+
|
|
20
|
+
return /*#__PURE__*/React.createElement(ThemeProvider, null, /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Button, {
|
|
21
|
+
"data-testid": "modal-toggle",
|
|
22
|
+
onClick: function onClick() {
|
|
23
|
+
return setOpen(!open);
|
|
24
|
+
},
|
|
25
|
+
title: "Toggle modal"
|
|
26
|
+
}), /*#__PURE__*/React.createElement(Modal, {
|
|
27
|
+
open: open,
|
|
28
|
+
onRequestClose: function onRequestClose() {
|
|
29
|
+
return setOpen(false);
|
|
30
|
+
}
|
|
31
|
+
}, _ref, /*#__PURE__*/React.createElement(Dropdown, null, [1, 2, 3].map(function (n) {
|
|
32
|
+
return /*#__PURE__*/React.createElement(Dropdown.Item, {
|
|
33
|
+
"data-testid": "dropdown-item-" + n,
|
|
34
|
+
key: n
|
|
35
|
+
}, n);
|
|
36
|
+
})), /*#__PURE__*/React.createElement(Select, {
|
|
37
|
+
onChange: noop
|
|
38
|
+
}, [1, 2, 3].map(function (n) {
|
|
39
|
+
return /*#__PURE__*/React.createElement(Select.Option, {
|
|
40
|
+
"data-testid": "select-option-" + n,
|
|
41
|
+
key: n,
|
|
42
|
+
value: n
|
|
43
|
+
}, n);
|
|
44
|
+
})))));
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
var _ref2 = /*#__PURE__*/React.createElement(TestModal, null);
|
|
48
|
+
|
|
49
|
+
var _ref3 = /*#__PURE__*/React.createElement(TestModal, null);
|
|
50
|
+
|
|
51
|
+
var _ref4 = /*#__PURE__*/React.createElement(TestModal, null);
|
|
52
|
+
|
|
53
|
+
var _ref5 = /*#__PURE__*/React.createElement(TestModal, null);
|
|
54
|
+
|
|
55
|
+
var _ref6 = /*#__PURE__*/React.createElement(TestModal, null);
|
|
56
|
+
|
|
57
|
+
var _ref7 = /*#__PURE__*/React.createElement(TestModal, null);
|
|
58
|
+
|
|
59
|
+
describe('Keyboard navigation', function () {
|
|
60
|
+
it('should close modal on escape keypress (dropdown button has focus)', function () {
|
|
61
|
+
render(_ref2);
|
|
62
|
+
expect(screen.queryByTestId('modal-header')).toBeNull();
|
|
63
|
+
userEvent.click(screen.getByTestId('modal-toggle'));
|
|
64
|
+
expect(screen.getByTestId('modal-header')).toBeInTheDocument();
|
|
65
|
+
userEvent.keyboard("{esc}");
|
|
66
|
+
expect(screen.queryByTestId('modal-header')).toBeNull();
|
|
67
|
+
});
|
|
68
|
+
it('should not close modal when escape key closes a dropdown within modal', function () {
|
|
69
|
+
render(_ref3);
|
|
70
|
+
userEvent.click(screen.getByTestId('modal-toggle'));
|
|
71
|
+
|
|
72
|
+
var _screen$getAllByRole = screen.getAllByRole('button'),
|
|
73
|
+
dropdown = _screen$getAllByRole[1];
|
|
74
|
+
|
|
75
|
+
expect(dropdown).toHaveFocus();
|
|
76
|
+
userEvent.keyboard('{arrowdown}');
|
|
77
|
+
userEvent.keyboard("{esc}");
|
|
78
|
+
expect(screen.getByTestId('modal-header')).toBeInTheDocument();
|
|
79
|
+
});
|
|
80
|
+
it('should close dropdown on escape & close modal on subsequent escape', function () {
|
|
81
|
+
render(_ref4);
|
|
82
|
+
userEvent.click(screen.getByTestId('modal-toggle'));
|
|
83
|
+
userEvent.keyboard('{arrowdown}');
|
|
84
|
+
userEvent.keyboard("{esc}");
|
|
85
|
+
expect(screen.getByTestId('modal-header')).toBeInTheDocument();
|
|
86
|
+
userEvent.keyboard("{esc}");
|
|
87
|
+
expect(screen.queryByTestId('modal-header')).toBeNull();
|
|
88
|
+
});
|
|
89
|
+
it('should hide select popover on escape, but select remains in dom', function () {
|
|
90
|
+
render(_ref5);
|
|
91
|
+
userEvent.click(screen.getByTestId('modal-toggle'));
|
|
92
|
+
userEvent.tab();
|
|
93
|
+
userEvent.keyboard('{arrowdown}');
|
|
94
|
+
userEvent.keyboard("{esc}");
|
|
95
|
+
expect(screen.queryByTestId('select-option-1')).toBeInTheDocument();
|
|
96
|
+
});
|
|
97
|
+
it('should hide select popover on escape, close (unmount) select popover on subsequent escape, persist modal', function () {
|
|
98
|
+
render(_ref6);
|
|
99
|
+
userEvent.click(screen.getByTestId('modal-toggle'));
|
|
100
|
+
userEvent.tab();
|
|
101
|
+
userEvent.keyboard('{arrowdown}');
|
|
102
|
+
userEvent.keyboard("{esc}");
|
|
103
|
+
expect(screen.queryByTestId('select-option-1')).toBeInTheDocument();
|
|
104
|
+
userEvent.keyboard("{esc}");
|
|
105
|
+
expect(screen.queryByTestId('select-option-1')).toBeNull();
|
|
106
|
+
expect(screen.queryByTestId('modal-header')).toBeInTheDocument();
|
|
107
|
+
});
|
|
108
|
+
it('should hide select popover on escape, close (unmount) select popover on subsequent escape, close modal on subsequent escape', function () {
|
|
109
|
+
render(_ref7);
|
|
110
|
+
userEvent.click(screen.getByTestId('modal-toggle'));
|
|
111
|
+
userEvent.tab();
|
|
112
|
+
userEvent.keyboard('{arrowdown}');
|
|
113
|
+
userEvent.keyboard("{esc}");
|
|
114
|
+
expect(screen.queryByTestId('select-option-1')).toBeInTheDocument();
|
|
115
|
+
userEvent.keyboard("{esc}");
|
|
116
|
+
expect(screen.queryByTestId('select-option-1')).toBeNull();
|
|
117
|
+
expect(screen.queryByTestId('modal-header')).toBeInTheDocument();
|
|
118
|
+
userEvent.keyboard("{esc}");
|
|
119
|
+
expect(screen.queryByTestId('modal-header')).toBeNull();
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -103,6 +103,10 @@ export var Popover = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
|
|
|
103
103
|
|
|
104
104
|
var requestClose = function requestClose(event) {
|
|
105
105
|
if (event.key === 'Escape' && onRequestClose) {
|
|
106
|
+
if (open) {
|
|
107
|
+
event.nativeEvent.stopImmediatePropagation();
|
|
108
|
+
}
|
|
109
|
+
|
|
106
110
|
onRequestClose();
|
|
107
111
|
}
|
|
108
112
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import '@testing-library/jest-dom/extend-expect';
|
|
5
|
+
import { Box, Text, Button, Popover } from '..';
|
|
6
|
+
|
|
7
|
+
var PopBasic = function PopBasic(_ref) {
|
|
8
|
+
var children = _ref.children;
|
|
9
|
+
|
|
10
|
+
var _useState = useState(false),
|
|
11
|
+
open = _useState[0],
|
|
12
|
+
setOpen = _useState[1];
|
|
13
|
+
|
|
14
|
+
return /*#__PURE__*/React.createElement(Box, {
|
|
15
|
+
id: "container"
|
|
16
|
+
}, /*#__PURE__*/React.createElement(Popover, {
|
|
17
|
+
open: open,
|
|
18
|
+
offset: 1,
|
|
19
|
+
renderTo: "#container",
|
|
20
|
+
anchorElement: /*#__PURE__*/React.createElement(Button, {
|
|
21
|
+
title: "Toggle",
|
|
22
|
+
onClick: function onClick() {
|
|
23
|
+
return setOpen(!open);
|
|
24
|
+
},
|
|
25
|
+
id: "anchor-element"
|
|
26
|
+
})
|
|
27
|
+
}, children));
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
var _ref2 = /*#__PURE__*/React.createElement(PopBasic, null, /*#__PURE__*/React.createElement(Box, null));
|
|
31
|
+
|
|
32
|
+
describe('Popover', function () {
|
|
33
|
+
it('should not render string in closed Popover', function () {
|
|
34
|
+
var string = 'Test Text';
|
|
35
|
+
render( /*#__PURE__*/React.createElement(PopBasic, null, /*#__PURE__*/React.createElement(Text, null, string)));
|
|
36
|
+
expect(screen.queryByText(string)).toBeNull();
|
|
37
|
+
});
|
|
38
|
+
it('should render string in open Popover', function () {
|
|
39
|
+
var string = 'Test Text';
|
|
40
|
+
render( /*#__PURE__*/React.createElement(PopBasic, null, /*#__PURE__*/React.createElement(Text, null, string)));
|
|
41
|
+
var openPopover = screen.getByRole('button');
|
|
42
|
+
userEvent.click(openPopover);
|
|
43
|
+
expect(screen.getByText(string)).toBeInTheDocument();
|
|
44
|
+
});
|
|
45
|
+
it('should focus open button on click', function () {
|
|
46
|
+
render(_ref2);
|
|
47
|
+
var openPopover = screen.getByRole('button');
|
|
48
|
+
userEvent.click(openPopover);
|
|
49
|
+
expect(openPopover).toHaveFocus();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -32,43 +32,31 @@ var RewireTabOrder = /*#__PURE__*/function () {
|
|
|
32
32
|
|
|
33
33
|
_defineProperty(this, "nextActiveElement", null);
|
|
34
34
|
|
|
35
|
-
_defineProperty(this, "focusOriginalActiveElement", function () {
|
|
36
|
-
_this.originalActiveElement.focus();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
_defineProperty(this, "focusNextActiveElement", function () {
|
|
40
|
-
_this.nextActiveElement.focus();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
35
|
_defineProperty(this, "moveFocusToTargetFromTriggerElement", function (event) {
|
|
44
36
|
if (!event.shiftKey && event.keyCode === TAB_KEY) {
|
|
45
37
|
event.preventDefault();
|
|
46
38
|
|
|
47
|
-
_this.
|
|
39
|
+
if (_this.tabbables.includes(_this.nextActiveElement)) {
|
|
40
|
+
_this.nextActiveElement.focus();
|
|
41
|
+
} else {
|
|
42
|
+
_this.firstFocusableElement.focus();
|
|
43
|
+
}
|
|
48
44
|
}
|
|
49
45
|
});
|
|
50
46
|
|
|
51
|
-
_defineProperty(this, "
|
|
47
|
+
_defineProperty(this, "moveFocusToTargetFromFirstElement", function (event) {
|
|
52
48
|
if (event.target === _this.firstFocusableElement && event.shiftKey && event.keyCode === TAB_KEY) {
|
|
53
49
|
event.preventDefault();
|
|
54
50
|
|
|
55
|
-
_this.originalActiveElement.focus();
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
_defineProperty(this, "moveFocusToTargetFromNextElement", function (event) {
|
|
60
|
-
if (event.shiftKey && event.keyCode === TAB_KEY) {
|
|
61
|
-
event.preventDefault();
|
|
62
|
-
|
|
63
51
|
_this.lastFocusableElement.focus();
|
|
64
52
|
}
|
|
65
53
|
});
|
|
66
54
|
|
|
67
|
-
_defineProperty(this, "
|
|
68
|
-
if (!event.shiftKey && event.keyCode === TAB_KEY) {
|
|
55
|
+
_defineProperty(this, "moveFocusToTargetFromLastElement", function (event) {
|
|
56
|
+
if (event.target === _this.lastFocusableElement && !event.shiftKey && event.keyCode === TAB_KEY) {
|
|
69
57
|
event.preventDefault();
|
|
70
58
|
|
|
71
|
-
_this.
|
|
59
|
+
_this.firstFocusableElement.focus();
|
|
72
60
|
}
|
|
73
61
|
});
|
|
74
62
|
|
|
@@ -89,12 +77,8 @@ var RewireTabOrder = /*#__PURE__*/function () {
|
|
|
89
77
|
this.originalActiveElement = document.activeElement;
|
|
90
78
|
this.nextActiveElement = getNextActiveElement(this.originalActiveElement);
|
|
91
79
|
this.originalActiveElement.addEventListener('keydown', this.moveFocusToTargetFromTriggerElement);
|
|
92
|
-
this.firstFocusableElement.addEventListener('keydown', this.
|
|
93
|
-
|
|
94
|
-
if (this.nextActiveElement) {
|
|
95
|
-
this.nextActiveElement.addEventListener('keydown', this.moveFocusToTargetFromNextElement);
|
|
96
|
-
this.lastFocusableElement.addEventListener('keydown', this.moveFocusFromTargetToNextElement);
|
|
97
|
-
}
|
|
80
|
+
this.firstFocusableElement.addEventListener('keydown', this.moveFocusToTargetFromFirstElement);
|
|
81
|
+
this.lastFocusableElement.addEventListener('keydown', this.moveFocusToTargetFromLastElement);
|
|
98
82
|
};
|
|
99
83
|
|
|
100
84
|
_proto.destroy = function destroy() {
|
|
@@ -103,12 +87,8 @@ var RewireTabOrder = /*#__PURE__*/function () {
|
|
|
103
87
|
}
|
|
104
88
|
|
|
105
89
|
this.originalActiveElement.removeEventListener('keydown', this.moveFocusToTargetFromTriggerElement);
|
|
106
|
-
this.firstFocusableElement.removeEventListener('keydown', this.
|
|
107
|
-
|
|
108
|
-
if (this.nextActiveElement) {
|
|
109
|
-
this.nextActiveElement.removeEventListener('keydown', this.moveFocusToTargetFromNextElement);
|
|
110
|
-
this.lastFocusableElement.removeEventListener('keydown', this.moveFocusFromTargetToNextElement);
|
|
111
|
-
}
|
|
90
|
+
this.firstFocusableElement.removeEventListener('keydown', this.moveFocusToTargetFromFirstElement);
|
|
91
|
+
this.lastFocusableElement.removeEventListener('keydown', this.moveFocusToTargetFromLastElement);
|
|
112
92
|
};
|
|
113
93
|
|
|
114
94
|
return RewireTabOrder;
|
package/dist/esm/Scrim/Scrim.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/esm/extends";
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import StackView from '../StackView';
|
|
4
|
-
var Scrim = /*#__PURE__*/React.forwardRef(function (props) {
|
|
4
|
+
var Scrim = /*#__PURE__*/React.forwardRef(function (props, _ref) {
|
|
5
5
|
React.useLayoutEffect(function () {
|
|
6
6
|
document.body.style.overflow = 'hidden';
|
|
7
7
|
return function () {
|
|
@@ -358,6 +358,15 @@ var Select = /*#__PURE__*/function (_Component) {
|
|
|
358
358
|
|
|
359
359
|
break;
|
|
360
360
|
|
|
361
|
+
case 'Escape':
|
|
362
|
+
if (isPopoverOpen && !isPopoverVisible) {
|
|
363
|
+
event.preventDefault();
|
|
364
|
+
|
|
365
|
+
_this2.closePopover();
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
break;
|
|
369
|
+
|
|
361
370
|
case ' ':
|
|
362
371
|
event.preventDefault();
|
|
363
372
|
|
|
@@ -7,7 +7,6 @@ import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWith
|
|
|
7
7
|
import { jsx } from '@emotion/core';
|
|
8
8
|
import { Children } from 'react';
|
|
9
9
|
import StickyBox from 'react-sticky-box';
|
|
10
|
-
import warning from 'warning';
|
|
11
10
|
import { css } from '../system';
|
|
12
11
|
import StackView from '../StackView';
|
|
13
12
|
import SidebarList from './SidebarList';
|
|
@@ -29,7 +28,10 @@ function Sidebar(_ref) {
|
|
|
29
28
|
}, restProps), jsx(StickyBox, {
|
|
30
29
|
css: flexColumnCss
|
|
31
30
|
}, Children.map(children, function (child) {
|
|
32
|
-
|
|
31
|
+
if (child && child.type !== Sidebar.List || child && child.type !== Sidebar.Item) {
|
|
32
|
+
console.warn("Invalid component nesting. " + child.type + " cannot appear as a child of <Sidebar>. Only <Sidebar.List/> or <Sidebar.Item/> may be used.");
|
|
33
|
+
}
|
|
34
|
+
|
|
33
35
|
return child;
|
|
34
36
|
})));
|
|
35
37
|
}
|
package/dist/esm/Table/Table.js
CHANGED
|
@@ -10,8 +10,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
10
10
|
|
|
11
11
|
import React, { PureComponent, Children, Fragment } from 'react';
|
|
12
12
|
import { Global } from '@emotion/core';
|
|
13
|
-
import camelCase from 'lodash
|
|
14
|
-
import snakeCase from 'lodash.snakecase';
|
|
13
|
+
import { camelCase, snakeCase } from 'lodash';
|
|
15
14
|
import Button from '../Button';
|
|
16
15
|
import DragDrop from '../DragDrop';
|
|
17
16
|
import Pagination from '../Pagination';
|
|
@@ -8,7 +8,7 @@ import React, { useLayoutEffect, useState } from 'react';
|
|
|
8
8
|
import { ThemeProvider as EmotionThemeProvider } from 'emotion-theming';
|
|
9
9
|
import { CacheProvider } from '@emotion/core';
|
|
10
10
|
import createCache from '@emotion/cache';
|
|
11
|
-
import merge from '
|
|
11
|
+
import { merge } from 'lodash';
|
|
12
12
|
import defaultTheme from '../system/default-theme';
|
|
13
13
|
import { flattenPalette } from '../system';
|
|
14
14
|
import { objectToCSSProperties, shallowEqual } from '../utils';
|