@dhis2-ui/select 10.13.0-alpha.1 → 10.13.1
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/build/cjs/locales/en/translations.json +2 -0
- package/build/cjs/multi-select/input.js +20 -11
- package/build/cjs/multi-select/multi-select.js +5 -1
- package/build/cjs/multi-select/multi-select.prod.stories.js +42 -1
- package/build/cjs/simple-single-select/menu/filter.js +23 -36
- package/build/cjs/simple-single-select/menu/menu.js +4 -36
- package/build/cjs/simple-single-select/menu/options-list.js +5 -13
- package/build/cjs/simple-single-select/selected-value/selected-value.js +26 -1
- package/build/cjs/simple-single-select/simple-single-select.js +20 -16
- package/build/cjs/simple-single-select/use-handle-key-press/use-handle-key-press-on-combobox.js +24 -15
- package/build/cjs/simple-single-select/use-handle-key-press/use-handle-key-press-on-filter-input.js +1 -3
- package/build/cjs/simple-single-select-field/simple-single-select-field.js +23 -3
- package/build/cjs/simple-single-select-field/simple-single-select-field.test.js +5 -2
- package/build/es/locales/en/translations.json +2 -0
- package/build/es/multi-select/input.js +16 -7
- package/build/es/multi-select/multi-select.js +5 -1
- package/build/es/multi-select/multi-select.prod.stories.js +40 -0
- package/build/es/simple-single-select/menu/filter.js +22 -33
- package/build/es/simple-single-select/menu/menu.js +4 -36
- package/build/es/simple-single-select/menu/options-list.js +5 -13
- package/build/es/simple-single-select/selected-value/selected-value.js +26 -1
- package/build/es/simple-single-select/simple-single-select.js +20 -16
- package/build/es/simple-single-select/use-handle-key-press/use-handle-key-press-on-combobox.js +24 -15
- package/build/es/simple-single-select/use-handle-key-press/use-handle-key-press-on-filter-input.js +1 -3
- package/build/es/simple-single-select-field/simple-single-select-field.js +23 -3
- package/build/es/simple-single-select-field/simple-single-select-field.test.js +5 -2
- package/package.json +15 -15
- package/types/index.d.ts +4 -0
package/build/cjs/simple-single-select/use-handle-key-press/use-handle-key-press-on-combobox.js
CHANGED
|
@@ -10,12 +10,21 @@ var _useHandleTyping = require("./use-handle-typing.js");
|
|
|
10
10
|
var _usePageDown = require("./use-page-down.js");
|
|
11
11
|
var _usePageUp = require("./use-page-up.js");
|
|
12
12
|
var _utils = require("./utils.js");
|
|
13
|
-
function
|
|
13
|
+
function isUnmodifiedCharacterKey(_ref) {
|
|
14
|
+
let {
|
|
15
|
+
key,
|
|
16
|
+
altKey,
|
|
17
|
+
ctrlKey,
|
|
18
|
+
metaKey
|
|
19
|
+
} = _ref;
|
|
20
|
+
return key.length === 1 && key !== ' ' && !altKey && !ctrlKey && !metaKey;
|
|
21
|
+
}
|
|
22
|
+
function useSelectOption(findIndexCallback, _ref2) {
|
|
14
23
|
let {
|
|
15
24
|
options,
|
|
16
25
|
onChange,
|
|
17
26
|
value
|
|
18
|
-
} =
|
|
27
|
+
} = _ref2;
|
|
19
28
|
return (0, _react.useCallback)(() => {
|
|
20
29
|
const currentOptionIndex = options.findIndex(option => option.value === value);
|
|
21
30
|
const nextSelectedOptionIndex = findIndexCallback({
|
|
@@ -32,7 +41,7 @@ function useSelectOption(findIndexCallback, _ref) {
|
|
|
32
41
|
});
|
|
33
42
|
}, [findIndexCallback, options, onChange, value]);
|
|
34
43
|
}
|
|
35
|
-
function useHandleKeyPressOnCombobox(
|
|
44
|
+
function useHandleKeyPressOnCombobox(_ref3) {
|
|
36
45
|
let {
|
|
37
46
|
value,
|
|
38
47
|
disabled,
|
|
@@ -46,10 +55,11 @@ function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
46
55
|
setFocussedOptionIndex,
|
|
47
56
|
selectFocussedOption,
|
|
48
57
|
onChange,
|
|
49
|
-
filterRef,
|
|
50
58
|
clearable,
|
|
51
|
-
onClear
|
|
52
|
-
|
|
59
|
+
onClear,
|
|
60
|
+
filterable,
|
|
61
|
+
onFilterChange
|
|
62
|
+
} = _ref3;
|
|
53
63
|
const {
|
|
54
64
|
onTyping,
|
|
55
65
|
typing
|
|
@@ -104,9 +114,7 @@ function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
104
114
|
const handleKeyPress = (0, _react.useCallback)(event => {
|
|
105
115
|
const {
|
|
106
116
|
key,
|
|
107
|
-
altKey
|
|
108
|
-
ctrlKey,
|
|
109
|
-
metaKey
|
|
117
|
+
altKey
|
|
110
118
|
} = event;
|
|
111
119
|
if (disabled || loading) {
|
|
112
120
|
return;
|
|
@@ -160,10 +168,6 @@ function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
160
168
|
return;
|
|
161
169
|
}
|
|
162
170
|
if (key === 'ArrowUp') {
|
|
163
|
-
if (filterRef !== null && filterRef !== void 0 && filterRef.current && focussedOptionIndex === 0) {
|
|
164
|
-
filterRef.current.focus();
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
171
|
focusPrevOption();
|
|
168
172
|
return;
|
|
169
173
|
}
|
|
@@ -175,7 +179,12 @@ function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
175
179
|
focusLastOption();
|
|
176
180
|
return;
|
|
177
181
|
}
|
|
178
|
-
if (
|
|
182
|
+
if (filterable && !expanded && isUnmodifiedCharacterKey(event)) {
|
|
183
|
+
openMenu();
|
|
184
|
+
onFilterChange === null || onFilterChange === void 0 ? void 0 : onFilterChange(key);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (key === 'Backspace' || key === 'Clear' || isUnmodifiedCharacterKey(event) || key === ' ' && typing) {
|
|
179
188
|
onTyping(key);
|
|
180
189
|
return;
|
|
181
190
|
}
|
|
@@ -189,6 +198,6 @@ function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
189
198
|
}
|
|
190
199
|
|
|
191
200
|
// Do nothing
|
|
192
|
-
}, [closeMenu, disabled, expanded, loading, openMenu, options, value, typing, focussedOptionIndex, selectFocussedOption, selectNextOption, selectPrevOption, focusNextOption, focusPrevOption, focusFirstOption, focusLastOption, pageDown, pageUp, onTyping,
|
|
201
|
+
}, [closeMenu, disabled, expanded, loading, openMenu, options, value, typing, focussedOptionIndex, selectFocussedOption, selectNextOption, selectPrevOption, focusNextOption, focusPrevOption, focusFirstOption, focusLastOption, pageDown, pageUp, onTyping, filterable, onFilterChange]);
|
|
193
202
|
return handleKeyPress;
|
|
194
203
|
}
|
package/build/cjs/simple-single-select/use-handle-key-press/use-handle-key-press-on-filter-input.js
CHANGED
|
@@ -72,10 +72,8 @@ function useHandleKeyPressOnFilterInput(_ref) {
|
|
|
72
72
|
return;
|
|
73
73
|
}
|
|
74
74
|
if (key === 'ArrowDown') {
|
|
75
|
-
var _listBoxRef$current;
|
|
76
75
|
e.preventDefault(); // Disable moving cursor to end
|
|
77
76
|
focusNextOption();
|
|
78
|
-
(_listBoxRef$current = listBoxRef.current) === null || _listBoxRef$current === void 0 ? void 0 : _listBoxRef$current.focus();
|
|
79
77
|
return;
|
|
80
78
|
}
|
|
81
79
|
if (key === 'ArrowUp') {
|
|
@@ -103,6 +101,6 @@ function useHandleKeyPressOnFilterInput(_ref) {
|
|
|
103
101
|
}
|
|
104
102
|
|
|
105
103
|
// Do nothing
|
|
106
|
-
}, [closeMenu, options, value, loading, focussedOptionIndex, selectFocussedOption, focusComboBox, focusNextOption, focusPrevOption, focusFirstOption, focusLastOption, pageDown, pageUp
|
|
104
|
+
}, [closeMenu, options, value, loading, focussedOptionIndex, selectFocussedOption, focusComboBox, focusNextOption, focusPrevOption, focusFirstOption, focusLastOption, pageDown, pageUp]);
|
|
107
105
|
return handleKeyPress;
|
|
108
106
|
}
|
|
@@ -13,6 +13,7 @@ var _index = require("../simple-single-select/index.js");
|
|
|
13
13
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
14
|
function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
|
|
15
15
|
function SimpleSingleSelectField(props) {
|
|
16
|
+
var _ref, _selectedOption$label;
|
|
16
17
|
const {
|
|
17
18
|
className,
|
|
18
19
|
dataTest,
|
|
@@ -21,12 +22,28 @@ function SimpleSingleSelectField(props) {
|
|
|
21
22
|
helpText,
|
|
22
23
|
label,
|
|
23
24
|
name,
|
|
25
|
+
onChange,
|
|
26
|
+
options,
|
|
24
27
|
required,
|
|
25
28
|
valid,
|
|
26
29
|
validationText,
|
|
30
|
+
value,
|
|
31
|
+
valueLabel,
|
|
27
32
|
warning
|
|
28
33
|
} = props;
|
|
29
34
|
const labelId = `${name}-label`;
|
|
35
|
+
const selectedOption = options.find(opt => opt.value === value);
|
|
36
|
+
const selected = value != null && value !== '' ? {
|
|
37
|
+
value,
|
|
38
|
+
label: (_ref = (_selectedOption$label = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _selectedOption$label !== void 0 ? _selectedOption$label : valueLabel) !== null && _ref !== void 0 ? _ref : ''
|
|
39
|
+
} : undefined;
|
|
40
|
+
const handleChange = option => {
|
|
41
|
+
var _option$value;
|
|
42
|
+
onChange((_option$value = option === null || option === void 0 ? void 0 : option.value) !== null && _option$value !== void 0 ? _option$value : '');
|
|
43
|
+
};
|
|
44
|
+
const handleClear = () => {
|
|
45
|
+
onChange('');
|
|
46
|
+
};
|
|
30
47
|
return /*#__PURE__*/_react.default.createElement(_field.Field, {
|
|
31
48
|
className: className,
|
|
32
49
|
dataTest: dataTest,
|
|
@@ -40,7 +57,10 @@ function SimpleSingleSelectField(props) {
|
|
|
40
57
|
warning: warning,
|
|
41
58
|
valid: valid
|
|
42
59
|
}, /*#__PURE__*/_react.default.createElement(_index.SimpleSingleSelect, _extends({}, props, {
|
|
43
|
-
labelledBy: labelId
|
|
60
|
+
labelledBy: labelId,
|
|
61
|
+
selected: selected,
|
|
62
|
+
onChange: handleChange,
|
|
63
|
+
onClear: handleClear
|
|
44
64
|
})));
|
|
45
65
|
}
|
|
46
66
|
SimpleSingleSelectField.propTypes = {
|
|
@@ -115,10 +135,10 @@ SimpleSingleSelectField.propTypes = {
|
|
|
115
135
|
* be used to supply the text to be shown.
|
|
116
136
|
**/
|
|
117
137
|
valueLabel: (0, _propTypes.requiredIf)(props => {
|
|
118
|
-
if (props.options.find(
|
|
138
|
+
if (props.options.find(_ref2 => {
|
|
119
139
|
let {
|
|
120
140
|
value
|
|
121
|
-
} =
|
|
141
|
+
} = _ref2;
|
|
122
142
|
return props.value === value;
|
|
123
143
|
})) {
|
|
124
144
|
return false;
|
|
@@ -26,7 +26,7 @@ describe('<SimpleSingleSelectField />', () => {
|
|
|
26
26
|
it('should forward props to the SimpleSingleSelect component', () => {
|
|
27
27
|
const options = [];
|
|
28
28
|
const optionComponent = () => null;
|
|
29
|
-
const onChange = ()
|
|
29
|
+
const onChange = jest.fn();
|
|
30
30
|
const onBlur = () => null;
|
|
31
31
|
const onEndReached = () => null;
|
|
32
32
|
const onFilterChange = () => null;
|
|
@@ -70,7 +70,10 @@ describe('<SimpleSingleSelectField />', () => {
|
|
|
70
70
|
}));
|
|
71
71
|
expect(_simpleSingleSelect.SimpleSingleSelect.mock.calls[0][0].name).toBe('foo');
|
|
72
72
|
expect(_simpleSingleSelect.SimpleSingleSelect.mock.calls[0][0].options).toBe(options);
|
|
73
|
-
|
|
73
|
+
_simpleSingleSelect.SimpleSingleSelect.mock.calls[0][0].onChange({
|
|
74
|
+
value: 'test'
|
|
75
|
+
});
|
|
76
|
+
expect(onChange).toHaveBeenCalledWith('test');
|
|
74
77
|
expect(_simpleSingleSelect.SimpleSingleSelect.mock.calls[0][0].autoFocus).toBe(false);
|
|
75
78
|
expect(_simpleSingleSelect.SimpleSingleSelect.mock.calls[0][0].className).toBe('');
|
|
76
79
|
expect(_simpleSingleSelect.SimpleSingleSelect.mock.calls[0][0].clearText).toBe('');
|
|
@@ -4,6 +4,7 @@ import { colors } from '@dhis2/ui-constants';
|
|
|
4
4
|
import cx from 'classnames';
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import React from 'react';
|
|
7
|
+
import i18n from '../locales/index.js';
|
|
7
8
|
import { InputClearButton, InputPlaceholder, InputPrefix } from '../select/index.js';
|
|
8
9
|
import { SelectionList } from './selection-list.js';
|
|
9
10
|
const Input = _ref => {
|
|
@@ -18,9 +19,11 @@ const Input = _ref => {
|
|
|
18
19
|
options,
|
|
19
20
|
className,
|
|
20
21
|
disabled,
|
|
21
|
-
inputMaxHeight = '100px'
|
|
22
|
+
inputMaxHeight = '100px',
|
|
23
|
+
collapseSelectionAfter
|
|
22
24
|
} = _ref;
|
|
23
25
|
const hasSelection = selected.length > 0;
|
|
26
|
+
const shouldCollapse = hasSelection && typeof collapseSelectionAfter === 'number' && selected.length > collapseSelectionAfter;
|
|
24
27
|
const onClear = e => {
|
|
25
28
|
const data = {
|
|
26
29
|
selected: []
|
|
@@ -29,30 +32,35 @@ const Input = _ref => {
|
|
|
29
32
|
onChange(data, e);
|
|
30
33
|
};
|
|
31
34
|
return /*#__PURE__*/React.createElement("div", {
|
|
32
|
-
className: _JSXStyle.dynamic([["
|
|
35
|
+
className: _JSXStyle.dynamic([["3188585639", [colors.grey900]], ["1331770409", [inputMaxHeight]]]) + " " + (cx('root', className) || "")
|
|
33
36
|
}, /*#__PURE__*/React.createElement(InputPrefix, {
|
|
34
37
|
prefix: prefix,
|
|
35
38
|
dataTest: `${dataTest}-prefix`
|
|
36
39
|
}), !hasSelection && !prefix && /*#__PURE__*/React.createElement(InputPlaceholder, {
|
|
37
40
|
placeholder: placeholder,
|
|
38
41
|
dataTest: `${dataTest}-placeholder`
|
|
39
|
-
}), hasSelection && /*#__PURE__*/React.createElement("
|
|
40
|
-
|
|
42
|
+
}), hasSelection && shouldCollapse && /*#__PURE__*/React.createElement("span", {
|
|
43
|
+
"data-test": `${dataTest}-selection-count`,
|
|
44
|
+
className: _JSXStyle.dynamic([["3188585639", [colors.grey900]], ["1331770409", [inputMaxHeight]]]) + " " + "collapsed-selection-text"
|
|
45
|
+
}, i18n.t('{{count}} selected', {
|
|
46
|
+
count: selected.length
|
|
47
|
+
})), hasSelection && !shouldCollapse && /*#__PURE__*/React.createElement("div", {
|
|
48
|
+
className: _JSXStyle.dynamic([["3188585639", [colors.grey900]], ["1331770409", [inputMaxHeight]]]) + " " + "root-input"
|
|
41
49
|
}, /*#__PURE__*/React.createElement(SelectionList, {
|
|
42
50
|
selected: selected,
|
|
43
51
|
onChange: onChange,
|
|
44
52
|
options: options,
|
|
45
53
|
disabled: disabled
|
|
46
54
|
})), hasSelection && clearable && !disabled && /*#__PURE__*/React.createElement("div", {
|
|
47
|
-
className: _JSXStyle.dynamic([["
|
|
55
|
+
className: _JSXStyle.dynamic([["3188585639", [colors.grey900]], ["1331770409", [inputMaxHeight]]]) + " " + "root-right"
|
|
48
56
|
}, /*#__PURE__*/React.createElement(InputClearButton, {
|
|
49
57
|
onClear: onClear,
|
|
50
58
|
clearText: clearText,
|
|
51
59
|
dataTest: `${dataTest}-clear`
|
|
52
60
|
})), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
53
|
-
id: "
|
|
61
|
+
id: "3188585639",
|
|
54
62
|
dynamic: [colors.grey900]
|
|
55
|
-
}, [`.root.__jsx-style-dynamic-selector{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:${colors.grey900};font-size:14px;line-height:16px;}`, ".root-input.__jsx-style-dynamic-selector{overflow-y:auto;-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:wrap;-ms-flex-flow:wrap;flex-flow:wrap;gap:4px;}", ".root-right.__jsx-style-dynamic-selector{margin-inline-start:auto;}"]), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
63
|
+
}, [`.root.__jsx-style-dynamic-selector{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;color:${colors.grey900};font-size:14px;line-height:16px;}`, ".root-input.__jsx-style-dynamic-selector{overflow-y:auto;-webkit-flex:1;-ms-flex:1;flex:1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:wrap;-ms-flex-flow:wrap;flex-flow:wrap;gap:4px;}", ".root-right.__jsx-style-dynamic-selector{margin-inline-start:auto;}", ".collapsed-selection-text.__jsx-style-dynamic-selector{-webkit-flex:1;-ms-flex:1;flex:1;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}"]), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
56
64
|
id: "1331770409",
|
|
57
65
|
dynamic: [inputMaxHeight]
|
|
58
66
|
}, [`.root-input.__jsx-style-dynamic-selector{max-height:${inputMaxHeight};}`]));
|
|
@@ -62,6 +70,7 @@ Input.propTypes = {
|
|
|
62
70
|
className: PropTypes.string,
|
|
63
71
|
clearText: requiredIf(props => props.clearable, PropTypes.string),
|
|
64
72
|
clearable: PropTypes.bool,
|
|
73
|
+
collapseSelectionAfter: PropTypes.number,
|
|
65
74
|
disabled: PropTypes.bool,
|
|
66
75
|
inputMaxHeight: PropTypes.string,
|
|
67
76
|
options: PropTypes.node,
|
|
@@ -39,6 +39,7 @@ const MultiSelect = _ref => {
|
|
|
39
39
|
noMatchText,
|
|
40
40
|
initialFocus,
|
|
41
41
|
dense,
|
|
42
|
+
collapseSelectionAfter,
|
|
42
43
|
dataTest = 'dhis2-uicore-multiselect'
|
|
43
44
|
} = _ref;
|
|
44
45
|
// If the select is filterable, use a filterable menu
|
|
@@ -65,7 +66,8 @@ const MultiSelect = _ref => {
|
|
|
65
66
|
dataTest: dataTest,
|
|
66
67
|
placeholder: placeholder,
|
|
67
68
|
prefix: prefix,
|
|
68
|
-
inputMaxHeight: inputMaxHeight
|
|
69
|
+
inputMaxHeight: inputMaxHeight,
|
|
70
|
+
collapseSelectionAfter: collapseSelectionAfter
|
|
69
71
|
}),
|
|
70
72
|
menu: menu,
|
|
71
73
|
tabIndex: tabIndex,
|
|
@@ -99,6 +101,8 @@ MultiSelect.propTypes = {
|
|
|
99
101
|
clearText: requiredIf(props => props.clearable, PropTypes.string),
|
|
100
102
|
/** Adds a 'clear' option to the menu */
|
|
101
103
|
clearable: PropTypes.bool,
|
|
104
|
+
/** When the number of selected items exceeds this threshold, chips are replaced with "X selected" text */
|
|
105
|
+
collapseSelectionAfter: PropTypes.number,
|
|
102
106
|
dataTest: PropTypes.string,
|
|
103
107
|
dense: PropTypes.bool,
|
|
104
108
|
disabled: PropTypes.bool,
|
|
@@ -494,6 +494,46 @@ export const ShiftedIntoView = args => /*#__PURE__*/React.createElement(React.Fr
|
|
|
494
494
|
})), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
495
495
|
id: "1828862170"
|
|
496
496
|
}, ["html,body,#root{position:relative;height:300px !important;max-height:300px;}", "#root{padding-top:130px !important;}"]));
|
|
497
|
+
export const CollapseSelectionAfterThreshold = () => {
|
|
498
|
+
const [selected, setSelected] = React.useState(['1', '3', '5']);
|
|
499
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
500
|
+
style: {
|
|
501
|
+
maxWidth: 400
|
|
502
|
+
}
|
|
503
|
+
}, /*#__PURE__*/React.createElement(MultiSelect, {
|
|
504
|
+
className: "select",
|
|
505
|
+
selected: selected,
|
|
506
|
+
onChange: _ref3 => {
|
|
507
|
+
let {
|
|
508
|
+
selected
|
|
509
|
+
} = _ref3;
|
|
510
|
+
return setSelected(selected);
|
|
511
|
+
},
|
|
512
|
+
collapseSelectionAfter: 2,
|
|
513
|
+
prefix: "Prefix text",
|
|
514
|
+
clearable: true,
|
|
515
|
+
clearText: "Clear all"
|
|
516
|
+
}, /*#__PURE__*/React.createElement(MultiSelectOption, {
|
|
517
|
+
value: "1",
|
|
518
|
+
label: "option one"
|
|
519
|
+
}), /*#__PURE__*/React.createElement(MultiSelectOption, {
|
|
520
|
+
value: "2",
|
|
521
|
+
label: "option two"
|
|
522
|
+
}), /*#__PURE__*/React.createElement(MultiSelectOption, {
|
|
523
|
+
value: "3",
|
|
524
|
+
label: "option three"
|
|
525
|
+
}), /*#__PURE__*/React.createElement(MultiSelectOption, {
|
|
526
|
+
value: "4",
|
|
527
|
+
label: "option four"
|
|
528
|
+
}), /*#__PURE__*/React.createElement(MultiSelectOption, {
|
|
529
|
+
value: "5",
|
|
530
|
+
label: "option five"
|
|
531
|
+
}), /*#__PURE__*/React.createElement(MultiSelectOption, {
|
|
532
|
+
value: "6",
|
|
533
|
+
label: "option six"
|
|
534
|
+
})));
|
|
535
|
+
};
|
|
536
|
+
CollapseSelectionAfterThreshold.storyName = 'Collapse selection after threshold';
|
|
497
537
|
export const RTL = args => {
|
|
498
538
|
useEffect(() => {
|
|
499
539
|
document.body.dir = 'rtl';
|
|
@@ -1,57 +1,46 @@
|
|
|
1
1
|
import _JSXStyle from "styled-jsx/style";
|
|
2
|
-
import { colors, spacers } from '@dhis2/ui-constants';
|
|
3
|
-
import { Input } from '@dhis2-ui/input';
|
|
4
2
|
import PropTypes from 'prop-types';
|
|
5
|
-
import React
|
|
3
|
+
import React from 'react';
|
|
6
4
|
import i18n from '../../locales/index.js';
|
|
7
|
-
export
|
|
5
|
+
export function Filter(_ref) {
|
|
8
6
|
let {
|
|
9
7
|
ariaControls,
|
|
10
8
|
dataTest,
|
|
9
|
+
inputRef,
|
|
11
10
|
label,
|
|
12
11
|
placeholder,
|
|
13
|
-
tabIndex,
|
|
14
12
|
value,
|
|
15
13
|
onChange,
|
|
16
|
-
onKeyDown
|
|
17
|
-
onFocus
|
|
14
|
+
onKeyDown
|
|
18
15
|
} = _ref;
|
|
19
|
-
return /*#__PURE__*/React.createElement("
|
|
20
|
-
|
|
21
|
-
className: _JSXStyle.dynamic([["3850436710", [colors.white, spacers.dp8, spacers.dp8, spacers.dp4, spacers.dp8]]])
|
|
22
|
-
}, /*#__PURE__*/React.createElement(Input, {
|
|
23
|
-
dense: true,
|
|
24
|
-
ref: ref,
|
|
25
|
-
tabIndex: tabIndex,
|
|
26
|
-
ariaControls: ariaControls,
|
|
27
|
-
ariaHaspopup: "listbox",
|
|
28
|
-
ariaLabel: label || i18n.t('Search options'),
|
|
29
|
-
dataTest: `${dataTest}-input`,
|
|
30
|
-
value: value,
|
|
31
|
-
onChange: _ref2 => {
|
|
32
|
-
let {
|
|
33
|
-
value
|
|
34
|
-
} = _ref2;
|
|
35
|
-
return onChange(value);
|
|
36
|
-
},
|
|
16
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("input", {
|
|
17
|
+
ref: inputRef,
|
|
37
18
|
type: "text",
|
|
38
19
|
name: "filter",
|
|
20
|
+
value: value,
|
|
39
21
|
placeholder: placeholder,
|
|
40
|
-
|
|
41
|
-
|
|
22
|
+
"aria-label": label || i18n.t('Search options'),
|
|
23
|
+
"aria-controls": ariaControls,
|
|
24
|
+
"aria-haspopup": "listbox",
|
|
25
|
+
"data-test": dataTest,
|
|
26
|
+
onChange: e => onChange(e.target.value),
|
|
27
|
+
onClick: e => e.stopPropagation(),
|
|
28
|
+
onKeyDown: e => {
|
|
29
|
+
e.stopPropagation();
|
|
30
|
+
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
|
|
31
|
+
},
|
|
32
|
+
className: "jsx-1122123784" + " " + "filter-input"
|
|
42
33
|
}), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
43
|
-
id: "
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
});
|
|
34
|
+
id: "1122123784"
|
|
35
|
+
}, [".filter-input.jsx-1122123784{-webkit-flex:1;-ms-flex:1;flex:1;border:none;outline:none;background:transparent;font-size:14px;line-height:16px;color:inherit;padding:0;min-width:0;}"]));
|
|
36
|
+
}
|
|
47
37
|
Filter.propTypes = {
|
|
48
38
|
ariaControls: PropTypes.string.isRequired,
|
|
39
|
+
inputRef: PropTypes.object.isRequired,
|
|
49
40
|
value: PropTypes.string.isRequired,
|
|
50
41
|
onChange: PropTypes.func.isRequired,
|
|
51
42
|
dataTest: PropTypes.string,
|
|
52
43
|
label: PropTypes.string,
|
|
53
44
|
placeholder: PropTypes.string,
|
|
54
|
-
tabIndex: PropTypes.string,
|
|
55
|
-
onFocus: PropTypes.func,
|
|
56
45
|
onKeyDown: PropTypes.func
|
|
57
46
|
};
|
|
@@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
|
|
|
6
6
|
import React, { useEffect, useState } from 'react';
|
|
7
7
|
import { optionProp } from '../shared-prop-types.js';
|
|
8
8
|
import { Empty } from './empty.js';
|
|
9
|
-
import { Filter } from './filter.js';
|
|
10
9
|
import { Loading } from './loading.js';
|
|
11
10
|
import { NoMatch } from './no-match.js';
|
|
12
11
|
import { OptionsList } from './options-list.js';
|
|
@@ -21,10 +20,7 @@ export function Menu(_ref) {
|
|
|
21
20
|
dataTest,
|
|
22
21
|
disabled,
|
|
23
22
|
empty,
|
|
24
|
-
filterLabel,
|
|
25
|
-
filterPlaceholder,
|
|
26
23
|
filterValue,
|
|
27
|
-
filterable,
|
|
28
24
|
hidden,
|
|
29
25
|
labelledBy,
|
|
30
26
|
listBoxRef,
|
|
@@ -35,14 +31,9 @@ export function Menu(_ref) {
|
|
|
35
31
|
optionUpdateStrategy,
|
|
36
32
|
selectRef,
|
|
37
33
|
selectedValue,
|
|
38
|
-
tabIndex,
|
|
39
34
|
onBlur,
|
|
40
35
|
onClose,
|
|
41
|
-
onEndReached
|
|
42
|
-
onFilterChange,
|
|
43
|
-
onFilterInputKeyDown,
|
|
44
|
-
filterRef,
|
|
45
|
-
onOptionsKeyDown
|
|
36
|
+
onEndReached
|
|
46
37
|
} = _ref;
|
|
47
38
|
const [menuWidth, setWidth] = useState('auto');
|
|
48
39
|
const dataTestPrefix = `${dataTest}-menu`;
|
|
@@ -76,25 +67,12 @@ export function Menu(_ref) {
|
|
|
76
67
|
maxHeight
|
|
77
68
|
},
|
|
78
69
|
className: _JSXStyle.dynamic([["2949029222", [colors.white, colors.grey200, elevations.e300]]]) + " " + "menu"
|
|
79
|
-
},
|
|
80
|
-
className: _JSXStyle.dynamic([["2949029222", [colors.white, colors.grey200, elevations.e300]]]) + " " + "filter-container"
|
|
81
|
-
}, /*#__PURE__*/React.createElement(Filter, {
|
|
82
|
-
ref: filterRef,
|
|
83
|
-
dataTest: `${dataTestPrefix}-filter`,
|
|
84
|
-
value: filterValue,
|
|
85
|
-
label: filterLabel,
|
|
86
|
-
ariaControls: `${name}-listbox`,
|
|
87
|
-
placeholder: filterPlaceholder,
|
|
88
|
-
tabIndex: tabIndex,
|
|
89
|
-
onChange: onFilterChange,
|
|
90
|
-
onKeyDown: onFilterInputKeyDown
|
|
91
|
-
})), isEmpty && /*#__PURE__*/React.createElement(Empty, null, empty), hasNoFilterMatch && /*#__PURE__*/React.createElement(NoMatch, null, noMatchText), /*#__PURE__*/React.createElement("div", {
|
|
70
|
+
}, isEmpty && /*#__PURE__*/React.createElement(Empty, null, empty), hasNoFilterMatch && /*#__PURE__*/React.createElement(NoMatch, null, noMatchText), /*#__PURE__*/React.createElement("div", {
|
|
92
71
|
className: _JSXStyle.dynamic([["2949029222", [colors.white, colors.grey200, elevations.e300]]]) + " " + "listbox-container"
|
|
93
72
|
}, /*#__PURE__*/React.createElement("div", {
|
|
94
73
|
className: _JSXStyle.dynamic([["2949029222", [colors.white, colors.grey200, elevations.e300]]]) + " " + "listbox-wrapper"
|
|
95
74
|
}, /*#__PURE__*/React.createElement(OptionsList, {
|
|
96
75
|
ref: listBoxRef,
|
|
97
|
-
onKeyDown: onOptionsKeyDown,
|
|
98
76
|
comboBoxId: comboBoxId,
|
|
99
77
|
optionComponent: optionComponent,
|
|
100
78
|
dataTest: `${dataTestPrefix}-list`,
|
|
@@ -126,16 +104,11 @@ Menu.propTypes = {
|
|
|
126
104
|
}).isRequired,
|
|
127
105
|
name: PropTypes.string.isRequired,
|
|
128
106
|
options: PropTypes.arrayOf(optionProp).isRequired,
|
|
107
|
+
onChange: PropTypes.func.isRequired,
|
|
129
108
|
dataTest: PropTypes.string,
|
|
130
109
|
disabled: PropTypes.bool,
|
|
131
110
|
empty: PropTypes.node,
|
|
132
|
-
filterLabel: PropTypes.string,
|
|
133
|
-
filterPlaceholder: PropTypes.string,
|
|
134
|
-
filterRef: PropTypes.shape({
|
|
135
|
-
current: PropTypes.instanceOf(HTMLElement)
|
|
136
|
-
}),
|
|
137
111
|
filterValue: PropTypes.string,
|
|
138
|
-
filterable: PropTypes.bool,
|
|
139
112
|
hidden: PropTypes.bool,
|
|
140
113
|
labelledBy: PropTypes.string,
|
|
141
114
|
loading: PropTypes.bool,
|
|
@@ -146,12 +119,7 @@ Menu.propTypes = {
|
|
|
146
119
|
optionUpdateStrategy: PropTypes.oneOf(['off', 'polite', 'assertive']),
|
|
147
120
|
selectRef: PropTypes.instanceOf(HTMLElement),
|
|
148
121
|
selectedValue: PropTypes.string,
|
|
149
|
-
tabIndex: PropTypes.string,
|
|
150
122
|
onBlur: PropTypes.func,
|
|
151
|
-
onChange: PropTypes.func,
|
|
152
123
|
onClose: PropTypes.func,
|
|
153
|
-
onEndReached: PropTypes.func
|
|
154
|
-
onFilterChange: PropTypes.func,
|
|
155
|
-
onFilterInputKeyDown: PropTypes.func,
|
|
156
|
-
onOptionsKeyDown: PropTypes.func
|
|
124
|
+
onEndReached: PropTypes.func
|
|
157
125
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _JSXStyle from "styled-jsx/style";
|
|
2
1
|
import PropTypes from 'prop-types';
|
|
3
2
|
import React, { forwardRef, useEffect } from 'react';
|
|
4
3
|
import { isOptionHidden } from '../is-option-hidden.js';
|
|
@@ -19,8 +18,7 @@ export const OptionsList = /*#__PURE__*/forwardRef(function OptionsList(_ref, re
|
|
|
19
18
|
loading,
|
|
20
19
|
onChange,
|
|
21
20
|
onBlur,
|
|
22
|
-
onEndReached
|
|
23
|
-
onKeyDown
|
|
21
|
+
onEndReached
|
|
24
22
|
} = _ref;
|
|
25
23
|
// scrolls the highlighted option into view when:
|
|
26
24
|
// * the highlighted option changes
|
|
@@ -41,15 +39,12 @@ export const OptionsList = /*#__PURE__*/forwardRef(function OptionsList(_ref, re
|
|
|
41
39
|
return /*#__PURE__*/React.createElement("div", {
|
|
42
40
|
ref: ref,
|
|
43
41
|
role: "listbox",
|
|
44
|
-
tabIndex: "-1",
|
|
45
42
|
id: id,
|
|
46
43
|
"aria-labelledby": labelledBy,
|
|
47
44
|
"aria-live": optionUpdateStrategy,
|
|
48
45
|
"aria-busy": loading.toString(),
|
|
49
46
|
"data-test": dataTest,
|
|
50
|
-
onBlur: onBlur
|
|
51
|
-
onKeyDown: onKeyDown,
|
|
52
|
-
className: "jsx-233683301"
|
|
47
|
+
onBlur: onBlur
|
|
53
48
|
}, options.map((_ref2, index) => {
|
|
54
49
|
let {
|
|
55
50
|
value,
|
|
@@ -73,15 +68,14 @@ export const OptionsList = /*#__PURE__*/forwardRef(function OptionsList(_ref, re
|
|
|
73
68
|
component: component || optionComponent,
|
|
74
69
|
onBecameVisible: isLast ? onEndReached : undefined
|
|
75
70
|
});
|
|
76
|
-
})
|
|
77
|
-
id: "233683301"
|
|
78
|
-
}, ["div.jsx-233683301{outline:none;}"]));
|
|
71
|
+
}));
|
|
79
72
|
});
|
|
80
73
|
OptionsList.propTypes = {
|
|
81
74
|
comboBoxId: PropTypes.string.isRequired,
|
|
82
75
|
focussedOptionIndex: PropTypes.number.isRequired,
|
|
83
76
|
id: PropTypes.string.isRequired,
|
|
84
77
|
options: PropTypes.arrayOf(optionProp).isRequired,
|
|
78
|
+
onChange: PropTypes.func.isRequired,
|
|
85
79
|
dataTest: PropTypes.string,
|
|
86
80
|
disabled: PropTypes.bool,
|
|
87
81
|
labelledBy: PropTypes.string,
|
|
@@ -90,7 +84,5 @@ OptionsList.propTypes = {
|
|
|
90
84
|
optionUpdateStrategy: PropTypes.oneOf(['off', 'polite', 'assertive']),
|
|
91
85
|
selectedValue: PropTypes.string,
|
|
92
86
|
onBlur: PropTypes.func,
|
|
93
|
-
|
|
94
|
-
onEndReached: PropTypes.func,
|
|
95
|
-
onKeyDown: PropTypes.func
|
|
87
|
+
onEndReached: PropTypes.func
|
|
96
88
|
};
|
|
@@ -2,6 +2,7 @@ import _JSXStyle from "styled-jsx/style";
|
|
|
2
2
|
import { IconChevronDown16 } from '@dhis2/ui-icons';
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
import React from 'react';
|
|
5
|
+
import { Filter } from '../menu/filter.js';
|
|
5
6
|
import { ClearButton } from './clear-button.js';
|
|
6
7
|
import { Container } from './container.js';
|
|
7
8
|
import { Placeholder } from './placeholder.js';
|
|
@@ -21,6 +22,11 @@ export function SelectedValue(_ref) {
|
|
|
21
22
|
disabled,
|
|
22
23
|
error,
|
|
23
24
|
expanded,
|
|
25
|
+
filterLabel,
|
|
26
|
+
filterPlaceholder,
|
|
27
|
+
filterRef,
|
|
28
|
+
filterable,
|
|
29
|
+
filterValue,
|
|
24
30
|
hasSelection,
|
|
25
31
|
inputMaxHeight,
|
|
26
32
|
labelledBy,
|
|
@@ -32,9 +38,12 @@ export function SelectedValue(_ref) {
|
|
|
32
38
|
onBlur,
|
|
33
39
|
onClear,
|
|
34
40
|
onClick,
|
|
41
|
+
onFilterChange,
|
|
42
|
+
onFilterInputKeyDown,
|
|
35
43
|
onFocus
|
|
36
44
|
} = _ref;
|
|
37
45
|
const dataTestPrefix = `${dataTest}-selectedvalue`;
|
|
46
|
+
const showFilter = filterable && expanded;
|
|
38
47
|
return /*#__PURE__*/React.createElement(Container, {
|
|
39
48
|
dataTest: `${dataTestPrefix}-container`,
|
|
40
49
|
ref: comboBoxRef,
|
|
@@ -57,7 +66,16 @@ export function SelectedValue(_ref) {
|
|
|
57
66
|
}, prefix && /*#__PURE__*/React.createElement(Prefix, {
|
|
58
67
|
dataTest: `${dataTestPrefix}-prefix`,
|
|
59
68
|
prefix: prefix
|
|
60
|
-
}), /*#__PURE__*/React.createElement(
|
|
69
|
+
}), showFilter ? /*#__PURE__*/React.createElement(Filter, {
|
|
70
|
+
inputRef: filterRef,
|
|
71
|
+
ariaControls: `${name}-listbox`,
|
|
72
|
+
dataTest: `${dataTestPrefix}-filter`,
|
|
73
|
+
label: filterLabel,
|
|
74
|
+
placeholder: filterPlaceholder,
|
|
75
|
+
value: filterValue,
|
|
76
|
+
onChange: onFilterChange,
|
|
77
|
+
onKeyDown: onFilterInputKeyDown
|
|
78
|
+
}) : /*#__PURE__*/React.createElement("div", {
|
|
61
79
|
tabIndex: "-1",
|
|
62
80
|
className: _JSXStyle.dynamic([["3226769786", [inputMaxHeight]]]) + " " + "selected-option-label"
|
|
63
81
|
}, !selectedLabel && !prefix && placeholder && /*#__PURE__*/React.createElement(Placeholder, {
|
|
@@ -84,6 +102,7 @@ export function SelectedValue(_ref) {
|
|
|
84
102
|
SelectedValue.propTypes = {
|
|
85
103
|
clearText: PropTypes.string.isRequired,
|
|
86
104
|
comboBoxId: PropTypes.string.isRequired,
|
|
105
|
+
filterRef: PropTypes.object.isRequired,
|
|
87
106
|
name: PropTypes.string.isRequired,
|
|
88
107
|
selectedLabel: PropTypes.string.isRequired,
|
|
89
108
|
onKeyDown: PropTypes.func.isRequired,
|
|
@@ -97,6 +116,10 @@ SelectedValue.propTypes = {
|
|
|
97
116
|
disabled: PropTypes.bool,
|
|
98
117
|
error: PropTypes.bool,
|
|
99
118
|
expanded: PropTypes.bool,
|
|
119
|
+
filterLabel: PropTypes.string,
|
|
120
|
+
filterPlaceholder: PropTypes.string,
|
|
121
|
+
filterValue: PropTypes.string,
|
|
122
|
+
filterable: PropTypes.bool,
|
|
100
123
|
hasSelection: PropTypes.bool,
|
|
101
124
|
inputMaxHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
102
125
|
labelledBy: PropTypes.string,
|
|
@@ -108,5 +131,7 @@ SelectedValue.propTypes = {
|
|
|
108
131
|
onBlur: PropTypes.func,
|
|
109
132
|
onClear: PropTypes.func,
|
|
110
133
|
onClick: PropTypes.func,
|
|
134
|
+
onFilterChange: PropTypes.func,
|
|
135
|
+
onFilterInputKeyDown: PropTypes.func,
|
|
111
136
|
onFocus: PropTypes.func
|
|
112
137
|
};
|