@pingux/astro 1.4.2-alpha.1 → 1.5.0-alpha.2
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/CodeView/CodeView.js +1 -1
- package/lib/cjs/components/CodeView/CodeView.test.js +22 -27
- package/lib/cjs/components/CopyText/CopyText.js +1 -1
- package/lib/cjs/components/ListView/ListView.js +12 -13
- package/lib/cjs/components/ListView/ListView.test.js +8 -8
- package/lib/cjs/components/ListViewItem/ListViewItem.js +0 -2
- package/lib/cjs/components/MultiselectFilter/MultiselectFilter.js +143 -0
- package/lib/cjs/components/MultiselectFilter/MultiselectFilter.stories.js +283 -0
- package/lib/cjs/components/MultiselectFilter/MultiselectFilter.test.js +83 -0
- package/lib/cjs/components/MultiselectFilter/index.js +18 -0
- package/lib/cjs/components/MultiselectFilterItem/MultiselectFilterItem.js +55 -0
- package/lib/cjs/components/MultiselectFilterItem/MultiselectFilterItem.test.js +53 -0
- package/lib/cjs/components/MultiselectFilterItem/index.js +18 -0
- package/lib/cjs/components/MultiselectListContainer/MultiselectBadge.js +47 -0
- package/lib/cjs/components/MultiselectListContainer/MultiselectBadge.test.js +48 -0
- package/lib/cjs/components/MultiselectListContainer/MultiselectListContainer.js +157 -0
- package/lib/cjs/components/MultiselectListContainer/MultiselectListContainer.test.js +112 -0
- package/lib/cjs/components/MultiselectListContainer/index.js +18 -0
- package/lib/cjs/components/PopoverMenu/PopoverMenu.js +7 -2
- package/lib/cjs/components/Tab/Tab.js +22 -15
- package/lib/cjs/components/TabPicker/TabPicker.js +239 -0
- package/lib/cjs/components/TabPicker/index.js +18 -0
- package/lib/cjs/components/Tabs/Tabs.js +46 -13
- package/lib/cjs/components/Tabs/Tabs.stories.js +32 -2
- package/lib/cjs/components/Tabs/Tabs.test.js +183 -32
- package/lib/cjs/index.js +98 -32
- package/lib/cjs/styles/variants/buttons.js +38 -1
- package/lib/cjs/styles/variants/codeView.js +2 -1
- package/lib/cjs/styles/variants/multiselectListContainer.js +73 -0
- package/lib/cjs/styles/variants/tabs.js +5 -1
- package/lib/cjs/styles/variants/text.js +29 -2
- package/lib/cjs/styles/variants/variants.js +3 -0
- package/lib/components/CodeView/CodeView.js +1 -1
- package/lib/components/CodeView/CodeView.test.js +22 -23
- package/lib/components/CopyText/CopyText.js +1 -1
- package/lib/components/ListView/ListView.js +12 -13
- package/lib/components/ListView/ListView.test.js +8 -8
- package/lib/components/ListViewItem/ListViewItem.js +0 -2
- package/lib/components/MultiselectFilter/MultiselectFilter.js +118 -0
- package/lib/components/MultiselectFilter/MultiselectFilter.stories.js +251 -0
- package/lib/components/MultiselectFilter/MultiselectFilter.test.js +69 -0
- package/lib/components/MultiselectFilter/index.js +1 -0
- package/lib/components/MultiselectFilterItem/MultiselectFilterItem.js +36 -0
- package/lib/components/MultiselectFilterItem/MultiselectFilterItem.test.js +37 -0
- package/lib/components/MultiselectFilterItem/index.js +1 -0
- package/lib/components/MultiselectListContainer/MultiselectBadge.js +31 -0
- package/lib/components/MultiselectListContainer/MultiselectBadge.test.js +34 -0
- package/lib/components/MultiselectListContainer/MultiselectListContainer.js +123 -0
- package/lib/components/MultiselectListContainer/MultiselectListContainer.test.js +81 -0
- package/lib/components/MultiselectListContainer/index.js +1 -0
- package/lib/components/PopoverMenu/PopoverMenu.js +7 -2
- package/lib/components/Tab/Tab.js +14 -8
- package/lib/components/TabPicker/TabPicker.js +210 -0
- package/lib/components/TabPicker/index.js +1 -0
- package/lib/components/Tabs/Tabs.js +44 -11
- package/lib/components/Tabs/Tabs.stories.js +27 -0
- package/lib/components/Tabs/Tabs.test.js +165 -32
- package/lib/index.js +6 -0
- package/lib/styles/variants/buttons.js +38 -1
- package/lib/styles/variants/codeView.js +2 -1
- package/lib/styles/variants/multiselectListContainer.js +63 -0
- package/lib/styles/variants/tabs.js +5 -1
- package/lib/styles/variants/text.js +29 -2
- package/lib/styles/variants/variants.js +2 -0
- package/package.json +1 -1
@@ -0,0 +1,36 @@
|
|
1
|
+
import React, { forwardRef } from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { Box, Icon, Text } from '../../index';
|
4
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
5
|
+
var MultiselectFilterItem = /*#__PURE__*/forwardRef(function (props, ref) {
|
6
|
+
var text = props.text,
|
7
|
+
icon = props.icon;
|
8
|
+
return ___EmotionJSX(Box, {
|
9
|
+
"data-testid": "multiselect-filter-item",
|
10
|
+
isRow: true,
|
11
|
+
justifyContent: "space-between",
|
12
|
+
ref: ref
|
13
|
+
}, ___EmotionJSX(Text, {
|
14
|
+
variant: "multiselectFilterItem"
|
15
|
+
}, text), icon && ___EmotionJSX(Icon, {
|
16
|
+
"data-testid": "multiselect-filter-data-icon",
|
17
|
+
icon: icon,
|
18
|
+
mr: "md",
|
19
|
+
color: "neutral.10",
|
20
|
+
size: 13,
|
21
|
+
flexShrink: 0
|
22
|
+
}));
|
23
|
+
});
|
24
|
+
MultiselectFilterItem.propTypes = {
|
25
|
+
/**
|
26
|
+
* Display text.
|
27
|
+
*/
|
28
|
+
text: PropTypes.string,
|
29
|
+
|
30
|
+
/**
|
31
|
+
* List icon.
|
32
|
+
*/
|
33
|
+
icon: PropTypes.shape({})
|
34
|
+
};
|
35
|
+
MultiselectFilterItem.displayName = 'MultiselectFilterItem';
|
36
|
+
export default MultiselectFilterItem;
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
2
|
+
import React from 'react';
|
3
|
+
import FilterIcon from 'mdi-react/FilterIcon';
|
4
|
+
import axeTest from '../../utils/testUtils/testAxe';
|
5
|
+
import { render, screen } from '../../utils/testUtils/testWrapper';
|
6
|
+
import MultiselectFilterItem from './MultiselectFilterItem';
|
7
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
8
|
+
var testId = 'multiselect-filter-item';
|
9
|
+
var iconId = 'multiselect-filter-data-icon';
|
10
|
+
var defaultProps = {
|
11
|
+
text: 'Item name'
|
12
|
+
};
|
13
|
+
|
14
|
+
var getComponent = function getComponent() {
|
15
|
+
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
16
|
+
return render(___EmotionJSX(MultiselectFilterItem, _extends({}, defaultProps, props)));
|
17
|
+
};
|
18
|
+
|
19
|
+
afterEach(function () {
|
20
|
+
jest.restoreAllMocks();
|
21
|
+
}); // Need to be added to each test file to test accessibility using axe.
|
22
|
+
|
23
|
+
axeTest(getComponent);
|
24
|
+
test('default multiselectFilter', function () {
|
25
|
+
getComponent();
|
26
|
+
var multiselectFilterItem = screen.getByTestId(testId);
|
27
|
+
var icon = screen.queryByTestId(iconId);
|
28
|
+
expect(icon).not.toBeInTheDocument();
|
29
|
+
expect(multiselectFilterItem).toBeInTheDocument();
|
30
|
+
});
|
31
|
+
test('icon displays when icon prop is present', function () {
|
32
|
+
getComponent({
|
33
|
+
icon: FilterIcon
|
34
|
+
});
|
35
|
+
var icon = screen.getByTestId(iconId);
|
36
|
+
expect(icon).toBeInTheDocument();
|
37
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default } from './MultiselectFilterItem';
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
2
|
+
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
3
|
+
import React from 'react';
|
4
|
+
import PropTypes from 'prop-types';
|
5
|
+
import Chip from '../Chip';
|
6
|
+
/**
|
7
|
+
* The MultiselectBadge serves as a badge to display selected count.
|
8
|
+
*/
|
9
|
+
|
10
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
11
|
+
|
12
|
+
var MultiselectBadge = function MultiselectBadge(props) {
|
13
|
+
var selectedFilterCount = props.selectedFilterCount,
|
14
|
+
others = _objectWithoutProperties(props, ["selectedFilterCount"]);
|
15
|
+
|
16
|
+
return ___EmotionJSX(Chip, _extends({
|
17
|
+
as: "span",
|
18
|
+
bg: "neutral.90",
|
19
|
+
label: selectedFilterCount.toString(),
|
20
|
+
textColor: "neutral.30",
|
21
|
+
variant: "multiselectListContainer.multiselectListBadge",
|
22
|
+
isUppercase: true
|
23
|
+
}, others));
|
24
|
+
};
|
25
|
+
|
26
|
+
MultiselectBadge.propTypes = {
|
27
|
+
selectedFilterCount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
28
|
+
margin: PropTypes.string
|
29
|
+
};
|
30
|
+
MultiselectBadge.displayName = 'MultiselectBadge';
|
31
|
+
export default MultiselectBadge;
|
@@ -0,0 +1,34 @@
|
|
1
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
2
|
+
import React from 'react';
|
3
|
+
import axeTest from '../../utils/testUtils/testAxe';
|
4
|
+
import { render, screen } from '../../utils/testUtils/testWrapper';
|
5
|
+
import MultiselectBadge from './MultiselectBadge';
|
6
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
7
|
+
var testId = 'test-multiselectBadge';
|
8
|
+
var defaultProps = {
|
9
|
+
'data-testid': testId,
|
10
|
+
selectedFilterCount: 9
|
11
|
+
};
|
12
|
+
|
13
|
+
var getComponent = function getComponent() {
|
14
|
+
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
15
|
+
return render(___EmotionJSX(MultiselectBadge, _extends({}, defaultProps, props)));
|
16
|
+
};
|
17
|
+
|
18
|
+
afterEach(function () {
|
19
|
+
jest.restoreAllMocks();
|
20
|
+
}); // Need to be added to each test file to test accessibility using axe.
|
21
|
+
|
22
|
+
axeTest(getComponent);
|
23
|
+
test('default multiselectBadge', function () {
|
24
|
+
getComponent();
|
25
|
+
var multiselectBadge = screen.getByTestId(testId);
|
26
|
+
expect(multiselectBadge).toBeInTheDocument();
|
27
|
+
});
|
28
|
+
test('custom classname can be passed', function () {
|
29
|
+
getComponent({
|
30
|
+
className: 'testing-class'
|
31
|
+
});
|
32
|
+
var multiselectBadge = screen.getByTestId(testId);
|
33
|
+
expect(multiselectBadge).toHaveClass('testing-class');
|
34
|
+
});
|
@@ -0,0 +1,123 @@
|
|
1
|
+
import _Object$defineProperty from "@babel/runtime-corejs3/core-js-stable/object/define-property";
|
2
|
+
import _Object$defineProperties from "@babel/runtime-corejs3/core-js-stable/object/define-properties";
|
3
|
+
import _Object$getOwnPropertyDescriptors from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors";
|
4
|
+
import _forEachInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/for-each";
|
5
|
+
import _Object$getOwnPropertyDescriptor from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor";
|
6
|
+
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
|
7
|
+
import _Object$getOwnPropertySymbols from "@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols";
|
8
|
+
import _Object$keys from "@babel/runtime-corejs3/core-js-stable/object/keys";
|
9
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
10
|
+
import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
|
11
|
+
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
12
|
+
|
13
|
+
function ownKeys(object, enumerableOnly) { var keys = _Object$keys(object); if (_Object$getOwnPropertySymbols) { var symbols = _Object$getOwnPropertySymbols(object); if (enumerableOnly) symbols = _filterInstanceProperty(symbols).call(symbols, function (sym) { return _Object$getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
|
14
|
+
|
15
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { var _context; _forEachInstanceProperty(_context = ownKeys(Object(source), true)).call(_context, function (key) { _defineProperty(target, key, source[key]); }); } else if (_Object$getOwnPropertyDescriptors) { _Object$defineProperties(target, _Object$getOwnPropertyDescriptors(source)); } else { var _context2; _forEachInstanceProperty(_context2 = ownKeys(Object(source))).call(_context2, function (key) { _Object$defineProperty(target, key, _Object$getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
16
|
+
|
17
|
+
import React, { forwardRef } from 'react';
|
18
|
+
import PropTypes from 'prop-types';
|
19
|
+
import ChevronRightIcon from 'mdi-react/ChevronRightIcon';
|
20
|
+
import ChevronLeftIcon from 'mdi-react/ChevronLeftIcon';
|
21
|
+
import { useOverlayTriggerState } from '@react-stately/overlays';
|
22
|
+
import MultiselectBadge from './MultiselectBadge';
|
23
|
+
import { Icon, IconButton, Box } from '../../index';
|
24
|
+
import { useStatusClasses } from '../../hooks';
|
25
|
+
/**
|
26
|
+
* The MultiselectListContainer serves as a wrapper around a list and its associated trigger,
|
27
|
+
* linking the list's open state with the trigger's press state and providing necessary context.
|
28
|
+
*/
|
29
|
+
|
30
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
31
|
+
var MultiselectListContainer = /*#__PURE__*/forwardRef(function (props, ref) {
|
32
|
+
var selectedFilterCount = props.selectedFilterCount,
|
33
|
+
className = props.className,
|
34
|
+
children = props.children,
|
35
|
+
closeAriaLabel = props.closeAriaLabel,
|
36
|
+
isDefaultOpen = props.isDefaultOpen,
|
37
|
+
isOpen = props.isOpen,
|
38
|
+
onOpenChange = props.onOpenChange,
|
39
|
+
openAriaLabel = props.openAriaLabel,
|
40
|
+
others = _objectWithoutProperties(props, ["selectedFilterCount", "className", "children", "closeAriaLabel", "isDefaultOpen", "isOpen", "onOpenChange", "openAriaLabel"]);
|
41
|
+
|
42
|
+
var triggerRef = React.useRef();
|
43
|
+
var state = useOverlayTriggerState({
|
44
|
+
defaultOpen: isDefaultOpen,
|
45
|
+
isOpen: isOpen,
|
46
|
+
onOpenChange: onOpenChange
|
47
|
+
});
|
48
|
+
var close = state.close;
|
49
|
+
|
50
|
+
var _useStatusClasses = useStatusClasses(className, {
|
51
|
+
isOpen: state.isOpen
|
52
|
+
}),
|
53
|
+
classNames = _useStatusClasses.classNames;
|
54
|
+
|
55
|
+
var handleButtonPress = function handleButtonPress() {
|
56
|
+
if (state.isOpen) {
|
57
|
+
close(state, triggerRef, close);
|
58
|
+
} else {
|
59
|
+
state.open();
|
60
|
+
}
|
61
|
+
};
|
62
|
+
|
63
|
+
var handleClose = function handleClose(e) {
|
64
|
+
if (e.key === 'Escape') {
|
65
|
+
close(state, triggerRef, close);
|
66
|
+
}
|
67
|
+
};
|
68
|
+
|
69
|
+
return ___EmotionJSX(Box, _extends({
|
70
|
+
className: classNames,
|
71
|
+
onKeyUp: handleClose,
|
72
|
+
ref: ref,
|
73
|
+
variant: "multiselectListContainer.multiselectListContainer",
|
74
|
+
isRow: true
|
75
|
+
}, others), ___EmotionJSX(IconButton, {
|
76
|
+
isRow: true,
|
77
|
+
"aria-label": state.isOpen ? closeAriaLabel : openAriaLabel,
|
78
|
+
"data-testid": "multiselect-list-button",
|
79
|
+
onPress: handleButtonPress,
|
80
|
+
ref: triggerRef,
|
81
|
+
variant: "multiselectToggle",
|
82
|
+
pr: "sm"
|
83
|
+
}, ___EmotionJSX(Icon, {
|
84
|
+
color: "active",
|
85
|
+
icon: state.isOpen ? ChevronRightIcon : ChevronLeftIcon,
|
86
|
+
role: "button",
|
87
|
+
size: "30px"
|
88
|
+
}), !state.isOpen && selectedFilterCount && ___EmotionJSX(MultiselectBadge, {
|
89
|
+
"data-testid": "multiselect-list-badge",
|
90
|
+
margin: "auto",
|
91
|
+
selectedFilterCount: selectedFilterCount
|
92
|
+
})), state.isOpen && _objectSpread({}, children));
|
93
|
+
});
|
94
|
+
MultiselectListContainer.propTypes = {
|
95
|
+
/** Amount of selected items indicator. */
|
96
|
+
selectedFilterCount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
97
|
+
|
98
|
+
/** Defines a string value that labels the trigger icon when menu is open. */
|
99
|
+
closeAriaLabel: PropTypes.string,
|
100
|
+
|
101
|
+
/** Sets the default open state of the overlay. */
|
102
|
+
isDefaultOpen: PropTypes.bool,
|
103
|
+
|
104
|
+
/** Whether the overlay is currently open. */
|
105
|
+
isOpen: PropTypes.bool,
|
106
|
+
|
107
|
+
/**
|
108
|
+
* Method that is called when the open state of the menu changes.
|
109
|
+
* Returns the new open state and the action that caused the opening of the menu.
|
110
|
+
*
|
111
|
+
* `(isOpen: boolean, overlayTrigger: OverlayTriggerAction) => void`
|
112
|
+
*/
|
113
|
+
onOpenChange: PropTypes.func,
|
114
|
+
|
115
|
+
/** Defines a string value that labels the trigger icon when menu is closed. */
|
116
|
+
openAriaLabel: PropTypes.string
|
117
|
+
};
|
118
|
+
MultiselectListContainer.defaultProps = {
|
119
|
+
openAriaLabel: 'Open filter menu?',
|
120
|
+
closeAriaLabel: 'Close filter menu?'
|
121
|
+
};
|
122
|
+
MultiselectListContainer.displayName = 'MultiselectListContainer';
|
123
|
+
export default MultiselectListContainer;
|
@@ -0,0 +1,81 @@
|
|
1
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
2
|
+
import React from 'react';
|
3
|
+
import userEvent from '@testing-library/user-event';
|
4
|
+
import axeTest from '../../utils/testUtils/testAxe';
|
5
|
+
import { render, screen } from '../../utils/testUtils/testWrapper';
|
6
|
+
import MultiselectListContainer from './MultiselectListContainer';
|
7
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
8
|
+
var testId = 'test-multiselectListContainer';
|
9
|
+
var multiselectListBadgeId = 'multiselect-list-badge';
|
10
|
+
var multiselectListButtonId = 'multiselect-list-button';
|
11
|
+
var multiselectFilterId = 'multiselect-filter';
|
12
|
+
var defaultProps = {
|
13
|
+
'data-testid': testId
|
14
|
+
};
|
15
|
+
|
16
|
+
var getComponent = function getComponent() {
|
17
|
+
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
18
|
+
return render(___EmotionJSX(MultiselectListContainer, _extends({}, defaultProps, props), ___EmotionJSX("div", {
|
19
|
+
"data-testid": multiselectFilterId
|
20
|
+
})));
|
21
|
+
};
|
22
|
+
|
23
|
+
afterEach(function () {
|
24
|
+
jest.restoreAllMocks();
|
25
|
+
}); // Need to be added to each test file to test accessibility using axe.
|
26
|
+
|
27
|
+
axeTest(getComponent);
|
28
|
+
test('default MultiselectListContainer', function () {
|
29
|
+
getComponent();
|
30
|
+
var multiselectListContainer = screen.getByTestId(testId);
|
31
|
+
expect(multiselectListContainer).toBeInTheDocument();
|
32
|
+
});
|
33
|
+
test('custom classname can be passed', function () {
|
34
|
+
getComponent({
|
35
|
+
className: 'testing-class'
|
36
|
+
});
|
37
|
+
var multiselectListContainer = screen.getByTestId(testId);
|
38
|
+
expect(multiselectListContainer).toHaveClass('testing-class');
|
39
|
+
});
|
40
|
+
test('shows badge when container is closed', function () {
|
41
|
+
getComponent({
|
42
|
+
selectedFilterCount: 9,
|
43
|
+
state: {
|
44
|
+
isOpen: false
|
45
|
+
}
|
46
|
+
});
|
47
|
+
var badge = screen.getByTestId(multiselectListBadgeId);
|
48
|
+
expect(badge).toBeInTheDocument();
|
49
|
+
});
|
50
|
+
test('updates aria label when button is clicked', function () {
|
51
|
+
var state = {
|
52
|
+
isOpen: true
|
53
|
+
};
|
54
|
+
getComponent({
|
55
|
+
state: state
|
56
|
+
});
|
57
|
+
var button = screen.getByTestId(multiselectListButtonId);
|
58
|
+
userEvent.click(button);
|
59
|
+
var multiSelect = screen.queryByTestId(multiselectFilterId);
|
60
|
+
expect(button).toHaveAttribute('aria-label', 'Close filter menu?');
|
61
|
+
expect(multiSelect).toBeInTheDocument();
|
62
|
+
userEvent.click(button);
|
63
|
+
expect(button).toHaveAttribute('aria-label', 'Open filter menu?');
|
64
|
+
expect(multiSelect).not.toBeInTheDocument();
|
65
|
+
});
|
66
|
+
test('shows children when isOpen is true', function () {
|
67
|
+
getComponent({
|
68
|
+
isOpen: true
|
69
|
+
});
|
70
|
+
var multiselectFilter = screen.getByTestId(multiselectFilterId);
|
71
|
+
expect(multiselectFilter).toBeInTheDocument();
|
72
|
+
});
|
73
|
+
test('should hide children when pressing the escape key', function () {
|
74
|
+
getComponent();
|
75
|
+
var button = screen.getByTestId(multiselectListButtonId);
|
76
|
+
userEvent.click(button);
|
77
|
+
var multiSelect = screen.queryByTestId(multiselectFilterId);
|
78
|
+
expect(multiSelect).toBeInTheDocument();
|
79
|
+
userEvent.type(button, '{esc}');
|
80
|
+
expect(multiSelect).not.toBeInTheDocument();
|
81
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default } from './MultiselectListContainer';
|
@@ -49,7 +49,8 @@ var PopoverMenu = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
49
49
|
isDefaultOpen = props.isDefaultOpen,
|
50
50
|
isNotFlippable = props.isNotFlippable,
|
51
51
|
isNotClosedOnSelect = props.isNotClosedOnSelect,
|
52
|
-
hasNoArrow = props.hasNoArrow
|
52
|
+
hasNoArrow = props.hasNoArrow,
|
53
|
+
isContainFocus = props.isContainFocus;
|
53
54
|
|
54
55
|
var _React$Children$toArr = React.Children.toArray(children),
|
55
56
|
_React$Children$toArr2 = _slicedToArray(_React$Children$toArr, 2),
|
@@ -90,7 +91,8 @@ var PopoverMenu = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
90
91
|
});
|
91
92
|
|
92
93
|
var contents = ___EmotionJSX(FocusScope, {
|
93
|
-
restoreFocus: true
|
94
|
+
restoreFocus: true,
|
95
|
+
contain: isContainFocus
|
94
96
|
}, ___EmotionJSX(DismissButton, {
|
95
97
|
onDismiss: state.close
|
96
98
|
}), menu, ___EmotionJSX(DismissButton, {
|
@@ -136,6 +138,9 @@ PopoverMenu.propTypes = {
|
|
136
138
|
/** Whether the PopoverMenu hides the arrow. */
|
137
139
|
hasNoArrow: PropTypes.bool,
|
138
140
|
|
141
|
+
/** Whether the PopoverMenu contains focus inside the scope. */
|
142
|
+
isContainFocus: PropTypes.bool,
|
143
|
+
|
139
144
|
/**
|
140
145
|
* Handler that is called when the overlay's open state changes.
|
141
146
|
*
|
@@ -7,13 +7,11 @@ import { useFocusRing } from '@react-aria/focus';
|
|
7
7
|
import { useHover } from '@react-aria/interactions';
|
8
8
|
import { mergeProps } from '@react-aria/utils';
|
9
9
|
import { Item as Tab } from '@react-stately/collections';
|
10
|
-
import Box from '../Box';
|
11
10
|
import { TabsContext } from '../Tabs';
|
12
|
-
import Text from '../Text';
|
13
11
|
import { useStatusClasses, usePropWarning } from '../../hooks';
|
14
12
|
import ORIENTATION from '../../utils/devUtils/constants/orientation';
|
15
|
-
import
|
16
|
-
import Button from '
|
13
|
+
import TabPicker from '../TabPicker';
|
14
|
+
import { Box, Text, TooltipTrigger, Tooltip, Button } from '../..';
|
17
15
|
import { jsx as ___EmotionJSX } from "@emotion/react";
|
18
16
|
export var CollectionTab = /*#__PURE__*/forwardRef(function (props, ref) {
|
19
17
|
var className = props.className,
|
@@ -84,6 +82,16 @@ export var CollectionTab = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
84
82
|
variant: "tabLabel"
|
85
83
|
}, tabLabelProps), rendered), isSelected && !isDisabled && ___EmotionJSX(TabLine, tabLineProps)), slots === null || slots === void 0 ? void 0 : slots.afterTab);
|
86
84
|
|
85
|
+
if (mode === 'list' && itemProps.list) {
|
86
|
+
return ___EmotionJSX(TabPicker, _extends({
|
87
|
+
ref: tabRef,
|
88
|
+
className: classNames,
|
89
|
+
items: itemProps.list,
|
90
|
+
state: state,
|
91
|
+
item: item
|
92
|
+
}, mergeProps(focusProps, hoverProps, tabProps), otherItemProps));
|
93
|
+
}
|
94
|
+
|
87
95
|
if (mode === 'tooltip') {
|
88
96
|
return ___EmotionJSX(React.Fragment, null, separator, ___EmotionJSX(TooltipTrigger, _extends({}, tooltipTriggerProps, {
|
89
97
|
isOpen: isHovered || isFocusVisible
|
@@ -103,7 +111,7 @@ CollectionTab.propTypes = {
|
|
103
111
|
rendered: PropTypes.node,
|
104
112
|
tabLineProps: PropTypes.shape({})
|
105
113
|
}),
|
106
|
-
mode: PropTypes.oneOf(['default', 'tooltip']),
|
114
|
+
mode: PropTypes.oneOf(['default', 'tooltip', 'list']),
|
107
115
|
orientation: PropTypes.oneOf(['horizontal', 'vertical']),
|
108
116
|
tooltipTriggerProps: PropTypes.shape({}),
|
109
117
|
slots: PropTypes.shape({
|
@@ -111,13 +119,11 @@ CollectionTab.propTypes = {
|
|
111
119
|
afterTab: PropTypes.node
|
112
120
|
})
|
113
121
|
};
|
114
|
-
|
115
|
-
var TabLine = function TabLine(props) {
|
122
|
+
export var TabLine = function TabLine(props) {
|
116
123
|
return ___EmotionJSX(Box, _extends({
|
117
124
|
role: "presentation",
|
118
125
|
variant: "tabLine"
|
119
126
|
}, props));
|
120
127
|
}; // Export Item as default Tab for simplicity, convert to CollectionTab within Tabs component
|
121
128
|
|
122
|
-
|
123
129
|
export default Tab;
|
@@ -0,0 +1,210 @@
|
|
1
|
+
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
|
2
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
3
|
+
import _findInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find";
|
4
|
+
import _findIndexInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/find-index";
|
5
|
+
import _Array$from from "@babel/runtime-corejs3/core-js-stable/array/from";
|
6
|
+
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/filter";
|
7
|
+
import _someInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/some";
|
8
|
+
import _slicedToArray from "@babel/runtime-corejs3/helpers/esm/slicedToArray";
|
9
|
+
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
10
|
+
import React, { forwardRef, useEffect, useMemo, useRef, useState } from 'react';
|
11
|
+
import PropTypes from 'prop-types';
|
12
|
+
import { Item as Tab } from '@react-stately/collections';
|
13
|
+
import ArrowDropUpIcon from 'mdi-react/ArrowDropUpIcon';
|
14
|
+
import ArrowDropDownIcon from 'mdi-react/ArrowDropDownIcon';
|
15
|
+
import { useStatusClasses } from '../../hooks';
|
16
|
+
import { Box, Text, Button, PopoverMenu, Icon, Menu } from '../..';
|
17
|
+
import { TabLine } from '../Tab';
|
18
|
+
/* istanbul ignore next */
|
19
|
+
|
20
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
21
|
+
var TabPicker = /*#__PURE__*/forwardRef(function (_ref, ref) {
|
22
|
+
var className = _ref.className,
|
23
|
+
items = _ref.items,
|
24
|
+
state = _ref.state,
|
25
|
+
item = _ref.item,
|
26
|
+
others = _objectWithoutProperties(_ref, ["className", "items", "state", "item"]);
|
27
|
+
|
28
|
+
var _useState = useState(false),
|
29
|
+
_useState2 = _slicedToArray(_useState, 2),
|
30
|
+
isOpen = _useState2[0],
|
31
|
+
setIsOpen = _useState2[1];
|
32
|
+
|
33
|
+
var _useState3 = useState(state.selectedKey),
|
34
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
35
|
+
selectedItem = _useState4[0],
|
36
|
+
setSelectedItem = _useState4[1];
|
37
|
+
|
38
|
+
var selectionManager = state.selectionManager;
|
39
|
+
|
40
|
+
var _useState5 = useState(selectionManager.focusedKey),
|
41
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
42
|
+
focusedItem = _useState6[0],
|
43
|
+
setFocusedItem = _useState6[1];
|
44
|
+
|
45
|
+
var isTabFocused = selectionManager.focusedKey === item.key;
|
46
|
+
var isTabSelected = state.selectedKey === item.key;
|
47
|
+
|
48
|
+
var isListItemFocused = _someInstanceProperty(items).call(items, function (el) {
|
49
|
+
return el.key === selectionManager.focusedKey;
|
50
|
+
});
|
51
|
+
|
52
|
+
var isListItemSelected = _someInstanceProperty(items).call(items, function (el) {
|
53
|
+
return el.key === state.selectedKey;
|
54
|
+
});
|
55
|
+
|
56
|
+
var _useMemo = useMemo(function () {
|
57
|
+
var _context, _tabs$prevIndex, _tabs$nextIndex;
|
58
|
+
|
59
|
+
var tabs = _filterInstanceProperty(_context = _Array$from(state.collection)).call(_context, function (tab) {
|
60
|
+
var _tab$value;
|
61
|
+
|
62
|
+
return !(tab === null || tab === void 0 ? void 0 : (_tab$value = tab.value) === null || _tab$value === void 0 ? void 0 : _tab$value.isListItem);
|
63
|
+
});
|
64
|
+
|
65
|
+
var prevIndex = _findIndexInstanceProperty(tabs).call(tabs, function (tab) {
|
66
|
+
return tab.key === item.key;
|
67
|
+
}) - 1;
|
68
|
+
var nextIndex = _findIndexInstanceProperty(tabs).call(tabs, function (tab) {
|
69
|
+
return tab.key === item.key;
|
70
|
+
}) + 1;
|
71
|
+
return {
|
72
|
+
prevKey: ((_tabs$prevIndex = tabs[prevIndex]) === null || _tabs$prevIndex === void 0 ? void 0 : _tabs$prevIndex.key) || tabs[tabs.length].key,
|
73
|
+
nextKey: ((_tabs$nextIndex = tabs[nextIndex]) === null || _tabs$nextIndex === void 0 ? void 0 : _tabs$nextIndex.key) || tabs[0].key
|
74
|
+
};
|
75
|
+
}, []),
|
76
|
+
prevKey = _useMemo.prevKey,
|
77
|
+
nextKey = _useMemo.nextKey;
|
78
|
+
|
79
|
+
var _useStatusClasses = useStatusClasses(className, {
|
80
|
+
isSelected: isListItemSelected
|
81
|
+
}),
|
82
|
+
classNames = _useStatusClasses.classNames;
|
83
|
+
|
84
|
+
var menuRef = useRef();
|
85
|
+
|
86
|
+
var handleSelectedItem = function handleSelectedItem(currentItem) {
|
87
|
+
state.setSelectedKey(currentItem);
|
88
|
+
setFocusedItem(currentItem);
|
89
|
+
};
|
90
|
+
|
91
|
+
useEffect(function () {
|
92
|
+
if (selectedItem) {
|
93
|
+
handleSelectedItem(selectedItem);
|
94
|
+
}
|
95
|
+
}, [selectedItem]);
|
96
|
+
useEffect(function () {
|
97
|
+
if (focusedItem) {
|
98
|
+
selectionManager.setFocusedKey(focusedItem);
|
99
|
+
}
|
100
|
+
}, [focusedItem]);
|
101
|
+
useEffect(function () {
|
102
|
+
if (isOpen && (isTabFocused || isListItemSelected) && menuRef.current) {
|
103
|
+
if (focusedItem) {
|
104
|
+
var _context2;
|
105
|
+
|
106
|
+
_findInstanceProperty(_context2 = _Array$from(menuRef.current.children)).call(_context2, function (el) {
|
107
|
+
return el.dataset.key === focusedItem;
|
108
|
+
}).focus();
|
109
|
+
} else {
|
110
|
+
menuRef.current.firstChild.focus();
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
if (!isOpen && isTabSelected && !selectedItem) {
|
115
|
+
setSelectedItem(selectionManager.focusedKey);
|
116
|
+
}
|
117
|
+
}, [isOpen]);
|
118
|
+
useEffect(function () {
|
119
|
+
if (isOpen && isListItemFocused) {
|
120
|
+
setFocusedItem(selectionManager.focusedKey);
|
121
|
+
} else if (!isOpen && isListItemFocused) {
|
122
|
+
selectionManager.setFocusedKey(item.key);
|
123
|
+
}
|
124
|
+
}, [selectionManager.focusedKey]);
|
125
|
+
useEffect(function () {
|
126
|
+
if (isTabSelected || isTabFocused) {
|
127
|
+
if (selectedItem) {
|
128
|
+
handleSelectedItem(selectedItem);
|
129
|
+
} else if (isListItemSelected && !selectedItem) {
|
130
|
+
setSelectedItem(state.selectedKey);
|
131
|
+
} else {
|
132
|
+
setFocusedItem(items[0].key);
|
133
|
+
}
|
134
|
+
} else if (!isListItemSelected && !isListItemFocused) {
|
135
|
+
setIsOpen(false);
|
136
|
+
setSelectedItem(null);
|
137
|
+
setFocusedItem(null);
|
138
|
+
}
|
139
|
+
}, [isTabSelected, isListItemSelected]);
|
140
|
+
|
141
|
+
var handleKeyNavigation = function handleKeyNavigation(e) {
|
142
|
+
switch (e.key) {
|
143
|
+
case 'ArrowRight':
|
144
|
+
{
|
145
|
+
selectionManager.setFocusedKey(nextKey);
|
146
|
+
break;
|
147
|
+
}
|
148
|
+
|
149
|
+
case 'ArrowLeft':
|
150
|
+
{
|
151
|
+
selectionManager.setFocusedKey(prevKey);
|
152
|
+
break;
|
153
|
+
}
|
154
|
+
|
155
|
+
default:
|
156
|
+
break;
|
157
|
+
}
|
158
|
+
};
|
159
|
+
|
160
|
+
var tabProps = others;
|
161
|
+
delete tabProps.onPointerDown;
|
162
|
+
delete tabProps.onKeyDown;
|
163
|
+
return ___EmotionJSX(PopoverMenu, {
|
164
|
+
onOpenChange: setIsOpen,
|
165
|
+
isOpen: isOpen,
|
166
|
+
isContainFocus: true
|
167
|
+
}, ___EmotionJSX(Button, {
|
168
|
+
className: classNames,
|
169
|
+
variant: "menuTab",
|
170
|
+
onKeyDown: handleKeyNavigation
|
171
|
+
}, ___EmotionJSX(Box, _extends({
|
172
|
+
className: classNames,
|
173
|
+
variant: "tab",
|
174
|
+
ref: ref
|
175
|
+
}, tabProps), ___EmotionJSX(Text, {
|
176
|
+
variant: "tabLabel"
|
177
|
+
}, item.props.name), selectedItem && ___EmotionJSX(TabLine, null)), ___EmotionJSX(Icon, {
|
178
|
+
icon: isOpen ? ArrowDropUpIcon : ArrowDropDownIcon
|
179
|
+
})), ___EmotionJSX(Menu, {
|
180
|
+
onAction: setSelectedItem,
|
181
|
+
selectionMode: "single",
|
182
|
+
selectedKeys: [selectionManager.focusedKey],
|
183
|
+
ref: menuRef
|
184
|
+
}, _mapInstanceProperty(items).call(items, function (tab) {
|
185
|
+
return ___EmotionJSX(Tab, {
|
186
|
+
key: tab.key
|
187
|
+
}, tab.name);
|
188
|
+
})));
|
189
|
+
});
|
190
|
+
TabPicker.propTypes = {
|
191
|
+
item: PropTypes.shape({
|
192
|
+
key: PropTypes.string,
|
193
|
+
props: PropTypes.shape({
|
194
|
+
name: PropTypes.string
|
195
|
+
})
|
196
|
+
}),
|
197
|
+
items: PropTypes.arrayOf(PropTypes.shape({
|
198
|
+
key: PropTypes.string
|
199
|
+
})),
|
200
|
+
state: PropTypes.shape({
|
201
|
+
collection: PropTypes.shape({}),
|
202
|
+
selectedKey: PropTypes.string,
|
203
|
+
setSelectedKey: PropTypes["function"],
|
204
|
+
selectionManager: PropTypes.shape({
|
205
|
+
focusedKey: PropTypes.string,
|
206
|
+
setFocusedKey: PropTypes["function"]
|
207
|
+
})
|
208
|
+
})
|
209
|
+
};
|
210
|
+
export default TabPicker;
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default } from './TabPicker';
|