@dhis2-ui/select 10.12.9 → 10.12.10
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/simple-single-select/menu/filter.js +18 -25
- package/build/cjs/simple-single-select/menu/menu.js +3 -27
- package/build/cjs/simple-single-select/selected-value/selected-value.js +26 -1
- package/build/cjs/simple-single-select/simple-single-select.js +20 -12
- package/build/cjs/simple-single-select/use-handle-key-press/use-handle-key-press-on-combobox.js +24 -10
- 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/simple-single-select/menu/filter.js +18 -25
- package/build/es/simple-single-select/menu/menu.js +3 -27
- package/build/es/simple-single-select/selected-value/selected-value.js +26 -1
- package/build/es/simple-single-select/simple-single-select.js +20 -12
- package/build/es/simple-single-select/use-handle-key-press/use-handle-key-press-on-combobox.js +24 -10
- 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
|
@@ -5,8 +5,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.Filter = Filter;
|
|
7
7
|
var _style = _interopRequireDefault(require("styled-jsx/style"));
|
|
8
|
-
var _uiConstants = require("@dhis2/ui-constants");
|
|
9
|
-
var _input = require("@dhis2-ui/input");
|
|
10
8
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
9
|
var _react = _interopRequireDefault(require("react"));
|
|
12
10
|
var _index = _interopRequireDefault(require("../../locales/index.js"));
|
|
@@ -15,46 +13,41 @@ function Filter(_ref) {
|
|
|
15
13
|
let {
|
|
16
14
|
ariaControls,
|
|
17
15
|
dataTest,
|
|
16
|
+
inputRef,
|
|
18
17
|
label,
|
|
19
18
|
placeholder,
|
|
20
|
-
tabIndex,
|
|
21
19
|
value,
|
|
22
20
|
onChange,
|
|
23
21
|
onKeyDown
|
|
24
22
|
} = _ref;
|
|
25
|
-
return /*#__PURE__*/_react.default.createElement("
|
|
26
|
-
|
|
27
|
-
className: _style.default.dynamic([["3850436710", [_uiConstants.colors.white, _uiConstants.spacers.dp8, _uiConstants.spacers.dp8, _uiConstants.spacers.dp4, _uiConstants.spacers.dp8]]])
|
|
28
|
-
}, /*#__PURE__*/_react.default.createElement(_input.Input, {
|
|
29
|
-
dense: true,
|
|
30
|
-
tabIndex: tabIndex,
|
|
31
|
-
ariaControls: ariaControls,
|
|
32
|
-
ariaHaspopup: "listbox",
|
|
33
|
-
ariaLabel: label || _index.default.t('Search options'),
|
|
34
|
-
dataTest: `${dataTest}-input`,
|
|
35
|
-
value: value,
|
|
36
|
-
onChange: _ref2 => {
|
|
37
|
-
let {
|
|
38
|
-
value
|
|
39
|
-
} = _ref2;
|
|
40
|
-
return onChange(value);
|
|
41
|
-
},
|
|
23
|
+
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("input", {
|
|
24
|
+
ref: inputRef,
|
|
42
25
|
type: "text",
|
|
43
26
|
name: "filter",
|
|
27
|
+
value: value,
|
|
44
28
|
placeholder: placeholder,
|
|
45
|
-
|
|
29
|
+
"aria-label": label || _index.default.t('Search options'),
|
|
30
|
+
"aria-controls": ariaControls,
|
|
31
|
+
"aria-haspopup": "listbox",
|
|
32
|
+
"data-test": dataTest,
|
|
33
|
+
onChange: e => onChange(e.target.value),
|
|
34
|
+
onClick: e => e.stopPropagation(),
|
|
35
|
+
onKeyDown: e => {
|
|
36
|
+
e.stopPropagation();
|
|
37
|
+
onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e);
|
|
38
|
+
},
|
|
39
|
+
className: "jsx-1122123784" + " " + "filter-input"
|
|
46
40
|
}), /*#__PURE__*/_react.default.createElement(_style.default, {
|
|
47
|
-
id: "
|
|
48
|
-
|
|
49
|
-
}, [`div.__jsx-style-dynamic-selector{height:100%;-webkit-inset-block-start:0;-ms-intb-rlock-start:0;inset-block-start:0;background:${_uiConstants.colors.white};}`]));
|
|
41
|
+
id: "1122123784"
|
|
42
|
+
}, [".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;}"]));
|
|
50
43
|
}
|
|
51
44
|
Filter.propTypes = {
|
|
52
45
|
ariaControls: _propTypes.default.string.isRequired,
|
|
46
|
+
inputRef: _propTypes.default.object.isRequired,
|
|
53
47
|
value: _propTypes.default.string.isRequired,
|
|
54
48
|
onChange: _propTypes.default.func.isRequired,
|
|
55
49
|
dataTest: _propTypes.default.string,
|
|
56
50
|
label: _propTypes.default.string,
|
|
57
51
|
placeholder: _propTypes.default.string,
|
|
58
|
-
tabIndex: _propTypes.default.string,
|
|
59
52
|
onKeyDown: _propTypes.default.func
|
|
60
53
|
};
|
|
@@ -12,7 +12,6 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
|
12
12
|
var _react = _interopRequireWildcard(require("react"));
|
|
13
13
|
var _sharedPropTypes = require("../shared-prop-types.js");
|
|
14
14
|
var _empty = require("./empty.js");
|
|
15
|
-
var _filter = require("./filter.js");
|
|
16
15
|
var _loading = require("./loading.js");
|
|
17
16
|
var _noMatch = require("./no-match.js");
|
|
18
17
|
var _optionsList = require("./options-list.js");
|
|
@@ -30,10 +29,7 @@ function Menu(_ref) {
|
|
|
30
29
|
dataTest,
|
|
31
30
|
disabled,
|
|
32
31
|
empty,
|
|
33
|
-
filterLabel,
|
|
34
|
-
filterPlaceholder,
|
|
35
32
|
filterValue,
|
|
36
|
-
filterable,
|
|
37
33
|
hidden,
|
|
38
34
|
labelledBy,
|
|
39
35
|
listBoxRef,
|
|
@@ -44,12 +40,9 @@ function Menu(_ref) {
|
|
|
44
40
|
optionUpdateStrategy,
|
|
45
41
|
selectRef,
|
|
46
42
|
selectedValue,
|
|
47
|
-
tabIndex,
|
|
48
43
|
onBlur,
|
|
49
44
|
onClose,
|
|
50
|
-
onEndReached
|
|
51
|
-
onFilterChange,
|
|
52
|
-
onFilterInputKeyDown
|
|
45
|
+
onEndReached
|
|
53
46
|
} = _ref;
|
|
54
47
|
const [menuWidth, setWidth] = (0, _react.useState)('auto');
|
|
55
48
|
const dataTestPrefix = `${dataTest}-menu`;
|
|
@@ -83,18 +76,7 @@ function Menu(_ref) {
|
|
|
83
76
|
maxHeight
|
|
84
77
|
},
|
|
85
78
|
className: _style.default.dynamic([["2949029222", [_uiConstants.colors.white, _uiConstants.colors.grey200, _uiConstants.elevations.e300]]]) + " " + "menu"
|
|
86
|
-
},
|
|
87
|
-
className: _style.default.dynamic([["2949029222", [_uiConstants.colors.white, _uiConstants.colors.grey200, _uiConstants.elevations.e300]]]) + " " + "filter-container"
|
|
88
|
-
}, /*#__PURE__*/_react.default.createElement(_filter.Filter, {
|
|
89
|
-
dataTest: `${dataTestPrefix}-filter`,
|
|
90
|
-
value: filterValue,
|
|
91
|
-
label: filterLabel,
|
|
92
|
-
ariaControls: `${name}-listbox`,
|
|
93
|
-
placeholder: filterPlaceholder,
|
|
94
|
-
tabIndex: tabIndex,
|
|
95
|
-
onChange: onFilterChange,
|
|
96
|
-
onKeyDown: onFilterInputKeyDown
|
|
97
|
-
})), isEmpty && /*#__PURE__*/_react.default.createElement(_empty.Empty, null, empty), hasNoFilterMatch && /*#__PURE__*/_react.default.createElement(_noMatch.NoMatch, null, noMatchText), /*#__PURE__*/_react.default.createElement("div", {
|
|
79
|
+
}, isEmpty && /*#__PURE__*/_react.default.createElement(_empty.Empty, null, empty), hasNoFilterMatch && /*#__PURE__*/_react.default.createElement(_noMatch.NoMatch, null, noMatchText), /*#__PURE__*/_react.default.createElement("div", {
|
|
98
80
|
className: _style.default.dynamic([["2949029222", [_uiConstants.colors.white, _uiConstants.colors.grey200, _uiConstants.elevations.e300]]]) + " " + "listbox-container"
|
|
99
81
|
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
100
82
|
className: _style.default.dynamic([["2949029222", [_uiConstants.colors.white, _uiConstants.colors.grey200, _uiConstants.elevations.e300]]]) + " " + "listbox-wrapper"
|
|
@@ -135,10 +117,7 @@ Menu.propTypes = {
|
|
|
135
117
|
dataTest: _propTypes.default.string,
|
|
136
118
|
disabled: _propTypes.default.bool,
|
|
137
119
|
empty: _propTypes.default.node,
|
|
138
|
-
filterLabel: _propTypes.default.string,
|
|
139
|
-
filterPlaceholder: _propTypes.default.string,
|
|
140
120
|
filterValue: _propTypes.default.string,
|
|
141
|
-
filterable: _propTypes.default.bool,
|
|
142
121
|
hidden: _propTypes.default.bool,
|
|
143
122
|
labelledBy: _propTypes.default.string,
|
|
144
123
|
loading: _propTypes.default.bool,
|
|
@@ -149,10 +128,7 @@ Menu.propTypes = {
|
|
|
149
128
|
optionUpdateStrategy: _propTypes.default.oneOf(['off', 'polite', 'assertive']),
|
|
150
129
|
selectRef: _propTypes.default.instanceOf(HTMLElement),
|
|
151
130
|
selectedValue: _propTypes.default.string,
|
|
152
|
-
tabIndex: _propTypes.default.string,
|
|
153
131
|
onBlur: _propTypes.default.func,
|
|
154
132
|
onClose: _propTypes.default.func,
|
|
155
|
-
onEndReached: _propTypes.default.func
|
|
156
|
-
onFilterChange: _propTypes.default.func,
|
|
157
|
-
onFilterInputKeyDown: _propTypes.default.func
|
|
133
|
+
onEndReached: _propTypes.default.func
|
|
158
134
|
};
|
|
@@ -8,6 +8,7 @@ var _style = _interopRequireDefault(require("styled-jsx/style"));
|
|
|
8
8
|
var _uiIcons = require("@dhis2/ui-icons");
|
|
9
9
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
10
10
|
var _react = _interopRequireDefault(require("react"));
|
|
11
|
+
var _filter = require("../menu/filter.js");
|
|
11
12
|
var _clearButton = require("./clear-button.js");
|
|
12
13
|
var _container = require("./container.js");
|
|
13
14
|
var _placeholder = require("./placeholder.js");
|
|
@@ -28,6 +29,11 @@ function SelectedValue(_ref) {
|
|
|
28
29
|
disabled,
|
|
29
30
|
error,
|
|
30
31
|
expanded,
|
|
32
|
+
filterLabel,
|
|
33
|
+
filterPlaceholder,
|
|
34
|
+
filterRef,
|
|
35
|
+
filterable,
|
|
36
|
+
filterValue,
|
|
31
37
|
hasSelection,
|
|
32
38
|
inputMaxHeight,
|
|
33
39
|
labelledBy,
|
|
@@ -39,9 +45,12 @@ function SelectedValue(_ref) {
|
|
|
39
45
|
onBlur,
|
|
40
46
|
onClear,
|
|
41
47
|
onClick,
|
|
48
|
+
onFilterChange,
|
|
49
|
+
onFilterInputKeyDown,
|
|
42
50
|
onFocus
|
|
43
51
|
} = _ref;
|
|
44
52
|
const dataTestPrefix = `${dataTest}-selectedvalue`;
|
|
53
|
+
const showFilter = filterable && expanded;
|
|
45
54
|
return /*#__PURE__*/_react.default.createElement(_container.Container, {
|
|
46
55
|
dataTest: `${dataTestPrefix}-container`,
|
|
47
56
|
ref: comboBoxRef,
|
|
@@ -64,7 +73,16 @@ function SelectedValue(_ref) {
|
|
|
64
73
|
}, prefix && /*#__PURE__*/_react.default.createElement(_prefix.Prefix, {
|
|
65
74
|
dataTest: `${dataTestPrefix}-prefix`,
|
|
66
75
|
prefix: prefix
|
|
67
|
-
}), /*#__PURE__*/_react.default.createElement(
|
|
76
|
+
}), showFilter ? /*#__PURE__*/_react.default.createElement(_filter.Filter, {
|
|
77
|
+
inputRef: filterRef,
|
|
78
|
+
ariaControls: `${name}-listbox`,
|
|
79
|
+
dataTest: `${dataTestPrefix}-filter`,
|
|
80
|
+
label: filterLabel,
|
|
81
|
+
placeholder: filterPlaceholder,
|
|
82
|
+
value: filterValue,
|
|
83
|
+
onChange: onFilterChange,
|
|
84
|
+
onKeyDown: onFilterInputKeyDown
|
|
85
|
+
}) : /*#__PURE__*/_react.default.createElement("div", {
|
|
68
86
|
tabIndex: "-1",
|
|
69
87
|
className: _style.default.dynamic([["3226769786", [inputMaxHeight]]]) + " " + "selected-option-label"
|
|
70
88
|
}, !selectedLabel && !prefix && placeholder && /*#__PURE__*/_react.default.createElement(_placeholder.Placeholder, {
|
|
@@ -91,6 +109,7 @@ function SelectedValue(_ref) {
|
|
|
91
109
|
SelectedValue.propTypes = {
|
|
92
110
|
clearText: _propTypes.default.string.isRequired,
|
|
93
111
|
comboBoxId: _propTypes.default.string.isRequired,
|
|
112
|
+
filterRef: _propTypes.default.object.isRequired,
|
|
94
113
|
name: _propTypes.default.string.isRequired,
|
|
95
114
|
selectedLabel: _propTypes.default.string.isRequired,
|
|
96
115
|
onKeyDown: _propTypes.default.func.isRequired,
|
|
@@ -104,6 +123,10 @@ SelectedValue.propTypes = {
|
|
|
104
123
|
disabled: _propTypes.default.bool,
|
|
105
124
|
error: _propTypes.default.bool,
|
|
106
125
|
expanded: _propTypes.default.bool,
|
|
126
|
+
filterLabel: _propTypes.default.string,
|
|
127
|
+
filterPlaceholder: _propTypes.default.string,
|
|
128
|
+
filterValue: _propTypes.default.string,
|
|
129
|
+
filterable: _propTypes.default.bool,
|
|
107
130
|
hasSelection: _propTypes.default.bool,
|
|
108
131
|
inputMaxHeight: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
|
|
109
132
|
labelledBy: _propTypes.default.string,
|
|
@@ -115,5 +138,7 @@ SelectedValue.propTypes = {
|
|
|
115
138
|
onBlur: _propTypes.default.func,
|
|
116
139
|
onClear: _propTypes.default.func,
|
|
117
140
|
onClick: _propTypes.default.func,
|
|
141
|
+
onFilterChange: _propTypes.default.func,
|
|
142
|
+
onFilterInputKeyDown: _propTypes.default.func,
|
|
118
143
|
onFocus: _propTypes.default.func
|
|
119
144
|
};
|
|
@@ -67,7 +67,6 @@ function SimpleSingleSelect(_ref2) {
|
|
|
67
67
|
disabled = false,
|
|
68
68
|
empty: _empty = false,
|
|
69
69
|
error = false,
|
|
70
|
-
filterHelpText = '',
|
|
71
70
|
filterLabel = '',
|
|
72
71
|
filterPlaceholder: _filterPlaceholder = '',
|
|
73
72
|
filterValue = '',
|
|
@@ -104,6 +103,7 @@ function SimpleSingleSelect(_ref2) {
|
|
|
104
103
|
const comboBoxId = `${name}-combo`;
|
|
105
104
|
const comboBoxRef = (0, _react.useRef)();
|
|
106
105
|
const listBoxRef = (0, _react.useRef)();
|
|
106
|
+
const filterInputRef = (0, _react.useRef)();
|
|
107
107
|
const [focussedOptionIndex, setFocussedOptionIndex] = useFocussedOptionIndex({
|
|
108
108
|
filterable,
|
|
109
109
|
filterValue,
|
|
@@ -111,6 +111,14 @@ function SimpleSingleSelect(_ref2) {
|
|
|
111
111
|
});
|
|
112
112
|
const [selectRef, setSelectRef] = (0, _react.useState)();
|
|
113
113
|
const [expanded, setExpanded] = (0, _react.useState)(false);
|
|
114
|
+
(0, _react.useEffect)(() => {
|
|
115
|
+
if (expanded && filterable) {
|
|
116
|
+
requestAnimationFrame(() => {
|
|
117
|
+
var _filterInputRef$curre;
|
|
118
|
+
(_filterInputRef$curre = filterInputRef.current) === null || _filterInputRef$curre === void 0 ? void 0 : _filterInputRef$curre.focus();
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
}, [expanded, filterable]);
|
|
114
122
|
const closeMenu = (0, _react.useCallback)(() => setExpanded(false), []);
|
|
115
123
|
const selectedValue = (selected === null || selected === void 0 ? void 0 : selected.value) || '';
|
|
116
124
|
const selectedLabel = (selected === null || selected === void 0 ? void 0 : selected.label) || '';
|
|
@@ -155,7 +163,9 @@ function SimpleSingleSelect(_ref2) {
|
|
|
155
163
|
setFocussedOptionIndex,
|
|
156
164
|
selectFocussedOption,
|
|
157
165
|
clearable,
|
|
158
|
-
onClear
|
|
166
|
+
onClear,
|
|
167
|
+
filterable,
|
|
168
|
+
onFilterChange
|
|
159
169
|
});
|
|
160
170
|
const handleKeyDownOnFilterInput = (0, _index4.useHandleKeyPressOnFilterInput)({
|
|
161
171
|
value: selectedValue,
|
|
@@ -195,6 +205,11 @@ function SimpleSingleSelect(_ref2) {
|
|
|
195
205
|
disabled: disabled,
|
|
196
206
|
error: error,
|
|
197
207
|
expanded: expanded,
|
|
208
|
+
filterLabel: filterLabel,
|
|
209
|
+
filterPlaceholder: filterPlaceholder,
|
|
210
|
+
filterRef: filterInputRef,
|
|
211
|
+
filterable: filterable,
|
|
212
|
+
filterValue: filterValue,
|
|
198
213
|
hasSelection: !!selectedValue,
|
|
199
214
|
inputMaxHeight: inputMaxHeight,
|
|
200
215
|
labelledBy: labelledBy,
|
|
@@ -208,6 +223,8 @@ function SimpleSingleSelect(_ref2) {
|
|
|
208
223
|
onBlur: onBlur,
|
|
209
224
|
onClear: onClear,
|
|
210
225
|
onClick: toggleMenu,
|
|
226
|
+
onFilterChange: onFilterChange,
|
|
227
|
+
onFilterInputKeyDown: handleKeyDownOnFilterInput,
|
|
211
228
|
onFocus: onFocus,
|
|
212
229
|
onKeyDown: handleKeyDown
|
|
213
230
|
}), /*#__PURE__*/_react.default.createElement(_index2.Menu, {
|
|
@@ -215,13 +232,8 @@ function SimpleSingleSelect(_ref2) {
|
|
|
215
232
|
optionComponent: optionComponent,
|
|
216
233
|
disabled: disabled,
|
|
217
234
|
empty: empty,
|
|
218
|
-
filterHelpText: filterHelpText,
|
|
219
|
-
filterLabel: filterLabel,
|
|
220
|
-
filterable: filterable,
|
|
221
235
|
filterValue: filterValue,
|
|
222
|
-
filterPlaceholder: filterPlaceholder,
|
|
223
236
|
focussedOptionIndex: focussedOptionIndex,
|
|
224
|
-
onFilterInputKeyDown: handleKeyDownOnFilterInput,
|
|
225
237
|
hidden: !expanded,
|
|
226
238
|
name: name,
|
|
227
239
|
labelledBy: labelledBy,
|
|
@@ -234,15 +246,13 @@ function SimpleSingleSelect(_ref2) {
|
|
|
234
246
|
options: options,
|
|
235
247
|
selectRef: selectRef,
|
|
236
248
|
selectedValue: selectedValue,
|
|
237
|
-
tabIndex: tabIndex.toString(),
|
|
238
249
|
onBlur: onBlur,
|
|
239
250
|
onChange: nextValue => {
|
|
240
251
|
onChange(nextValue);
|
|
241
252
|
closeMenu();
|
|
242
253
|
},
|
|
243
254
|
onClose: closeMenu,
|
|
244
|
-
onEndReached: onEndReached
|
|
245
|
-
onFilterChange: onFilterChange
|
|
255
|
+
onEndReached: onEndReached
|
|
246
256
|
}));
|
|
247
257
|
}
|
|
248
258
|
SimpleSingleSelect.propTypes = {
|
|
@@ -270,8 +280,6 @@ SimpleSingleSelect.propTypes = {
|
|
|
270
280
|
empty: _propTypes2.default.node,
|
|
271
281
|
/** Applies 'error' appearance for validation feedback. Mutually exclusive with `warning` and `valid` props **/
|
|
272
282
|
error: _uiConstants.sharedPropTypes.statusPropType,
|
|
273
|
-
/** Help text that will be displayed below the input **/
|
|
274
|
-
filterHelpText: _propTypes2.default.string,
|
|
275
283
|
/** Value will be used as aria-label attribute on the filter input **/
|
|
276
284
|
filterLabel: _propTypes2.default.string,
|
|
277
285
|
/** Placeholder for the filter input **/
|
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,
|
|
@@ -47,8 +56,10 @@ function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
47
56
|
selectFocussedOption,
|
|
48
57
|
onChange,
|
|
49
58
|
clearable,
|
|
50
|
-
onClear
|
|
51
|
-
|
|
59
|
+
onClear,
|
|
60
|
+
filterable,
|
|
61
|
+
onFilterChange
|
|
62
|
+
} = _ref3;
|
|
52
63
|
const {
|
|
53
64
|
onTyping,
|
|
54
65
|
typing
|
|
@@ -103,9 +114,7 @@ function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
103
114
|
const handleKeyPress = (0, _react.useCallback)(event => {
|
|
104
115
|
const {
|
|
105
116
|
key,
|
|
106
|
-
altKey
|
|
107
|
-
ctrlKey,
|
|
108
|
-
metaKey
|
|
117
|
+
altKey
|
|
109
118
|
} = event;
|
|
110
119
|
if (disabled || loading) {
|
|
111
120
|
return;
|
|
@@ -170,7 +179,12 @@ function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
170
179
|
focusLastOption();
|
|
171
180
|
return;
|
|
172
181
|
}
|
|
173
|
-
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) {
|
|
174
188
|
onTyping(key);
|
|
175
189
|
return;
|
|
176
190
|
}
|
|
@@ -184,6 +198,6 @@ function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
184
198
|
}
|
|
185
199
|
|
|
186
200
|
// Do nothing
|
|
187
|
-
}, [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]);
|
|
188
202
|
return handleKeyPress;
|
|
189
203
|
}
|
|
@@ -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('');
|
|
@@ -1,6 +1,4 @@
|
|
|
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
3
|
import React from 'react';
|
|
6
4
|
import i18n from '../../locales/index.js';
|
|
@@ -8,46 +6,41 @@ 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
14
|
onKeyDown
|
|
17
15
|
} = _ref;
|
|
18
|
-
return /*#__PURE__*/React.createElement("
|
|
19
|
-
|
|
20
|
-
className: _JSXStyle.dynamic([["3850436710", [colors.white, spacers.dp8, spacers.dp8, spacers.dp4, spacers.dp8]]])
|
|
21
|
-
}, /*#__PURE__*/React.createElement(Input, {
|
|
22
|
-
dense: true,
|
|
23
|
-
tabIndex: tabIndex,
|
|
24
|
-
ariaControls: ariaControls,
|
|
25
|
-
ariaHaspopup: "listbox",
|
|
26
|
-
ariaLabel: label || i18n.t('Search options'),
|
|
27
|
-
dataTest: `${dataTest}-input`,
|
|
28
|
-
value: value,
|
|
29
|
-
onChange: _ref2 => {
|
|
30
|
-
let {
|
|
31
|
-
value
|
|
32
|
-
} = _ref2;
|
|
33
|
-
return onChange(value);
|
|
34
|
-
},
|
|
16
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("input", {
|
|
17
|
+
ref: inputRef,
|
|
35
18
|
type: "text",
|
|
36
19
|
name: "filter",
|
|
20
|
+
value: value,
|
|
37
21
|
placeholder: placeholder,
|
|
38
|
-
|
|
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"
|
|
39
33
|
}), /*#__PURE__*/React.createElement(_JSXStyle, {
|
|
40
|
-
id: "
|
|
41
|
-
|
|
42
|
-
}, [`div.__jsx-style-dynamic-selector{height:100%;-webkit-inset-block-start:0;-ms-intb-rlock-start:0;inset-block-start:0;background:${colors.white};}`]));
|
|
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;}"]));
|
|
43
36
|
}
|
|
44
37
|
Filter.propTypes = {
|
|
45
38
|
ariaControls: PropTypes.string.isRequired,
|
|
39
|
+
inputRef: PropTypes.object.isRequired,
|
|
46
40
|
value: PropTypes.string.isRequired,
|
|
47
41
|
onChange: PropTypes.func.isRequired,
|
|
48
42
|
dataTest: PropTypes.string,
|
|
49
43
|
label: PropTypes.string,
|
|
50
44
|
placeholder: PropTypes.string,
|
|
51
|
-
tabIndex: PropTypes.string,
|
|
52
45
|
onKeyDown: PropTypes.func
|
|
53
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,12 +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
|
|
36
|
+
onEndReached
|
|
44
37
|
} = _ref;
|
|
45
38
|
const [menuWidth, setWidth] = useState('auto');
|
|
46
39
|
const dataTestPrefix = `${dataTest}-menu`;
|
|
@@ -74,18 +67,7 @@ export function Menu(_ref) {
|
|
|
74
67
|
maxHeight
|
|
75
68
|
},
|
|
76
69
|
className: _JSXStyle.dynamic([["2949029222", [colors.white, colors.grey200, elevations.e300]]]) + " " + "menu"
|
|
77
|
-
},
|
|
78
|
-
className: _JSXStyle.dynamic([["2949029222", [colors.white, colors.grey200, elevations.e300]]]) + " " + "filter-container"
|
|
79
|
-
}, /*#__PURE__*/React.createElement(Filter, {
|
|
80
|
-
dataTest: `${dataTestPrefix}-filter`,
|
|
81
|
-
value: filterValue,
|
|
82
|
-
label: filterLabel,
|
|
83
|
-
ariaControls: `${name}-listbox`,
|
|
84
|
-
placeholder: filterPlaceholder,
|
|
85
|
-
tabIndex: tabIndex,
|
|
86
|
-
onChange: onFilterChange,
|
|
87
|
-
onKeyDown: onFilterInputKeyDown
|
|
88
|
-
})), 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", {
|
|
89
71
|
className: _JSXStyle.dynamic([["2949029222", [colors.white, colors.grey200, elevations.e300]]]) + " " + "listbox-container"
|
|
90
72
|
}, /*#__PURE__*/React.createElement("div", {
|
|
91
73
|
className: _JSXStyle.dynamic([["2949029222", [colors.white, colors.grey200, elevations.e300]]]) + " " + "listbox-wrapper"
|
|
@@ -126,10 +108,7 @@ Menu.propTypes = {
|
|
|
126
108
|
dataTest: PropTypes.string,
|
|
127
109
|
disabled: PropTypes.bool,
|
|
128
110
|
empty: PropTypes.node,
|
|
129
|
-
filterLabel: PropTypes.string,
|
|
130
|
-
filterPlaceholder: PropTypes.string,
|
|
131
111
|
filterValue: PropTypes.string,
|
|
132
|
-
filterable: PropTypes.bool,
|
|
133
112
|
hidden: PropTypes.bool,
|
|
134
113
|
labelledBy: PropTypes.string,
|
|
135
114
|
loading: PropTypes.bool,
|
|
@@ -140,10 +119,7 @@ Menu.propTypes = {
|
|
|
140
119
|
optionUpdateStrategy: PropTypes.oneOf(['off', 'polite', 'assertive']),
|
|
141
120
|
selectRef: PropTypes.instanceOf(HTMLElement),
|
|
142
121
|
selectedValue: PropTypes.string,
|
|
143
|
-
tabIndex: PropTypes.string,
|
|
144
122
|
onBlur: PropTypes.func,
|
|
145
123
|
onClose: PropTypes.func,
|
|
146
|
-
onEndReached: PropTypes.func
|
|
147
|
-
onFilterChange: PropTypes.func,
|
|
148
|
-
onFilterInputKeyDown: PropTypes.func
|
|
124
|
+
onEndReached: PropTypes.func
|
|
149
125
|
};
|
|
@@ -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
|
};
|
|
@@ -58,7 +58,6 @@ export function SimpleSingleSelect(_ref2) {
|
|
|
58
58
|
disabled = false,
|
|
59
59
|
empty: _empty = false,
|
|
60
60
|
error = false,
|
|
61
|
-
filterHelpText = '',
|
|
62
61
|
filterLabel = '',
|
|
63
62
|
filterPlaceholder: _filterPlaceholder = '',
|
|
64
63
|
filterValue = '',
|
|
@@ -95,6 +94,7 @@ export function SimpleSingleSelect(_ref2) {
|
|
|
95
94
|
const comboBoxId = `${name}-combo`;
|
|
96
95
|
const comboBoxRef = useRef();
|
|
97
96
|
const listBoxRef = useRef();
|
|
97
|
+
const filterInputRef = useRef();
|
|
98
98
|
const [focussedOptionIndex, setFocussedOptionIndex] = useFocussedOptionIndex({
|
|
99
99
|
filterable,
|
|
100
100
|
filterValue,
|
|
@@ -102,6 +102,14 @@ export function SimpleSingleSelect(_ref2) {
|
|
|
102
102
|
});
|
|
103
103
|
const [selectRef, setSelectRef] = useState();
|
|
104
104
|
const [expanded, setExpanded] = useState(false);
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (expanded && filterable) {
|
|
107
|
+
requestAnimationFrame(() => {
|
|
108
|
+
var _filterInputRef$curre;
|
|
109
|
+
(_filterInputRef$curre = filterInputRef.current) === null || _filterInputRef$curre === void 0 ? void 0 : _filterInputRef$curre.focus();
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}, [expanded, filterable]);
|
|
105
113
|
const closeMenu = useCallback(() => setExpanded(false), []);
|
|
106
114
|
const selectedValue = (selected === null || selected === void 0 ? void 0 : selected.value) || '';
|
|
107
115
|
const selectedLabel = (selected === null || selected === void 0 ? void 0 : selected.label) || '';
|
|
@@ -146,7 +154,9 @@ export function SimpleSingleSelect(_ref2) {
|
|
|
146
154
|
setFocussedOptionIndex,
|
|
147
155
|
selectFocussedOption,
|
|
148
156
|
clearable,
|
|
149
|
-
onClear
|
|
157
|
+
onClear,
|
|
158
|
+
filterable,
|
|
159
|
+
onFilterChange
|
|
150
160
|
});
|
|
151
161
|
const handleKeyDownOnFilterInput = useHandleKeyPressOnFilterInput({
|
|
152
162
|
value: selectedValue,
|
|
@@ -186,6 +196,11 @@ export function SimpleSingleSelect(_ref2) {
|
|
|
186
196
|
disabled: disabled,
|
|
187
197
|
error: error,
|
|
188
198
|
expanded: expanded,
|
|
199
|
+
filterLabel: filterLabel,
|
|
200
|
+
filterPlaceholder: filterPlaceholder,
|
|
201
|
+
filterRef: filterInputRef,
|
|
202
|
+
filterable: filterable,
|
|
203
|
+
filterValue: filterValue,
|
|
189
204
|
hasSelection: !!selectedValue,
|
|
190
205
|
inputMaxHeight: inputMaxHeight,
|
|
191
206
|
labelledBy: labelledBy,
|
|
@@ -199,6 +214,8 @@ export function SimpleSingleSelect(_ref2) {
|
|
|
199
214
|
onBlur: onBlur,
|
|
200
215
|
onClear: onClear,
|
|
201
216
|
onClick: toggleMenu,
|
|
217
|
+
onFilterChange: onFilterChange,
|
|
218
|
+
onFilterInputKeyDown: handleKeyDownOnFilterInput,
|
|
202
219
|
onFocus: onFocus,
|
|
203
220
|
onKeyDown: handleKeyDown
|
|
204
221
|
}), /*#__PURE__*/React.createElement(Menu, {
|
|
@@ -206,13 +223,8 @@ export function SimpleSingleSelect(_ref2) {
|
|
|
206
223
|
optionComponent: optionComponent,
|
|
207
224
|
disabled: disabled,
|
|
208
225
|
empty: empty,
|
|
209
|
-
filterHelpText: filterHelpText,
|
|
210
|
-
filterLabel: filterLabel,
|
|
211
|
-
filterable: filterable,
|
|
212
226
|
filterValue: filterValue,
|
|
213
|
-
filterPlaceholder: filterPlaceholder,
|
|
214
227
|
focussedOptionIndex: focussedOptionIndex,
|
|
215
|
-
onFilterInputKeyDown: handleKeyDownOnFilterInput,
|
|
216
228
|
hidden: !expanded,
|
|
217
229
|
name: name,
|
|
218
230
|
labelledBy: labelledBy,
|
|
@@ -225,15 +237,13 @@ export function SimpleSingleSelect(_ref2) {
|
|
|
225
237
|
options: options,
|
|
226
238
|
selectRef: selectRef,
|
|
227
239
|
selectedValue: selectedValue,
|
|
228
|
-
tabIndex: tabIndex.toString(),
|
|
229
240
|
onBlur: onBlur,
|
|
230
241
|
onChange: nextValue => {
|
|
231
242
|
onChange(nextValue);
|
|
232
243
|
closeMenu();
|
|
233
244
|
},
|
|
234
245
|
onClose: closeMenu,
|
|
235
|
-
onEndReached: onEndReached
|
|
236
|
-
onFilterChange: onFilterChange
|
|
246
|
+
onEndReached: onEndReached
|
|
237
247
|
}));
|
|
238
248
|
}
|
|
239
249
|
SimpleSingleSelect.propTypes = {
|
|
@@ -261,8 +271,6 @@ SimpleSingleSelect.propTypes = {
|
|
|
261
271
|
empty: PropTypes.node,
|
|
262
272
|
/** Applies 'error' appearance for validation feedback. Mutually exclusive with `warning` and `valid` props **/
|
|
263
273
|
error: sharedPropTypes.statusPropType,
|
|
264
|
-
/** Help text that will be displayed below the input **/
|
|
265
|
-
filterHelpText: PropTypes.string,
|
|
266
274
|
/** Value will be used as aria-label attribute on the filter input **/
|
|
267
275
|
filterLabel: PropTypes.string,
|
|
268
276
|
/** Placeholder for the filter input **/
|
package/build/es/simple-single-select/use-handle-key-press/use-handle-key-press-on-combobox.js
CHANGED
|
@@ -4,12 +4,21 @@ import { useHandleTyping } from './use-handle-typing.js';
|
|
|
4
4
|
import { usePageDown } from './use-page-down.js';
|
|
5
5
|
import { usePageUp } from './use-page-up.js';
|
|
6
6
|
import { findNextOptionIndex, findPrevOptionIndex, findFirstOptionIndex, findLastOptionIndex } from './utils.js';
|
|
7
|
-
function
|
|
7
|
+
function isUnmodifiedCharacterKey(_ref) {
|
|
8
|
+
let {
|
|
9
|
+
key,
|
|
10
|
+
altKey,
|
|
11
|
+
ctrlKey,
|
|
12
|
+
metaKey
|
|
13
|
+
} = _ref;
|
|
14
|
+
return key.length === 1 && key !== ' ' && !altKey && !ctrlKey && !metaKey;
|
|
15
|
+
}
|
|
16
|
+
function useSelectOption(findIndexCallback, _ref2) {
|
|
8
17
|
let {
|
|
9
18
|
options,
|
|
10
19
|
onChange,
|
|
11
20
|
value
|
|
12
|
-
} =
|
|
21
|
+
} = _ref2;
|
|
13
22
|
return useCallback(() => {
|
|
14
23
|
const currentOptionIndex = options.findIndex(option => option.value === value);
|
|
15
24
|
const nextSelectedOptionIndex = findIndexCallback({
|
|
@@ -26,7 +35,7 @@ function useSelectOption(findIndexCallback, _ref) {
|
|
|
26
35
|
});
|
|
27
36
|
}, [findIndexCallback, options, onChange, value]);
|
|
28
37
|
}
|
|
29
|
-
export function useHandleKeyPressOnCombobox(
|
|
38
|
+
export function useHandleKeyPressOnCombobox(_ref3) {
|
|
30
39
|
let {
|
|
31
40
|
value,
|
|
32
41
|
disabled,
|
|
@@ -41,8 +50,10 @@ export function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
41
50
|
selectFocussedOption,
|
|
42
51
|
onChange,
|
|
43
52
|
clearable,
|
|
44
|
-
onClear
|
|
45
|
-
|
|
53
|
+
onClear,
|
|
54
|
+
filterable,
|
|
55
|
+
onFilterChange
|
|
56
|
+
} = _ref3;
|
|
46
57
|
const {
|
|
47
58
|
onTyping,
|
|
48
59
|
typing
|
|
@@ -97,9 +108,7 @@ export function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
97
108
|
const handleKeyPress = useCallback(event => {
|
|
98
109
|
const {
|
|
99
110
|
key,
|
|
100
|
-
altKey
|
|
101
|
-
ctrlKey,
|
|
102
|
-
metaKey
|
|
111
|
+
altKey
|
|
103
112
|
} = event;
|
|
104
113
|
if (disabled || loading) {
|
|
105
114
|
return;
|
|
@@ -164,7 +173,12 @@ export function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
164
173
|
focusLastOption();
|
|
165
174
|
return;
|
|
166
175
|
}
|
|
167
|
-
if (
|
|
176
|
+
if (filterable && !expanded && isUnmodifiedCharacterKey(event)) {
|
|
177
|
+
openMenu();
|
|
178
|
+
onFilterChange === null || onFilterChange === void 0 ? void 0 : onFilterChange(key);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (key === 'Backspace' || key === 'Clear' || isUnmodifiedCharacterKey(event) || key === ' ' && typing) {
|
|
168
182
|
onTyping(key);
|
|
169
183
|
return;
|
|
170
184
|
}
|
|
@@ -178,6 +192,6 @@ export function useHandleKeyPressOnCombobox(_ref2) {
|
|
|
178
192
|
}
|
|
179
193
|
|
|
180
194
|
// Do nothing
|
|
181
|
-
}, [closeMenu, disabled, expanded, loading, openMenu, options, value, typing, focussedOptionIndex, selectFocussedOption, selectNextOption, selectPrevOption, focusNextOption, focusPrevOption, focusFirstOption, focusLastOption, pageDown, pageUp, onTyping]);
|
|
195
|
+
}, [closeMenu, disabled, expanded, loading, openMenu, options, value, typing, focussedOptionIndex, selectFocussedOption, selectNextOption, selectPrevOption, focusNextOption, focusPrevOption, focusFirstOption, focusLastOption, pageDown, pageUp, onTyping, filterable, onFilterChange]);
|
|
182
196
|
return handleKeyPress;
|
|
183
197
|
}
|
|
@@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
|
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import { SimpleSingleSelect, optionProp } from '../simple-single-select/index.js';
|
|
8
8
|
export function SimpleSingleSelectField(props) {
|
|
9
|
+
var _ref, _selectedOption$label;
|
|
9
10
|
const {
|
|
10
11
|
className,
|
|
11
12
|
dataTest,
|
|
@@ -14,12 +15,28 @@ export function SimpleSingleSelectField(props) {
|
|
|
14
15
|
helpText,
|
|
15
16
|
label,
|
|
16
17
|
name,
|
|
18
|
+
onChange,
|
|
19
|
+
options,
|
|
17
20
|
required,
|
|
18
21
|
valid,
|
|
19
22
|
validationText,
|
|
23
|
+
value,
|
|
24
|
+
valueLabel,
|
|
20
25
|
warning
|
|
21
26
|
} = props;
|
|
22
27
|
const labelId = `${name}-label`;
|
|
28
|
+
const selectedOption = options.find(opt => opt.value === value);
|
|
29
|
+
const selected = value != null && value !== '' ? {
|
|
30
|
+
value,
|
|
31
|
+
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 : ''
|
|
32
|
+
} : undefined;
|
|
33
|
+
const handleChange = option => {
|
|
34
|
+
var _option$value;
|
|
35
|
+
onChange((_option$value = option === null || option === void 0 ? void 0 : option.value) !== null && _option$value !== void 0 ? _option$value : '');
|
|
36
|
+
};
|
|
37
|
+
const handleClear = () => {
|
|
38
|
+
onChange('');
|
|
39
|
+
};
|
|
23
40
|
return /*#__PURE__*/React.createElement(Field, {
|
|
24
41
|
className: className,
|
|
25
42
|
dataTest: dataTest,
|
|
@@ -33,7 +50,10 @@ export function SimpleSingleSelectField(props) {
|
|
|
33
50
|
warning: warning,
|
|
34
51
|
valid: valid
|
|
35
52
|
}, /*#__PURE__*/React.createElement(SimpleSingleSelect, _extends({}, props, {
|
|
36
|
-
labelledBy: labelId
|
|
53
|
+
labelledBy: labelId,
|
|
54
|
+
selected: selected,
|
|
55
|
+
onChange: handleChange,
|
|
56
|
+
onClear: handleClear
|
|
37
57
|
})));
|
|
38
58
|
}
|
|
39
59
|
SimpleSingleSelectField.propTypes = {
|
|
@@ -108,10 +128,10 @@ SimpleSingleSelectField.propTypes = {
|
|
|
108
128
|
* be used to supply the text to be shown.
|
|
109
129
|
**/
|
|
110
130
|
valueLabel: requiredIf(props => {
|
|
111
|
-
if (props.options.find(
|
|
131
|
+
if (props.options.find(_ref2 => {
|
|
112
132
|
let {
|
|
113
133
|
value
|
|
114
|
-
} =
|
|
134
|
+
} = _ref2;
|
|
115
135
|
return props.value === value;
|
|
116
136
|
})) {
|
|
117
137
|
return false;
|
|
@@ -23,7 +23,7 @@ describe('<SimpleSingleSelectField />', () => {
|
|
|
23
23
|
it('should forward props to the SimpleSingleSelect component', () => {
|
|
24
24
|
const options = [];
|
|
25
25
|
const optionComponent = () => null;
|
|
26
|
-
const onChange = ()
|
|
26
|
+
const onChange = jest.fn();
|
|
27
27
|
const onBlur = () => null;
|
|
28
28
|
const onEndReached = () => null;
|
|
29
29
|
const onFilterChange = () => null;
|
|
@@ -67,7 +67,10 @@ describe('<SimpleSingleSelectField />', () => {
|
|
|
67
67
|
}));
|
|
68
68
|
expect(SimpleSingleSelect.mock.calls[0][0].name).toBe('foo');
|
|
69
69
|
expect(SimpleSingleSelect.mock.calls[0][0].options).toBe(options);
|
|
70
|
-
|
|
70
|
+
SimpleSingleSelect.mock.calls[0][0].onChange({
|
|
71
|
+
value: 'test'
|
|
72
|
+
});
|
|
73
|
+
expect(onChange).toHaveBeenCalledWith('test');
|
|
71
74
|
expect(SimpleSingleSelect.mock.calls[0][0].autoFocus).toBe(false);
|
|
72
75
|
expect(SimpleSingleSelect.mock.calls[0][0].className).toBe('');
|
|
73
76
|
expect(SimpleSingleSelect.mock.calls[0][0].clearText).toBe('');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dhis2-ui/select",
|
|
3
|
-
"version": "10.12.
|
|
3
|
+
"version": "10.12.10",
|
|
4
4
|
"description": "UI Select",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,21 +33,21 @@
|
|
|
33
33
|
"styled-jsx": "^4"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@dhis2-ui/box": "10.12.
|
|
37
|
-
"@dhis2-ui/button": "10.12.
|
|
38
|
-
"@dhis2-ui/card": "10.12.
|
|
39
|
-
"@dhis2-ui/checkbox": "10.12.
|
|
40
|
-
"@dhis2-ui/chip": "10.12.
|
|
41
|
-
"@dhis2-ui/field": "10.12.
|
|
42
|
-
"@dhis2-ui/input": "10.12.
|
|
43
|
-
"@dhis2-ui/layer": "10.12.
|
|
44
|
-
"@dhis2-ui/loader": "10.12.
|
|
45
|
-
"@dhis2-ui/popper": "10.12.
|
|
46
|
-
"@dhis2-ui/status-icon": "10.12.
|
|
47
|
-
"@dhis2-ui/tooltip": "10.12.
|
|
36
|
+
"@dhis2-ui/box": "10.12.10",
|
|
37
|
+
"@dhis2-ui/button": "10.12.10",
|
|
38
|
+
"@dhis2-ui/card": "10.12.10",
|
|
39
|
+
"@dhis2-ui/checkbox": "10.12.10",
|
|
40
|
+
"@dhis2-ui/chip": "10.12.10",
|
|
41
|
+
"@dhis2-ui/field": "10.12.10",
|
|
42
|
+
"@dhis2-ui/input": "10.12.10",
|
|
43
|
+
"@dhis2-ui/layer": "10.12.10",
|
|
44
|
+
"@dhis2-ui/loader": "10.12.10",
|
|
45
|
+
"@dhis2-ui/popper": "10.12.10",
|
|
46
|
+
"@dhis2-ui/status-icon": "10.12.10",
|
|
47
|
+
"@dhis2-ui/tooltip": "10.12.10",
|
|
48
48
|
"@dhis2/prop-types": "^3.1.2",
|
|
49
|
-
"@dhis2/ui-constants": "10.12.
|
|
50
|
-
"@dhis2/ui-icons": "10.12.
|
|
49
|
+
"@dhis2/ui-constants": "10.12.10",
|
|
50
|
+
"@dhis2/ui-icons": "10.12.10",
|
|
51
51
|
"classnames": "^2.3.1",
|
|
52
52
|
"prop-types": "^15.7.2"
|
|
53
53
|
},
|