@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
@@ -35,8 +35,21 @@ var textValue = "\nexport const Default = args => (\n <>\n <Text sx={{ fontW
|
|
35
35
|
var getComponent = function getComponent() {
|
36
36
|
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
37
37
|
return render(___EmotionJSX(CodeView, _extends({}, defaultProps, props), textValue));
|
38
|
-
};
|
38
|
+
};
|
39
39
|
|
40
|
+
beforeEach(function () {
|
41
|
+
var mockClipboard = {
|
42
|
+
writeText: jest.fn()
|
43
|
+
};
|
44
|
+
global.navigator.clipboard = mockClipboard;
|
45
|
+
global.document.execCommand = jest.fn();
|
46
|
+
global.document.execCommand.mockReturnValue(true);
|
47
|
+
});
|
48
|
+
afterEach(function () {
|
49
|
+
jest.resetAllMocks();
|
50
|
+
global.navigator.clipboard = originalClipboard;
|
51
|
+
global.document.execCommand = originalExecCommand;
|
52
|
+
}); // Need to be added to each test file to test accessibility using axe.
|
40
53
|
|
41
54
|
axeTest(getComponent);
|
42
55
|
test('renders component in the default state', function () {
|
@@ -45,25 +58,24 @@ test('renders component in the default state', function () {
|
|
45
58
|
expect(container).toBeInstanceOf(HTMLDivElement);
|
46
59
|
expect(container).toBeInTheDocument();
|
47
60
|
});
|
48
|
-
test('
|
61
|
+
test('copy button is hovered and renders tooltip via mouse', function () {
|
49
62
|
getComponent();
|
50
|
-
var
|
51
|
-
|
52
|
-
|
63
|
+
var copyBtn = screen.getByLabelText('copy');
|
64
|
+
expect(copyBtn).not.toHaveFocus();
|
65
|
+
userEvent.hover(copyBtn);
|
66
|
+
expect(copyBtn).toHaveClass('is-hovered');
|
53
67
|
expect(screen.queryByRole('tooltip')).toBeInTheDocument();
|
54
68
|
expect(screen.queryByRole('tooltip')).toHaveTextContent('Copy to clipboard');
|
55
69
|
});
|
56
|
-
test('
|
70
|
+
test('copy button is focused and renders tooltip via keyboard', function () {
|
57
71
|
getComponent();
|
58
|
-
var container = screen.getByTestId(testId);
|
59
|
-
expect(container).not.toHaveFocus();
|
60
|
-
userEvent.tab();
|
61
|
-
expect(container).toHaveFocus();
|
62
72
|
var copyBtn = screen.getByLabelText('copy');
|
63
73
|
expect(copyBtn).not.toHaveFocus();
|
64
74
|
userEvent.tab();
|
65
75
|
expect(copyBtn).toHaveFocus();
|
66
76
|
expect(copyBtn).toHaveClass('is-focused');
|
77
|
+
expect(screen.queryByRole('tooltip')).toBeInTheDocument();
|
78
|
+
expect(screen.queryByRole('tooltip')).toHaveTextContent('Copy to clipboard');
|
67
79
|
});
|
68
80
|
test('doesn\'t render copy button and tooltip with prop hasNoCopyButton', function () {
|
69
81
|
getComponent({
|
@@ -86,19 +98,6 @@ test('renders line numbers with prop hasLineNumbers', function () {
|
|
86
98
|
expect(screen.queryByText('1')).toBeInTheDocument();
|
87
99
|
expect(screen.queryByText(linesLength)).toBeInTheDocument();
|
88
100
|
});
|
89
|
-
beforeEach(function () {
|
90
|
-
var mockClipboard = {
|
91
|
-
writeText: jest.fn()
|
92
|
-
};
|
93
|
-
global.navigator.clipboard = mockClipboard;
|
94
|
-
global.document.execCommand = jest.fn();
|
95
|
-
global.document.execCommand.mockReturnValue(true);
|
96
|
-
});
|
97
|
-
afterEach(function () {
|
98
|
-
jest.resetAllMocks();
|
99
|
-
global.navigator.clipboard = originalClipboard;
|
100
|
-
global.document.execCommand = originalExecCommand;
|
101
|
-
});
|
102
101
|
test('click on copy button copies data to the clipboard', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
|
103
102
|
var button;
|
104
103
|
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
|
@@ -106,7 +106,7 @@ var CopyText = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
106
106
|
ref: ref,
|
107
107
|
isRow: true,
|
108
108
|
variant: "boxes.copy"
|
109
|
-
}, others), content, ___EmotionJSX(TooltipWrapper, {
|
109
|
+
}, wrapperProps, others), content, ___EmotionJSX(TooltipWrapper, {
|
110
110
|
isOpen: isTooltipOpen,
|
111
111
|
tooltip: tooltip
|
112
112
|
}, ___EmotionJSX(CopyButton, _extends({
|
@@ -11,6 +11,7 @@ import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
|
11
11
|
import _defineProperty from "@babel/runtime-corejs3/helpers/esm/defineProperty";
|
12
12
|
import _Array$from from "@babel/runtime-corejs3/core-js-stable/array/from";
|
13
13
|
import _mapInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/map";
|
14
|
+
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
14
15
|
|
15
16
|
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; }
|
16
17
|
|
@@ -57,9 +58,14 @@ export function useListLayout(state) {
|
|
57
58
|
return layout;
|
58
59
|
}
|
59
60
|
var ListView = /*#__PURE__*/forwardRef(function (props, ref) {
|
60
|
-
var
|
61
|
+
var disabledKeys = props.disabledKeys,
|
62
|
+
loadingState = props.loadingState,
|
61
63
|
onLoadMore = props.onLoadMore,
|
62
|
-
|
64
|
+
onSelectionChange = props.onSelectionChange,
|
65
|
+
selectionMode = props.selectionMode,
|
66
|
+
selectionStyle = props.selectionStyle,
|
67
|
+
others = _objectWithoutProperties(props, ["disabledKeys", "loadingState", "onLoadMore", "onSelectionChange", "selectionMode", "selectionStyle"]);
|
68
|
+
|
63
69
|
var isLoading = loadingState === loadingStates.LOADING_MORE || loadingState === loadingStates.LOADING;
|
64
70
|
|
65
71
|
var renderWrapper = function renderWrapper(parent, reusableView) {
|
@@ -122,8 +128,7 @@ var ListView = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
122
128
|
disabledKeys: state.disabledKeys,
|
123
129
|
ref: listViewRef,
|
124
130
|
direction: direction,
|
125
|
-
collator: collator
|
126
|
-
focusMode: 'cell'
|
131
|
+
collator: collator
|
127
132
|
});
|
128
133
|
}, [state, listViewRef, direction, collator]);
|
129
134
|
|
@@ -136,13 +141,7 @@ var ListView = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
136
141
|
|
137
142
|
|
138
143
|
layout.isLoading = isLoading;
|
139
|
-
var
|
140
|
-
var focusedItem = gridCollection.getItem(state.selectionManager.focusedKey);
|
141
|
-
|
142
|
-
if ((focusedItem === null || focusedItem === void 0 ? void 0 : focusedItem.parentKey) != null) {
|
143
|
-
focusedKey = focusedItem.parentKey;
|
144
|
-
}
|
145
|
-
|
144
|
+
var focusedItem = gridCollection.getFirstKey();
|
146
145
|
return ___EmotionJSX(ListViewContext.Provider, {
|
147
146
|
value: {
|
148
147
|
state: state,
|
@@ -151,7 +150,7 @@ var ListView = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
151
150
|
}, ___EmotionJSX(Virtualizer, _extends({}, gridProps, {
|
152
151
|
onLoadMore: onLoadMore,
|
153
152
|
ref: listViewRef,
|
154
|
-
focusedKey:
|
153
|
+
focusedKey: focusedItem === null || focusedItem === void 0 ? void 0 : focusedItem.parentKey,
|
155
154
|
renderWrapper: renderWrapper,
|
156
155
|
sizeToFit: "height",
|
157
156
|
scrollDirection: "vertical",
|
@@ -159,7 +158,7 @@ var ListView = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
159
158
|
isLoading: isLoading,
|
160
159
|
collection: gridCollection,
|
161
160
|
transitionDuration: 0
|
162
|
-
}), function (type, item) {
|
161
|
+
}, others), function (type, item) {
|
163
162
|
if (type === 'item') {
|
164
163
|
return ___EmotionJSX(ListViewItem, {
|
165
164
|
item: item
|
@@ -106,13 +106,13 @@ test('navigating the list using the keyboard causes the isSelected and isFocused
|
|
106
106
|
userEvent.type(listView, '{arrowdown}', {
|
107
107
|
skipClick: true
|
108
108
|
});
|
109
|
-
options = screen.getAllByRole('
|
109
|
+
options = screen.getAllByRole('gridcell');
|
110
110
|
expect(options[1]).toHaveClass('is-focused');
|
111
111
|
userEvent.type(listView, '{enter}', {
|
112
112
|
skipClick: true
|
113
113
|
});
|
114
114
|
_context.next = 9;
|
115
|
-
return screen.findAllByRole('
|
115
|
+
return screen.findAllByRole('gridcell');
|
116
116
|
|
117
117
|
case 9:
|
118
118
|
updatedOption = _context.sent;
|
@@ -141,7 +141,7 @@ test('navigating to a disabled key will not apply the isFocused class', /*#__PUR
|
|
141
141
|
userEvent.type(listView, '{arrowdown}', {
|
142
142
|
skipClick: true
|
143
143
|
});
|
144
|
-
options = screen.getAllByRole('
|
144
|
+
options = screen.getAllByRole('gridcell');
|
145
145
|
expect(options[1]).not.toHaveClass('is-focused');
|
146
146
|
|
147
147
|
case 6:
|
@@ -161,7 +161,7 @@ test('clicking an item on the list selects the item', /*#__PURE__*/_asyncToGener
|
|
161
161
|
options = screen.getByTestId(items[1].name);
|
162
162
|
userEvent.click(options);
|
163
163
|
_context3.next = 5;
|
164
|
-
return screen.findAllByRole('
|
164
|
+
return screen.findAllByRole('gridcell');
|
165
165
|
|
166
166
|
case 5:
|
167
167
|
updatedOption = _context3.sent;
|
@@ -222,11 +222,11 @@ test('does not render loader, if loadingState is not loadingMore', function () {
|
|
222
222
|
test('renders neither loader nor item if the component is given no items nor a loading state prop', function () {
|
223
223
|
getComponentEmpty();
|
224
224
|
expect(screen.queryByRole('progressbar')).not.toBeInTheDocument();
|
225
|
-
expect(screen.queryByRole('
|
225
|
+
expect(screen.queryByRole('gridcell')).not.toBeInTheDocument();
|
226
226
|
});
|
227
227
|
test('Item accepts a data-id and the data-id can be found in the DOM', function () {
|
228
228
|
getComponent();
|
229
|
-
var options = screen.getAllByRole('
|
229
|
+
var options = screen.getAllByRole('gridcell');
|
230
230
|
expect(options).toHaveLength(items.length);
|
231
231
|
expect(options[0]).toHaveAttribute('data-id', items[0].name);
|
232
232
|
});
|
@@ -242,7 +242,7 @@ test('selectionMode "none" disallows to select item', /*#__PURE__*/_asyncToGener
|
|
242
242
|
option1 = screen.getByTestId(items[1].name);
|
243
243
|
userEvent.click(option1);
|
244
244
|
_context5.next = 5;
|
245
|
-
return screen.findAllByRole('
|
245
|
+
return screen.findAllByRole('gridcell');
|
246
246
|
|
247
247
|
case 5:
|
248
248
|
updatedOption = _context5.sent;
|
@@ -269,7 +269,7 @@ test('selectionMode "multiple" allows to select more than one item', /*#__PURE__
|
|
269
269
|
option2 = screen.getByTestId(items[2].name);
|
270
270
|
userEvent.click(option2);
|
271
271
|
_context6.next = 7;
|
272
|
-
return screen.findAllByRole('
|
272
|
+
return screen.findAllByRole('gridcell');
|
273
273
|
|
274
274
|
case 7:
|
275
275
|
updatedOption = _context6.sent;
|
@@ -81,7 +81,6 @@ var ListViewItem = function ListViewItem(props) {
|
|
81
81
|
classNames = _useStatusClasses.classNames;
|
82
82
|
|
83
83
|
return ___EmotionJSX(React.Fragment, null, ___EmotionJSX(Box, _extends({
|
84
|
-
as: "li",
|
85
84
|
isDisabled: isDisabled,
|
86
85
|
isRow: true
|
87
86
|
}, raRowProps, {
|
@@ -90,7 +89,6 @@ var ListViewItem = function ListViewItem(props) {
|
|
90
89
|
as: "div",
|
91
90
|
ref: cellRef
|
92
91
|
}, mergedProps, {
|
93
|
-
role: "listitem",
|
94
92
|
variant: "boxes.listViewItem",
|
95
93
|
isFocused: isDisabled ? false : isFocusVisible,
|
96
94
|
isDisabled: isDisabled,
|
@@ -0,0 +1,118 @@
|
|
1
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
2
|
+
import _objectWithoutProperties from "@babel/runtime-corejs3/helpers/esm/objectWithoutProperties";
|
3
|
+
import React, { forwardRef } from 'react';
|
4
|
+
import PropTypes from 'prop-types';
|
5
|
+
import { useFocusRing } from '@react-aria/focus';
|
6
|
+
import { mergeProps } from '@react-aria/utils';
|
7
|
+
import { isIterableProp } from '../../utils/devUtils/props/isIterable';
|
8
|
+
import { useStatusClasses } from '../../hooks';
|
9
|
+
import MultiselectBadge from '../MultiselectListContainer/MultiselectBadge';
|
10
|
+
import { Box, ListView, MultiselectListContainer, Text } from '../../index';
|
11
|
+
/**
|
12
|
+
* The MultiselectFilter serves as a filter menu with a menu title
|
13
|
+
* and selected count displayed in a badge.
|
14
|
+
*/
|
15
|
+
|
16
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
17
|
+
var MultiselectFilter = /*#__PURE__*/forwardRef(function (props, ref) {
|
18
|
+
var selectedFilterCount = props.selectedFilterCount,
|
19
|
+
className = props.className,
|
20
|
+
closeAriaLabel = props.closeAriaLabel,
|
21
|
+
children = props.children,
|
22
|
+
isDefaultOpen = props.isDefaultOpen,
|
23
|
+
isOpen = props.isOpen,
|
24
|
+
items = props.items,
|
25
|
+
listTitle = props.listTitle,
|
26
|
+
onOpenChange = props.onOpenChange,
|
27
|
+
onSelectionChange = props.onSelectionChange,
|
28
|
+
openAriaLabel = props.openAriaLabel,
|
29
|
+
others = _objectWithoutProperties(props, ["selectedFilterCount", "className", "closeAriaLabel", "children", "isDefaultOpen", "isOpen", "items", "listTitle", "onOpenChange", "onSelectionChange", "openAriaLabel"]);
|
30
|
+
|
31
|
+
var _useFocusRing = useFocusRing({
|
32
|
+
within: true
|
33
|
+
}),
|
34
|
+
focusWithinProps = _useFocusRing.focusProps;
|
35
|
+
|
36
|
+
var _useFocusRing2 = useFocusRing(),
|
37
|
+
focusProps = _useFocusRing2.focusProps,
|
38
|
+
isFocusVisible = _useFocusRing2.isFocusVisible;
|
39
|
+
|
40
|
+
var mergedProps = mergeProps(focusWithinProps, focusProps);
|
41
|
+
|
42
|
+
var _useStatusClasses = useStatusClasses(className, {
|
43
|
+
isFocused: isFocusVisible
|
44
|
+
}),
|
45
|
+
classNames = _useStatusClasses.classNames;
|
46
|
+
|
47
|
+
return ___EmotionJSX(MultiselectListContainer, {
|
48
|
+
closeAriaLabel: closeAriaLabel,
|
49
|
+
isDefaultOpen: isDefaultOpen,
|
50
|
+
isOpen: isOpen,
|
51
|
+
onOpenChange: onOpenChange,
|
52
|
+
openAriaLabel: openAriaLabel,
|
53
|
+
selectedFilterCount: selectedFilterCount
|
54
|
+
}, ___EmotionJSX(Box, _extends({
|
55
|
+
className: classNames,
|
56
|
+
"data-testid": "multiselect-filter",
|
57
|
+
ref: ref,
|
58
|
+
tabIndex: 0,
|
59
|
+
variant: "multiselectListContainer.multiselectListContent"
|
60
|
+
}, mergedProps, others), ___EmotionJSX(Box, {
|
61
|
+
isRow: true,
|
62
|
+
variant: "multiselectListContainer.multiselectListTitle"
|
63
|
+
}, ___EmotionJSX(Text, {
|
64
|
+
variant: "multiselectFilterTitle"
|
65
|
+
}, listTitle), selectedFilterCount && ___EmotionJSX(MultiselectBadge, {
|
66
|
+
margin: "0",
|
67
|
+
selectedFilterCount: selectedFilterCount
|
68
|
+
})), ___EmotionJSX(Box, {
|
69
|
+
pl: "xs",
|
70
|
+
pr: "xs"
|
71
|
+
}, ___EmotionJSX(ListView, {
|
72
|
+
items: items,
|
73
|
+
onSelectionChange: onSelectionChange,
|
74
|
+
selectionMode: "multiple",
|
75
|
+
style: {
|
76
|
+
width: '100%'
|
77
|
+
},
|
78
|
+
pl: "md"
|
79
|
+
}, children))));
|
80
|
+
});
|
81
|
+
MultiselectFilter.propTypes = {
|
82
|
+
/** Amount of selected items indicator. */
|
83
|
+
selectedFilterCount: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
84
|
+
|
85
|
+
/** Title of list content. */
|
86
|
+
listTitle: PropTypes.string,
|
87
|
+
|
88
|
+
/** Defines a string value that labels the trigger icon when menu is open. */
|
89
|
+
closeAriaLabel: PropTypes.string,
|
90
|
+
|
91
|
+
/** Sets the default open state of the overlay. */
|
92
|
+
isDefaultOpen: PropTypes.bool,
|
93
|
+
|
94
|
+
/** Whether the overlay is currently open. */
|
95
|
+
isOpen: PropTypes.bool,
|
96
|
+
|
97
|
+
/** The list of ListView items (controlled). */
|
98
|
+
items: isIterableProp,
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Method that is called when the open state of the menu changes.
|
102
|
+
* Returns the new open state and the action that caused the opening of the menu.
|
103
|
+
*
|
104
|
+
* `(isOpen: boolean, overlayTrigger: OverlayTriggerAction) => void`
|
105
|
+
*/
|
106
|
+
onOpenChange: PropTypes.func,
|
107
|
+
|
108
|
+
/** Callback function that fires when the selected key changes. */
|
109
|
+
onSelectionChange: PropTypes.func,
|
110
|
+
|
111
|
+
/** Defines a string value that labels the trigger icon when menu is closed. */
|
112
|
+
openAriaLabel: PropTypes.string
|
113
|
+
};
|
114
|
+
MultiselectFilter.defaultProps = {
|
115
|
+
isDefaultOpen: true
|
116
|
+
};
|
117
|
+
MultiselectFilter.displayName = 'MultiselectFilter';
|
118
|
+
export default MultiselectFilter;
|
@@ -0,0 +1,251 @@
|
|
1
|
+
import _extends from "@babel/runtime-corejs3/helpers/esm/extends";
|
2
|
+
import React, { useRef } from 'react';
|
3
|
+
import AccountGroupIcon from 'mdi-react/AccountGroupIcon';
|
4
|
+
import Clear from 'mdi-react/CloseIcon';
|
5
|
+
import ChevronRightIcon from 'mdi-react/ChevronRightIcon';
|
6
|
+
import FilterIcon from 'mdi-react/FilterIcon';
|
7
|
+
import SearchIcon from 'mdi-react/SearchIcon';
|
8
|
+
import PersonIcon from 'mdi-react/PersonIcon';
|
9
|
+
import MultiselectFilter from './MultiselectFilter';
|
10
|
+
import { useOverlayPanelState } from '../../hooks';
|
11
|
+
import { Breadcrumbs, Box, Button, Chip, ListView, Item, Icon, IconButton, MultiselectFilterItem, OverlayPanel, OverlayProvider, SearchField, Text } from '../../index';
|
12
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
13
|
+
export default {
|
14
|
+
title: 'MultiselectFilter',
|
15
|
+
component: MultiselectFilter,
|
16
|
+
argTypes: {
|
17
|
+
listTitle: {
|
18
|
+
defaultValue: 'Selected Groups'
|
19
|
+
},
|
20
|
+
openAriaLabel: {
|
21
|
+
defaultValue: 'Open filter menu?'
|
22
|
+
},
|
23
|
+
closeAriaLabel: {
|
24
|
+
defaultValue: 'Close filter menu?'
|
25
|
+
},
|
26
|
+
isDefaultOpen: {},
|
27
|
+
isOpen: {
|
28
|
+
onClick: {
|
29
|
+
action: 'clicked'
|
30
|
+
},
|
31
|
+
control: {
|
32
|
+
type: 'none'
|
33
|
+
}
|
34
|
+
}
|
35
|
+
}
|
36
|
+
};
|
37
|
+
var items = [{
|
38
|
+
id: '1',
|
39
|
+
icon: 'Group',
|
40
|
+
key: 'Avengers',
|
41
|
+
name: 'Avengers',
|
42
|
+
subtitle: 'Default',
|
43
|
+
chipValue: '25'
|
44
|
+
}, {
|
45
|
+
id: '2',
|
46
|
+
icon: 'Group',
|
47
|
+
key: 'Credit Cards',
|
48
|
+
name: 'Credit Cards',
|
49
|
+
subtitle: '',
|
50
|
+
chipValue: '123'
|
51
|
+
}, {
|
52
|
+
id: '3',
|
53
|
+
icon: 'Group',
|
54
|
+
key: 'Debit Cards',
|
55
|
+
name: 'Debit Cards',
|
56
|
+
subtitle: '',
|
57
|
+
chipValue: '23'
|
58
|
+
}, {
|
59
|
+
id: '4',
|
60
|
+
icon: 'Group',
|
61
|
+
key: 'Digital Investors',
|
62
|
+
name: 'Digital Investors',
|
63
|
+
subtitle: 'N America',
|
64
|
+
chipValue: '12'
|
65
|
+
}, {
|
66
|
+
id: '5',
|
67
|
+
icon: 'Group',
|
68
|
+
key: 'Mortgages',
|
69
|
+
name: 'Mortgages',
|
70
|
+
subtitle: 'N America',
|
71
|
+
chipValue: '112'
|
72
|
+
}, {
|
73
|
+
id: '6',
|
74
|
+
icon: 'Group',
|
75
|
+
key: 'Person LOC',
|
76
|
+
name: 'Person LOC',
|
77
|
+
subtitle: '',
|
78
|
+
chipValue: '45'
|
79
|
+
}, {
|
80
|
+
id: '7',
|
81
|
+
icon: 'Group',
|
82
|
+
key: 'Production',
|
83
|
+
name: 'Production',
|
84
|
+
subtitle: '',
|
85
|
+
chipValue: '55'
|
86
|
+
}, {
|
87
|
+
id: '8',
|
88
|
+
icon: 'Group',
|
89
|
+
key: 'UX Team',
|
90
|
+
name: 'UX Team',
|
91
|
+
subtitle: '',
|
92
|
+
chipValue: '61'
|
93
|
+
}, {
|
94
|
+
id: '9',
|
95
|
+
icon: 'Group',
|
96
|
+
key: 'UI Team',
|
97
|
+
name: 'UI Team',
|
98
|
+
subtitle: '',
|
99
|
+
chipValue: '29'
|
100
|
+
}];
|
101
|
+
var mockData = [{
|
102
|
+
id: '10',
|
103
|
+
key: 'Avengers',
|
104
|
+
name: 'Avengers'
|
105
|
+
}, {
|
106
|
+
id: '11',
|
107
|
+
key: 'Digital Investors',
|
108
|
+
name: 'Digital Investors'
|
109
|
+
}, {
|
110
|
+
id: '12',
|
111
|
+
key: 'A very long title as well',
|
112
|
+
name: 'A very long title as well'
|
113
|
+
}];
|
114
|
+
|
115
|
+
var changeSelection = function changeSelection(selected) {
|
116
|
+
console.log(selected);
|
117
|
+
};
|
118
|
+
|
119
|
+
export var Default = function Default(args) {
|
120
|
+
return ___EmotionJSX(MultiselectFilter, args);
|
121
|
+
};
|
122
|
+
export var MultiselectWithBadge = function MultiselectWithBadge(args) {
|
123
|
+
var _useOverlayPanelState = useOverlayPanelState(),
|
124
|
+
state = _useOverlayPanelState.state,
|
125
|
+
onClose = _useOverlayPanelState.onClose;
|
126
|
+
|
127
|
+
var triggerRef = useRef();
|
128
|
+
return ___EmotionJSX(OverlayProvider, null, ___EmotionJSX(Button, {
|
129
|
+
ref: triggerRef,
|
130
|
+
onPress: state.open
|
131
|
+
}, "Open Panel"), ___EmotionJSX(OverlayPanel, {
|
132
|
+
isOpen: state.isOpen,
|
133
|
+
size: "large",
|
134
|
+
p: "0"
|
135
|
+
}, ___EmotionJSX(Box, {
|
136
|
+
sx: {
|
137
|
+
minHeight: '60px'
|
138
|
+
},
|
139
|
+
bg: "accent.99"
|
140
|
+
}, ___EmotionJSX(Box, {
|
141
|
+
isRow: true,
|
142
|
+
flexBasis: "0px",
|
143
|
+
flexGrow: "1",
|
144
|
+
alignItems: "center",
|
145
|
+
pl: "md",
|
146
|
+
pr: "md",
|
147
|
+
justifyContent: "space-between",
|
148
|
+
zIndex: 2
|
149
|
+
}, ___EmotionJSX(Box, {
|
150
|
+
isRow: true
|
151
|
+
}, ___EmotionJSX(Icon, {
|
152
|
+
icon: PersonIcon,
|
153
|
+
alignSelf: "center",
|
154
|
+
mr: "md",
|
155
|
+
color: "accent.40",
|
156
|
+
size: 25,
|
157
|
+
flexShrink: 0,
|
158
|
+
display: "flex"
|
159
|
+
}), ___EmotionJSX(Breadcrumbs, {
|
160
|
+
icon: ChevronRightIcon
|
161
|
+
}, ___EmotionJSX(Item, {
|
162
|
+
key: "home",
|
163
|
+
variant: "link",
|
164
|
+
"data-id": "home"
|
165
|
+
}, "Ed Nepomuceno"), ___EmotionJSX(Item, {
|
166
|
+
key: "editGroups",
|
167
|
+
variant: "neutralText",
|
168
|
+
"data-id": "editGroups"
|
169
|
+
}, "Edit Groups"))), ___EmotionJSX(Box, {
|
170
|
+
isRow: true
|
171
|
+
}, ___EmotionJSX(IconButton, {
|
172
|
+
"aria-label": "Close Panel",
|
173
|
+
onPress: function onPress() {
|
174
|
+
onClose(state, triggerRef);
|
175
|
+
}
|
176
|
+
}, ___EmotionJSX(Icon, {
|
177
|
+
icon: Clear,
|
178
|
+
size: 20
|
179
|
+
}))))), ___EmotionJSX(Box, {
|
180
|
+
pl: "md",
|
181
|
+
pt: "25px"
|
182
|
+
}, ___EmotionJSX(Box, {
|
183
|
+
isRow: true,
|
184
|
+
justifyContent: "space-between"
|
185
|
+
}, ___EmotionJSX(Box, {
|
186
|
+
width: "100%"
|
187
|
+
}, ___EmotionJSX(SearchField, {
|
188
|
+
icon: SearchIcon,
|
189
|
+
"aria-label": "Search",
|
190
|
+
placeholder: "Search",
|
191
|
+
width: "100%",
|
192
|
+
mt: "0px",
|
193
|
+
mr: "sm"
|
194
|
+
}), ___EmotionJSX(ListView, {
|
195
|
+
items: items,
|
196
|
+
style: {
|
197
|
+
width: '108%'
|
198
|
+
}
|
199
|
+
}, function (item) {
|
200
|
+
return ___EmotionJSX(Item, {
|
201
|
+
key: item.key,
|
202
|
+
textValue: item.name,
|
203
|
+
"data-id": item.key,
|
204
|
+
listItemProps: {
|
205
|
+
sx: {
|
206
|
+
bg: 'white',
|
207
|
+
'&.is-hovered': {
|
208
|
+
bg: 'accent.99'
|
209
|
+
}
|
210
|
+
}
|
211
|
+
}
|
212
|
+
}, ___EmotionJSX(Box, {
|
213
|
+
isRow: true
|
214
|
+
}, ___EmotionJSX(Icon, {
|
215
|
+
icon: AccountGroupIcon,
|
216
|
+
alignSelf: "center",
|
217
|
+
mr: "md",
|
218
|
+
color: "accent.40",
|
219
|
+
size: 25,
|
220
|
+
flexShrink: 1
|
221
|
+
}), ___EmotionJSX(Box, null, ___EmotionJSX(Box, {
|
222
|
+
isRow: true
|
223
|
+
}, ___EmotionJSX(Text, {
|
224
|
+
variant: "listTitle",
|
225
|
+
mb: "xs",
|
226
|
+
mr: "xs"
|
227
|
+
}, item.name), ___EmotionJSX(Chip, {
|
228
|
+
label: item.chipValue,
|
229
|
+
bg: "accent.99",
|
230
|
+
textColor: "text.secondary",
|
231
|
+
sx: {
|
232
|
+
minWidth: 'max-content'
|
233
|
+
}
|
234
|
+
})), ___EmotionJSX(Text, {
|
235
|
+
variant: "listSubtitle"
|
236
|
+
}, item.subtitle))));
|
237
|
+
})), ___EmotionJSX(MultiselectFilter, _extends({
|
238
|
+
items: mockData,
|
239
|
+
onSelectionChange: changeSelection,
|
240
|
+
selectedFilterCount: "1000+"
|
241
|
+
}, args), function (item) {
|
242
|
+
return ___EmotionJSX(Item, {
|
243
|
+
key: item.key,
|
244
|
+
textValue: item.name,
|
245
|
+
"data-id": item.key
|
246
|
+
}, ___EmotionJSX(MultiselectFilterItem, {
|
247
|
+
text: item.name,
|
248
|
+
icon: FilterIcon
|
249
|
+
}));
|
250
|
+
})))));
|
251
|
+
};
|
@@ -0,0 +1,69 @@
|
|
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 MultiselectFilter from './MultiselectFilter';
|
6
|
+
import { jsx as ___EmotionJSX } from "@emotion/react";
|
7
|
+
var testId = 'multiselect-filter-item';
|
8
|
+
var onSelectionChange = jest.fn();
|
9
|
+
var defaultProps = {
|
10
|
+
'data-testid': testId,
|
11
|
+
isOpen: true,
|
12
|
+
items: [{
|
13
|
+
name: 'item name'
|
14
|
+
}],
|
15
|
+
listTitle: 'Selected Groups',
|
16
|
+
selectedFilterCount: 8,
|
17
|
+
onSelectionChange: onSelectionChange
|
18
|
+
};
|
19
|
+
|
20
|
+
var getComponent = function getComponent() {
|
21
|
+
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
22
|
+
return render(___EmotionJSX(MultiselectFilter, _extends({}, defaultProps, props)));
|
23
|
+
};
|
24
|
+
|
25
|
+
beforeAll(function () {
|
26
|
+
jest.spyOn(window.HTMLElement.prototype, 'clientWidth', 'get').mockImplementation(function () {
|
27
|
+
return 1000;
|
28
|
+
});
|
29
|
+
jest.spyOn(window.HTMLElement.prototype, 'clientHeight', 'get').mockImplementation(function () {
|
30
|
+
return 1000;
|
31
|
+
});
|
32
|
+
window.HTMLElement.prototype.scrollIntoView = jest.fn();
|
33
|
+
jest.spyOn(window.screen, 'width', 'get').mockImplementation(function () {
|
34
|
+
return 1024;
|
35
|
+
});
|
36
|
+
jest.spyOn(window, 'requestAnimationFrame').mockImplementation(function (cb) {
|
37
|
+
return cb();
|
38
|
+
});
|
39
|
+
});
|
40
|
+
afterEach(function () {
|
41
|
+
jest.clearAllMocks();
|
42
|
+
onSelectionChange.mockClear();
|
43
|
+
});
|
44
|
+
afterAll(function () {
|
45
|
+
jest.restoreAllMocks();
|
46
|
+
}); // Need to be added to each test file to test accessibility using axe.
|
47
|
+
|
48
|
+
axeTest(getComponent, {
|
49
|
+
rules: {
|
50
|
+
'aria-required-children': {
|
51
|
+
enabled: false
|
52
|
+
},
|
53
|
+
'aria-required-parent': {
|
54
|
+
enabled: false
|
55
|
+
}
|
56
|
+
}
|
57
|
+
});
|
58
|
+
test('default multiselectFilter', function () {
|
59
|
+
getComponent();
|
60
|
+
var multiselectFilter = screen.getByTestId(testId);
|
61
|
+
expect(multiselectFilter).toBeInTheDocument();
|
62
|
+
});
|
63
|
+
test('custom classname can be passed', function () {
|
64
|
+
getComponent({
|
65
|
+
className: 'testing-class'
|
66
|
+
});
|
67
|
+
var multiselectFilter = screen.getByTestId(testId);
|
68
|
+
expect(multiselectFilter).toHaveClass('testing-class');
|
69
|
+
});
|
@@ -0,0 +1 @@
|
|
1
|
+
export { default } from './MultiselectFilter';
|