downshift 7.0.0-beta.0 → 7.0.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/CHANGELOG.md +5 -0
- package/dist/downshift.cjs.js +264 -651
- package/dist/downshift.esm.js +264 -651
- package/dist/downshift.native.cjs.js +265 -650
- package/dist/downshift.umd.js +262 -646
- package/dist/downshift.umd.js.map +1 -1
- package/dist/downshift.umd.min.js +1 -1
- package/dist/downshift.umd.min.js.map +1 -1
- package/dist/src/hooks/utils.d.ts +1 -1
- package/package.json +1 -1
- package/preact/dist/downshift.cjs.js +264 -648
- package/preact/dist/downshift.esm.js +264 -648
- package/preact/dist/downshift.umd.js +262 -643
- package/preact/dist/downshift.umd.js.map +1 -1
- package/preact/dist/downshift.umd.min.js +1 -1
- package/preact/dist/downshift.umd.min.js.map +1 -1
|
@@ -14,6 +14,7 @@ var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
|
|
|
14
14
|
var computeScrollIntoView__default = /*#__PURE__*/_interopDefaultLegacy(computeScrollIntoView);
|
|
15
15
|
|
|
16
16
|
let idCounter = 0;
|
|
17
|
+
|
|
17
18
|
/**
|
|
18
19
|
* Accepts a parameter and returns it if it's a function
|
|
19
20
|
* or a noop function if it's not. This allows us to
|
|
@@ -22,24 +23,20 @@ let idCounter = 0;
|
|
|
22
23
|
* @param {Function} cb the callback
|
|
23
24
|
* @return {Function} a function
|
|
24
25
|
*/
|
|
25
|
-
|
|
26
26
|
function cbToCb(cb) {
|
|
27
27
|
return typeof cb === 'function' ? cb : noop;
|
|
28
28
|
}
|
|
29
|
-
|
|
30
29
|
function noop() {}
|
|
30
|
+
|
|
31
31
|
/**
|
|
32
32
|
* Scroll node into view if necessary
|
|
33
33
|
* @param {HTMLElement} node the element that should scroll into view
|
|
34
34
|
* @param {HTMLElement} menuNode the menu element of the component
|
|
35
35
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
36
|
function scrollIntoView(node, menuNode) {
|
|
39
37
|
if (!node) {
|
|
40
38
|
return;
|
|
41
39
|
}
|
|
42
|
-
|
|
43
40
|
const actions = computeScrollIntoView__default["default"](node, {
|
|
44
41
|
boundary: menuNode,
|
|
45
42
|
block: 'nearest',
|
|
@@ -55,18 +52,18 @@ function scrollIntoView(node, menuNode) {
|
|
|
55
52
|
el.scrollLeft = left;
|
|
56
53
|
});
|
|
57
54
|
}
|
|
55
|
+
|
|
58
56
|
/**
|
|
59
57
|
* @param {HTMLElement} parent the parent node
|
|
60
58
|
* @param {HTMLElement} child the child node
|
|
61
59
|
* @param {Window} environment The window context where downshift renders.
|
|
62
60
|
* @return {Boolean} whether the parent is the child or the child is in the parent
|
|
63
61
|
*/
|
|
64
|
-
|
|
65
|
-
|
|
66
62
|
function isOrContainsNode(parent, child, environment) {
|
|
67
63
|
const result = parent === child || child instanceof environment.Node && parent.contains && parent.contains(child);
|
|
68
64
|
return result;
|
|
69
65
|
}
|
|
66
|
+
|
|
70
67
|
/**
|
|
71
68
|
* Simple debounce implementation. Will call the given
|
|
72
69
|
* function once after the time given has passed since
|
|
@@ -75,32 +72,27 @@ function isOrContainsNode(parent, child, environment) {
|
|
|
75
72
|
* @param {Number} time the time to wait
|
|
76
73
|
* @return {Function} the debounced function
|
|
77
74
|
*/
|
|
78
|
-
|
|
79
|
-
|
|
80
75
|
function debounce(fn, time) {
|
|
81
76
|
let timeoutId;
|
|
82
|
-
|
|
83
77
|
function cancel() {
|
|
84
78
|
if (timeoutId) {
|
|
85
79
|
clearTimeout(timeoutId);
|
|
86
80
|
}
|
|
87
81
|
}
|
|
88
|
-
|
|
89
82
|
function wrapper() {
|
|
90
83
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
91
84
|
args[_key] = arguments[_key];
|
|
92
85
|
}
|
|
93
|
-
|
|
94
86
|
cancel();
|
|
95
87
|
timeoutId = setTimeout(() => {
|
|
96
88
|
timeoutId = null;
|
|
97
89
|
fn(...args);
|
|
98
90
|
}, time);
|
|
99
91
|
}
|
|
100
|
-
|
|
101
92
|
wrapper.cancel = cancel;
|
|
102
93
|
return wrapper;
|
|
103
94
|
}
|
|
95
|
+
|
|
104
96
|
/**
|
|
105
97
|
* This is intended to be used to compose event handlers.
|
|
106
98
|
* They are executed in order until one of them sets
|
|
@@ -108,33 +100,26 @@ function debounce(fn, time) {
|
|
|
108
100
|
* @param {...Function} fns the event handler functions
|
|
109
101
|
* @return {Function} the event handler to add to an element
|
|
110
102
|
*/
|
|
111
|
-
|
|
112
|
-
|
|
113
103
|
function callAllEventHandlers() {
|
|
114
104
|
for (var _len2 = arguments.length, fns = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
115
105
|
fns[_key2] = arguments[_key2];
|
|
116
106
|
}
|
|
117
|
-
|
|
118
107
|
return function (event) {
|
|
119
108
|
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
120
109
|
args[_key3 - 1] = arguments[_key3];
|
|
121
110
|
}
|
|
122
|
-
|
|
123
111
|
return fns.some(fn => {
|
|
124
112
|
if (fn) {
|
|
125
113
|
fn(event, ...args);
|
|
126
114
|
}
|
|
127
|
-
|
|
128
115
|
return event.preventDownshiftDefault || event.hasOwnProperty('nativeEvent') && event.nativeEvent.preventDownshiftDefault;
|
|
129
116
|
});
|
|
130
117
|
};
|
|
131
118
|
}
|
|
132
|
-
|
|
133
119
|
function handleRefs() {
|
|
134
120
|
for (var _len4 = arguments.length, refs = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
135
121
|
refs[_key4] = arguments[_key4];
|
|
136
122
|
}
|
|
137
|
-
|
|
138
123
|
return node => {
|
|
139
124
|
refs.forEach(ref => {
|
|
140
125
|
if (typeof ref === 'function') {
|
|
@@ -145,23 +130,22 @@ function handleRefs() {
|
|
|
145
130
|
});
|
|
146
131
|
};
|
|
147
132
|
}
|
|
133
|
+
|
|
148
134
|
/**
|
|
149
135
|
* This generates a unique ID for an instance of Downshift
|
|
150
136
|
* @return {String} the unique ID
|
|
151
137
|
*/
|
|
152
|
-
|
|
153
|
-
|
|
154
138
|
function generateId() {
|
|
155
139
|
return String(idCounter++);
|
|
156
140
|
}
|
|
141
|
+
|
|
157
142
|
/**
|
|
158
143
|
* Resets idCounter to 0. Used for SSR.
|
|
159
144
|
*/
|
|
160
|
-
|
|
161
|
-
|
|
162
145
|
function resetIdCounter() {
|
|
163
146
|
idCounter = 0;
|
|
164
147
|
}
|
|
148
|
+
|
|
165
149
|
/**
|
|
166
150
|
* Default implementation for status message. Only added when menu is open.
|
|
167
151
|
* Will specify if there are results in the list, and if so, how many,
|
|
@@ -170,29 +154,24 @@ function resetIdCounter() {
|
|
|
170
154
|
* @param {Object} param the downshift state and other relevant properties
|
|
171
155
|
* @return {String} the a11y status message
|
|
172
156
|
*/
|
|
173
|
-
|
|
174
|
-
|
|
175
157
|
function getA11yStatusMessage$1(_ref2) {
|
|
176
158
|
let {
|
|
177
159
|
isOpen,
|
|
178
160
|
resultCount,
|
|
179
161
|
previousResultCount
|
|
180
162
|
} = _ref2;
|
|
181
|
-
|
|
182
163
|
if (!isOpen) {
|
|
183
164
|
return '';
|
|
184
165
|
}
|
|
185
|
-
|
|
186
166
|
if (!resultCount) {
|
|
187
167
|
return 'No results are available.';
|
|
188
168
|
}
|
|
189
|
-
|
|
190
169
|
if (resultCount !== previousResultCount) {
|
|
191
170
|
return `${resultCount} result${resultCount === 1 ? ' is' : 's are'} available, use up and down arrow keys to navigate. Press Enter key to select.`;
|
|
192
171
|
}
|
|
193
|
-
|
|
194
172
|
return '';
|
|
195
173
|
}
|
|
174
|
+
|
|
196
175
|
/**
|
|
197
176
|
* Takes an argument and if it's an array, returns the first item in the array
|
|
198
177
|
* otherwise returns the argument
|
|
@@ -200,64 +179,52 @@ function getA11yStatusMessage$1(_ref2) {
|
|
|
200
179
|
* @param {*} defaultValue the value if arg is falsey not defined
|
|
201
180
|
* @return {*} the arg or it's first item
|
|
202
181
|
*/
|
|
203
|
-
|
|
204
|
-
|
|
205
182
|
function unwrapArray(arg, defaultValue) {
|
|
206
|
-
arg = Array.isArray(arg) ?
|
|
207
|
-
/* istanbul ignore next (preact) */
|
|
208
|
-
arg[0] : arg;
|
|
209
|
-
|
|
183
|
+
arg = Array.isArray(arg) ? /* istanbul ignore next (preact) */arg[0] : arg;
|
|
210
184
|
if (!arg && defaultValue) {
|
|
211
185
|
return defaultValue;
|
|
212
186
|
} else {
|
|
213
187
|
return arg;
|
|
214
188
|
}
|
|
215
189
|
}
|
|
190
|
+
|
|
216
191
|
/**
|
|
217
192
|
* @param {Object} element (P)react element
|
|
218
193
|
* @return {Boolean} whether it's a DOM element
|
|
219
194
|
*/
|
|
220
|
-
|
|
221
|
-
|
|
222
195
|
function isDOMElement(element) {
|
|
223
196
|
|
|
224
|
-
|
|
197
|
+
// then we assume this is react
|
|
225
198
|
return typeof element.type === 'string';
|
|
226
199
|
}
|
|
200
|
+
|
|
227
201
|
/**
|
|
228
202
|
* @param {Object} element (P)react element
|
|
229
203
|
* @return {Object} the props
|
|
230
204
|
*/
|
|
231
|
-
|
|
232
|
-
|
|
233
205
|
function getElementProps(element) {
|
|
234
|
-
|
|
235
206
|
return element.props;
|
|
236
207
|
}
|
|
208
|
+
|
|
237
209
|
/**
|
|
238
210
|
* Throws a helpful error message for required properties. Useful
|
|
239
211
|
* to be used as a default in destructuring or object params.
|
|
240
212
|
* @param {String} fnName the function name
|
|
241
213
|
* @param {String} propName the prop name
|
|
242
214
|
*/
|
|
243
|
-
|
|
244
|
-
|
|
245
215
|
function requiredProp(fnName, propName) {
|
|
246
216
|
// eslint-disable-next-line no-console
|
|
247
217
|
console.error(`The property "${propName}" is required in "${fnName}"`);
|
|
248
218
|
}
|
|
249
|
-
|
|
250
219
|
const stateKeys = ['highlightedIndex', 'inputValue', 'isOpen', 'selectedItem', 'type'];
|
|
251
220
|
/**
|
|
252
221
|
* @param {Object} state the state object
|
|
253
222
|
* @return {Object} state that is relevant to downshift
|
|
254
223
|
*/
|
|
255
|
-
|
|
256
224
|
function pickState(state) {
|
|
257
225
|
if (state === void 0) {
|
|
258
226
|
state = {};
|
|
259
227
|
}
|
|
260
|
-
|
|
261
228
|
const result = {};
|
|
262
229
|
stateKeys.forEach(k => {
|
|
263
230
|
if (state.hasOwnProperty(k)) {
|
|
@@ -266,6 +233,7 @@ function pickState(state) {
|
|
|
266
233
|
});
|
|
267
234
|
return result;
|
|
268
235
|
}
|
|
236
|
+
|
|
269
237
|
/**
|
|
270
238
|
* This will perform a shallow merge of the given state object
|
|
271
239
|
* with the state coming from props
|
|
@@ -277,14 +245,13 @@ function pickState(state) {
|
|
|
277
245
|
* @param {Object} props The props that may contain controlled values.
|
|
278
246
|
* @returns {Object} The merged controlled state.
|
|
279
247
|
*/
|
|
280
|
-
|
|
281
|
-
|
|
282
248
|
function getState(state, props) {
|
|
283
249
|
return Object.keys(state).reduce((prevState, key) => {
|
|
284
250
|
prevState[key] = isControlledProp(props, key) ? props[key] : state[key];
|
|
285
251
|
return prevState;
|
|
286
252
|
}, {});
|
|
287
253
|
}
|
|
254
|
+
|
|
288
255
|
/**
|
|
289
256
|
* This determines whether a prop is a "controlled prop" meaning it is
|
|
290
257
|
* state which is controlled by the outside of this component rather
|
|
@@ -294,41 +261,36 @@ function getState(state, props) {
|
|
|
294
261
|
* @param {String} key the key to check
|
|
295
262
|
* @return {Boolean} whether it is a controlled controlled prop
|
|
296
263
|
*/
|
|
297
|
-
|
|
298
|
-
|
|
299
264
|
function isControlledProp(props, key) {
|
|
300
265
|
return props[key] !== undefined;
|
|
301
266
|
}
|
|
267
|
+
|
|
302
268
|
/**
|
|
303
269
|
* Normalizes the 'key' property of a KeyboardEvent in IE/Edge
|
|
304
270
|
* @param {Object} event a keyboardEvent object
|
|
305
271
|
* @return {String} keyboard key
|
|
306
272
|
*/
|
|
307
|
-
|
|
308
|
-
|
|
309
273
|
function normalizeArrowKey(event) {
|
|
310
274
|
const {
|
|
311
275
|
key,
|
|
312
276
|
keyCode
|
|
313
277
|
} = event;
|
|
314
278
|
/* istanbul ignore next (ie) */
|
|
315
|
-
|
|
316
279
|
if (keyCode >= 37 && keyCode <= 40 && key.indexOf('Arrow') !== 0) {
|
|
317
280
|
return `Arrow${key}`;
|
|
318
281
|
}
|
|
319
|
-
|
|
320
282
|
return key;
|
|
321
283
|
}
|
|
284
|
+
|
|
322
285
|
/**
|
|
323
286
|
* Simple check if the value passed is object literal
|
|
324
287
|
* @param {*} obj any things
|
|
325
288
|
* @return {Boolean} whether it's object literal
|
|
326
289
|
*/
|
|
327
|
-
|
|
328
|
-
|
|
329
290
|
function isPlainObject(obj) {
|
|
330
291
|
return Object.prototype.toString.call(obj) === '[object Object]';
|
|
331
292
|
}
|
|
293
|
+
|
|
332
294
|
/**
|
|
333
295
|
* Returns the new index in the list, in a circular way. If next value is out of bonds from the total,
|
|
334
296
|
* it will wrap to either 0 or itemCount - 1.
|
|
@@ -340,39 +302,30 @@ function isPlainObject(obj) {
|
|
|
340
302
|
* @param {boolean} circular Specify if navigation is circular. Default is true.
|
|
341
303
|
* @returns {number} The new index after the move.
|
|
342
304
|
*/
|
|
343
|
-
|
|
344
|
-
|
|
345
305
|
function getNextWrappingIndex(moveAmount, baseIndex, itemCount, getItemNodeFromIndex, circular) {
|
|
346
306
|
if (circular === void 0) {
|
|
347
307
|
circular = true;
|
|
348
308
|
}
|
|
349
|
-
|
|
350
309
|
if (itemCount === 0) {
|
|
351
310
|
return -1;
|
|
352
311
|
}
|
|
353
|
-
|
|
354
312
|
const itemsLastIndex = itemCount - 1;
|
|
355
|
-
|
|
356
313
|
if (typeof baseIndex !== 'number' || baseIndex < 0 || baseIndex >= itemCount) {
|
|
357
314
|
baseIndex = moveAmount > 0 ? -1 : itemsLastIndex + 1;
|
|
358
315
|
}
|
|
359
|
-
|
|
360
316
|
let newIndex = baseIndex + moveAmount;
|
|
361
|
-
|
|
362
317
|
if (newIndex < 0) {
|
|
363
318
|
newIndex = circular ? itemsLastIndex : 0;
|
|
364
319
|
} else if (newIndex > itemsLastIndex) {
|
|
365
320
|
newIndex = circular ? 0 : itemsLastIndex;
|
|
366
321
|
}
|
|
367
|
-
|
|
368
322
|
const nonDisabledNewIndex = getNextNonDisabledIndex(moveAmount, newIndex, itemCount, getItemNodeFromIndex, circular);
|
|
369
|
-
|
|
370
323
|
if (nonDisabledNewIndex === -1) {
|
|
371
324
|
return baseIndex >= itemCount ? -1 : baseIndex;
|
|
372
325
|
}
|
|
373
|
-
|
|
374
326
|
return nonDisabledNewIndex;
|
|
375
327
|
}
|
|
328
|
+
|
|
376
329
|
/**
|
|
377
330
|
* Returns the next index in the list of an item that is not disabled.
|
|
378
331
|
*
|
|
@@ -383,15 +336,11 @@ function getNextWrappingIndex(moveAmount, baseIndex, itemCount, getItemNodeFromI
|
|
|
383
336
|
* @param {boolean} circular Specify if navigation is circular. Default is true.
|
|
384
337
|
* @returns {number} The new index. Returns baseIndex if item is not disabled. Returns next non-disabled item otherwise. If no non-disabled found it will return -1.
|
|
385
338
|
*/
|
|
386
|
-
|
|
387
|
-
|
|
388
339
|
function getNextNonDisabledIndex(moveAmount, baseIndex, itemCount, getItemNodeFromIndex, circular) {
|
|
389
340
|
const currentElementNode = getItemNodeFromIndex(baseIndex);
|
|
390
|
-
|
|
391
341
|
if (!currentElementNode || !currentElementNode.hasAttribute('disabled')) {
|
|
392
342
|
return baseIndex;
|
|
393
343
|
}
|
|
394
|
-
|
|
395
344
|
if (moveAmount > 0) {
|
|
396
345
|
for (let index = baseIndex + 1; index < itemCount; index++) {
|
|
397
346
|
if (!getItemNodeFromIndex(index).hasAttribute('disabled')) {
|
|
@@ -405,13 +354,12 @@ function getNextNonDisabledIndex(moveAmount, baseIndex, itemCount, getItemNodeFr
|
|
|
405
354
|
}
|
|
406
355
|
}
|
|
407
356
|
}
|
|
408
|
-
|
|
409
357
|
if (circular) {
|
|
410
358
|
return moveAmount > 0 ? getNextNonDisabledIndex(1, 0, itemCount, getItemNodeFromIndex, false) : getNextNonDisabledIndex(-1, itemCount - 1, itemCount, getItemNodeFromIndex, false);
|
|
411
359
|
}
|
|
412
|
-
|
|
413
360
|
return -1;
|
|
414
361
|
}
|
|
362
|
+
|
|
415
363
|
/**
|
|
416
364
|
* Checks if event target is within the downshift elements.
|
|
417
365
|
*
|
|
@@ -422,20 +370,16 @@ function getNextNonDisabledIndex(moveAmount, baseIndex, itemCount, getItemNodeFr
|
|
|
422
370
|
*
|
|
423
371
|
* @returns {boolean} Whether or not the target is within downshift elements.
|
|
424
372
|
*/
|
|
425
|
-
|
|
426
|
-
|
|
427
373
|
function targetWithinDownshift(target, downshiftElements, environment, checkActiveElement) {
|
|
428
374
|
if (checkActiveElement === void 0) {
|
|
429
375
|
checkActiveElement = true;
|
|
430
376
|
}
|
|
431
|
-
|
|
432
377
|
return downshiftElements.some(contextNode => contextNode && (isOrContainsNode(contextNode, target, environment) || checkActiveElement && isOrContainsNode(contextNode, environment.document.activeElement, environment)));
|
|
433
|
-
}
|
|
434
|
-
|
|
378
|
+
}
|
|
435
379
|
|
|
380
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
436
381
|
let validateControlledUnchanged = noop;
|
|
437
382
|
/* istanbul ignore next */
|
|
438
|
-
|
|
439
383
|
if (process.env.NODE_ENV !== 'production') {
|
|
440
384
|
validateControlledUnchanged = (state, prevProps, nextProps) => {
|
|
441
385
|
const warningDescription = `This prop should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled Downshift element for the lifetime of the component. More info: https://github.com/downshift-js/downshift#control-props`;
|
|
@@ -454,39 +398,33 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
454
398
|
const cleanupStatus = debounce(documentProp => {
|
|
455
399
|
getStatusDiv(documentProp).textContent = '';
|
|
456
400
|
}, 500);
|
|
401
|
+
|
|
457
402
|
/**
|
|
458
403
|
* @param {String} status the status message
|
|
459
404
|
* @param {Object} documentProp document passed by the user.
|
|
460
405
|
*/
|
|
461
|
-
|
|
462
406
|
function setStatus(status, documentProp) {
|
|
463
407
|
const div = getStatusDiv(documentProp);
|
|
464
|
-
|
|
465
408
|
if (!status) {
|
|
466
409
|
return;
|
|
467
410
|
}
|
|
468
|
-
|
|
469
411
|
div.textContent = status;
|
|
470
412
|
cleanupStatus(documentProp);
|
|
471
413
|
}
|
|
414
|
+
|
|
472
415
|
/**
|
|
473
416
|
* Get the status node or create it if it does not already exist.
|
|
474
417
|
* @param {Object} documentProp document passed by the user.
|
|
475
418
|
* @return {HTMLElement} the status node.
|
|
476
419
|
*/
|
|
477
|
-
|
|
478
|
-
|
|
479
420
|
function getStatusDiv(documentProp) {
|
|
480
421
|
if (documentProp === void 0) {
|
|
481
422
|
documentProp = document;
|
|
482
423
|
}
|
|
483
|
-
|
|
484
424
|
let statusDiv = documentProp.getElementById('a11y-status-message');
|
|
485
|
-
|
|
486
425
|
if (statusDiv) {
|
|
487
426
|
return statusDiv;
|
|
488
427
|
}
|
|
489
|
-
|
|
490
428
|
statusDiv = documentProp.createElement('div');
|
|
491
429
|
statusDiv.setAttribute('id', 'a11y-status-message');
|
|
492
430
|
statusDiv.setAttribute('role', 'status');
|
|
@@ -546,27 +484,22 @@ var stateChangeTypes$3 = /*#__PURE__*/Object.freeze({
|
|
|
546
484
|
});
|
|
547
485
|
|
|
548
486
|
/* eslint camelcase:0 */
|
|
549
|
-
|
|
550
487
|
const Downshift = /*#__PURE__*/(() => {
|
|
551
488
|
class Downshift extends react.Component {
|
|
552
489
|
constructor(_props) {
|
|
553
490
|
var _this;
|
|
554
|
-
|
|
555
491
|
super(_props);
|
|
556
492
|
_this = this;
|
|
557
493
|
this.id = this.props.id || `downshift-${generateId()}`;
|
|
558
494
|
this.menuId = this.props.menuId || `${this.id}-menu`;
|
|
559
495
|
this.labelId = this.props.labelId || `${this.id}-label`;
|
|
560
496
|
this.inputId = this.props.inputId || `${this.id}-input`;
|
|
561
|
-
|
|
562
497
|
this.getItemId = this.props.getItemId || (index => `${this.id}-item-${index}`);
|
|
563
|
-
|
|
564
498
|
this.input = null;
|
|
565
499
|
this.items = [];
|
|
566
500
|
this.itemCount = null;
|
|
567
501
|
this.previousResultCount = 0;
|
|
568
502
|
this.timeoutIds = [];
|
|
569
|
-
|
|
570
503
|
this.internalSetTimeout = (fn, time) => {
|
|
571
504
|
const id = setTimeout(() => {
|
|
572
505
|
this.timeoutIds = this.timeoutIds.filter(i => i !== id);
|
|
@@ -574,32 +507,25 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
574
507
|
}, time);
|
|
575
508
|
this.timeoutIds.push(id);
|
|
576
509
|
};
|
|
577
|
-
|
|
578
510
|
this.setItemCount = count => {
|
|
579
511
|
this.itemCount = count;
|
|
580
512
|
};
|
|
581
|
-
|
|
582
513
|
this.unsetItemCount = () => {
|
|
583
514
|
this.itemCount = null;
|
|
584
515
|
};
|
|
585
|
-
|
|
586
516
|
this.setHighlightedIndex = function (highlightedIndex, otherStateToSet) {
|
|
587
517
|
if (highlightedIndex === void 0) {
|
|
588
518
|
highlightedIndex = _this.props.defaultHighlightedIndex;
|
|
589
519
|
}
|
|
590
|
-
|
|
591
520
|
if (otherStateToSet === void 0) {
|
|
592
521
|
otherStateToSet = {};
|
|
593
522
|
}
|
|
594
|
-
|
|
595
523
|
otherStateToSet = pickState(otherStateToSet);
|
|
596
|
-
|
|
597
524
|
_this.internalSetState({
|
|
598
525
|
highlightedIndex,
|
|
599
526
|
...otherStateToSet
|
|
600
527
|
});
|
|
601
528
|
};
|
|
602
|
-
|
|
603
529
|
this.clearSelection = cb => {
|
|
604
530
|
this.internalSetState({
|
|
605
531
|
selectedItem: null,
|
|
@@ -608,7 +534,6 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
608
534
|
isOpen: this.props.defaultIsOpen
|
|
609
535
|
}, cb);
|
|
610
536
|
};
|
|
611
|
-
|
|
612
537
|
this.selectItem = (item, otherStateToSet, cb) => {
|
|
613
538
|
otherStateToSet = pickState(otherStateToSet);
|
|
614
539
|
this.internalSetState({
|
|
@@ -619,114 +544,105 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
619
544
|
...otherStateToSet
|
|
620
545
|
}, cb);
|
|
621
546
|
};
|
|
622
|
-
|
|
623
547
|
this.selectItemAtIndex = (itemIndex, otherStateToSet, cb) => {
|
|
624
548
|
const item = this.items[itemIndex];
|
|
625
|
-
|
|
626
549
|
if (item == null) {
|
|
627
550
|
return;
|
|
628
551
|
}
|
|
629
|
-
|
|
630
552
|
this.selectItem(item, otherStateToSet, cb);
|
|
631
553
|
};
|
|
632
|
-
|
|
633
554
|
this.selectHighlightedItem = (otherStateToSet, cb) => {
|
|
634
555
|
return this.selectItemAtIndex(this.getState().highlightedIndex, otherStateToSet, cb);
|
|
635
556
|
};
|
|
636
|
-
|
|
637
557
|
this.internalSetState = (stateToSet, cb) => {
|
|
638
558
|
let isItemSelected, onChangeArg;
|
|
639
559
|
const onStateChangeArg = {};
|
|
640
|
-
const isStateToSetFunction = typeof stateToSet === 'function';
|
|
560
|
+
const isStateToSetFunction = typeof stateToSet === 'function';
|
|
561
|
+
|
|
562
|
+
// we want to call `onInputValueChange` before the `setState` call
|
|
641
563
|
// so someone controlling the `inputValue` state gets notified of
|
|
642
564
|
// the input change as soon as possible. This avoids issues with
|
|
643
565
|
// preserving the cursor position.
|
|
644
566
|
// See https://github.com/downshift-js/downshift/issues/217 for more info.
|
|
645
|
-
|
|
646
567
|
if (!isStateToSetFunction && stateToSet.hasOwnProperty('inputValue')) {
|
|
647
|
-
this.props.onInputValueChange(stateToSet.inputValue, {
|
|
568
|
+
this.props.onInputValueChange(stateToSet.inputValue, {
|
|
569
|
+
...this.getStateAndHelpers(),
|
|
648
570
|
...stateToSet
|
|
649
571
|
});
|
|
650
572
|
}
|
|
651
|
-
|
|
652
573
|
return this.setState(state => {
|
|
653
574
|
state = this.getState(state);
|
|
654
|
-
let newStateToSet = isStateToSetFunction ? stateToSet(state) : stateToSet;
|
|
575
|
+
let newStateToSet = isStateToSetFunction ? stateToSet(state) : stateToSet;
|
|
655
576
|
|
|
656
|
-
|
|
577
|
+
// Your own function that could modify the state that will be set.
|
|
578
|
+
newStateToSet = this.props.stateReducer(state, newStateToSet);
|
|
579
|
+
|
|
580
|
+
// checks if an item is selected, regardless of if it's different from
|
|
657
581
|
// what was selected before
|
|
658
582
|
// used to determine if onSelect and onChange callbacks should be called
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
583
|
+
isItemSelected = newStateToSet.hasOwnProperty('selectedItem');
|
|
584
|
+
// this keeps track of the object we want to call with setState
|
|
585
|
+
const nextState = {};
|
|
586
|
+
// we need to call on change if the outside world is controlling any of our state
|
|
663
587
|
// and we're trying to update that state. OR if the selection has changed and we're
|
|
664
588
|
// trying to update the selection
|
|
665
|
-
|
|
666
589
|
if (isItemSelected && newStateToSet.selectedItem !== state.selectedItem) {
|
|
667
590
|
onChangeArg = newStateToSet.selectedItem;
|
|
668
591
|
}
|
|
669
|
-
|
|
670
592
|
newStateToSet.type = newStateToSet.type || unknown;
|
|
671
593
|
Object.keys(newStateToSet).forEach(key => {
|
|
672
594
|
// onStateChangeArg should only have the state that is
|
|
673
595
|
// actually changing
|
|
674
596
|
if (state[key] !== newStateToSet[key]) {
|
|
675
597
|
onStateChangeArg[key] = newStateToSet[key];
|
|
676
|
-
}
|
|
598
|
+
}
|
|
599
|
+
// the type is useful for the onStateChangeArg
|
|
677
600
|
// but we don't actually want to set it in internal state.
|
|
678
601
|
// this is an undocumented feature for now... Not all internalSetState
|
|
679
602
|
// calls support it and I'm not certain we want them to yet.
|
|
680
603
|
// But it enables users controlling the isOpen state to know when
|
|
681
604
|
// the isOpen state changes due to mouseup events which is quite handy.
|
|
682
|
-
|
|
683
|
-
|
|
684
605
|
if (key === 'type') {
|
|
685
606
|
return;
|
|
686
607
|
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
608
|
+
newStateToSet[key];
|
|
609
|
+
// if it's coming from props, then we don't care to set it internally
|
|
690
610
|
if (!isControlledProp(this.props, key)) {
|
|
691
611
|
nextState[key] = newStateToSet[key];
|
|
692
612
|
}
|
|
693
|
-
});
|
|
694
|
-
// earlier, so we'll call it now that we know what the inputValue state will be.
|
|
613
|
+
});
|
|
695
614
|
|
|
615
|
+
// if stateToSet is a function, then we weren't able to call onInputValueChange
|
|
616
|
+
// earlier, so we'll call it now that we know what the inputValue state will be.
|
|
696
617
|
if (isStateToSetFunction && newStateToSet.hasOwnProperty('inputValue')) {
|
|
697
|
-
this.props.onInputValueChange(newStateToSet.inputValue, {
|
|
618
|
+
this.props.onInputValueChange(newStateToSet.inputValue, {
|
|
619
|
+
...this.getStateAndHelpers(),
|
|
698
620
|
...newStateToSet
|
|
699
621
|
});
|
|
700
622
|
}
|
|
701
|
-
|
|
702
623
|
return nextState;
|
|
703
624
|
}, () => {
|
|
704
625
|
// call the provided callback if it's a function
|
|
705
|
-
cbToCb(cb)();
|
|
706
|
-
// we have relevant information to pass them.
|
|
626
|
+
cbToCb(cb)();
|
|
707
627
|
|
|
628
|
+
// only call the onStateChange and onChange callbacks if
|
|
629
|
+
// we have relevant information to pass them.
|
|
708
630
|
const hasMoreStateThanType = Object.keys(onStateChangeArg).length > 1;
|
|
709
|
-
|
|
710
631
|
if (hasMoreStateThanType) {
|
|
711
632
|
this.props.onStateChange(onStateChangeArg, this.getStateAndHelpers());
|
|
712
633
|
}
|
|
713
|
-
|
|
714
634
|
if (isItemSelected) {
|
|
715
635
|
this.props.onSelect(stateToSet.selectedItem, this.getStateAndHelpers());
|
|
716
636
|
}
|
|
717
|
-
|
|
718
637
|
if (onChangeArg !== undefined) {
|
|
719
638
|
this.props.onChange(onChangeArg, this.getStateAndHelpers());
|
|
720
|
-
}
|
|
639
|
+
}
|
|
640
|
+
// this is currently undocumented and therefore subject to change
|
|
721
641
|
// We'll try to not break it, but just be warned.
|
|
722
|
-
|
|
723
|
-
|
|
724
642
|
this.props.onUserAction(onStateChangeArg, this.getStateAndHelpers());
|
|
725
643
|
});
|
|
726
644
|
};
|
|
727
|
-
|
|
728
645
|
this.rootRef = node => this._rootNode = node;
|
|
729
|
-
|
|
730
646
|
this.getRootProps = function (_temp, _temp2) {
|
|
731
647
|
let {
|
|
732
648
|
refKey = 'ref',
|
|
@@ -741,11 +657,9 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
741
657
|
_this.getRootProps.called = true;
|
|
742
658
|
_this.getRootProps.refKey = refKey;
|
|
743
659
|
_this.getRootProps.suppressRefError = suppressRefError;
|
|
744
|
-
|
|
745
660
|
const {
|
|
746
661
|
isOpen
|
|
747
662
|
} = _this.getState();
|
|
748
|
-
|
|
749
663
|
return {
|
|
750
664
|
[refKey]: handleRefs(ref, _this.rootRef),
|
|
751
665
|
role: 'combobox',
|
|
@@ -756,11 +670,9 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
756
670
|
...rest
|
|
757
671
|
};
|
|
758
672
|
};
|
|
759
|
-
|
|
760
673
|
this.keyDownHandlers = {
|
|
761
674
|
ArrowDown(event) {
|
|
762
675
|
event.preventDefault();
|
|
763
|
-
|
|
764
676
|
if (this.getState().isOpen) {
|
|
765
677
|
const amount = event.shiftKey ? 5 : 1;
|
|
766
678
|
this.moveHighlightedIndex(amount, {
|
|
@@ -772,7 +684,6 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
772
684
|
type: keyDownArrowDown
|
|
773
685
|
}, () => {
|
|
774
686
|
const itemCount = this.getItemCount();
|
|
775
|
-
|
|
776
687
|
if (itemCount > 0) {
|
|
777
688
|
const {
|
|
778
689
|
highlightedIndex
|
|
@@ -785,10 +696,8 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
785
696
|
});
|
|
786
697
|
}
|
|
787
698
|
},
|
|
788
|
-
|
|
789
699
|
ArrowUp(event) {
|
|
790
700
|
event.preventDefault();
|
|
791
|
-
|
|
792
701
|
if (this.getState().isOpen) {
|
|
793
702
|
const amount = event.shiftKey ? -5 : -1;
|
|
794
703
|
this.moveHighlightedIndex(amount, {
|
|
@@ -800,7 +709,6 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
800
709
|
type: keyDownArrowUp
|
|
801
710
|
}, () => {
|
|
802
711
|
const itemCount = this.getItemCount();
|
|
803
|
-
|
|
804
712
|
if (itemCount > 0) {
|
|
805
713
|
const {
|
|
806
714
|
highlightedIndex
|
|
@@ -813,32 +721,26 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
813
721
|
});
|
|
814
722
|
}
|
|
815
723
|
},
|
|
816
|
-
|
|
817
724
|
Enter(event) {
|
|
818
725
|
if (event.which === 229) {
|
|
819
726
|
return;
|
|
820
727
|
}
|
|
821
|
-
|
|
822
728
|
const {
|
|
823
729
|
isOpen,
|
|
824
730
|
highlightedIndex
|
|
825
731
|
} = this.getState();
|
|
826
|
-
|
|
827
732
|
if (isOpen && highlightedIndex != null) {
|
|
828
733
|
event.preventDefault();
|
|
829
734
|
const item = this.items[highlightedIndex];
|
|
830
735
|
const itemNode = this.getItemNodeFromIndex(highlightedIndex);
|
|
831
|
-
|
|
832
736
|
if (item == null || itemNode && itemNode.hasAttribute('disabled')) {
|
|
833
737
|
return;
|
|
834
738
|
}
|
|
835
|
-
|
|
836
739
|
this.selectHighlightedItem({
|
|
837
740
|
type: keyDownEnter
|
|
838
741
|
});
|
|
839
742
|
}
|
|
840
743
|
},
|
|
841
|
-
|
|
842
744
|
Escape(event) {
|
|
843
745
|
event.preventDefault();
|
|
844
746
|
this.reset({
|
|
@@ -849,68 +751,57 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
849
751
|
})
|
|
850
752
|
});
|
|
851
753
|
}
|
|
852
|
-
|
|
853
754
|
};
|
|
854
|
-
this.buttonKeyDownHandlers = {
|
|
855
|
-
|
|
755
|
+
this.buttonKeyDownHandlers = {
|
|
756
|
+
...this.keyDownHandlers,
|
|
856
757
|
' '(event) {
|
|
857
758
|
event.preventDefault();
|
|
858
759
|
this.toggleMenu({
|
|
859
760
|
type: keyDownSpaceButton
|
|
860
761
|
});
|
|
861
762
|
}
|
|
862
|
-
|
|
863
763
|
};
|
|
864
|
-
this.inputKeyDownHandlers = {
|
|
865
|
-
|
|
764
|
+
this.inputKeyDownHandlers = {
|
|
765
|
+
...this.keyDownHandlers,
|
|
866
766
|
Home(event) {
|
|
867
767
|
const {
|
|
868
768
|
isOpen
|
|
869
769
|
} = this.getState();
|
|
870
|
-
|
|
871
770
|
if (!isOpen) {
|
|
872
771
|
return;
|
|
873
772
|
}
|
|
874
|
-
|
|
875
773
|
event.preventDefault();
|
|
876
774
|
const itemCount = this.getItemCount();
|
|
877
|
-
|
|
878
775
|
if (itemCount <= 0 || !isOpen) {
|
|
879
776
|
return;
|
|
880
|
-
}
|
|
881
|
-
|
|
777
|
+
}
|
|
882
778
|
|
|
779
|
+
// get next non-disabled starting downwards from 0 if that's disabled.
|
|
883
780
|
const newHighlightedIndex = getNextNonDisabledIndex(1, 0, itemCount, index => this.getItemNodeFromIndex(index), false);
|
|
884
781
|
this.setHighlightedIndex(newHighlightedIndex, {
|
|
885
782
|
type: keyDownHome
|
|
886
783
|
});
|
|
887
784
|
},
|
|
888
|
-
|
|
889
785
|
End(event) {
|
|
890
786
|
const {
|
|
891
787
|
isOpen
|
|
892
788
|
} = this.getState();
|
|
893
|
-
|
|
894
789
|
if (!isOpen) {
|
|
895
790
|
return;
|
|
896
791
|
}
|
|
897
|
-
|
|
898
792
|
event.preventDefault();
|
|
899
793
|
const itemCount = this.getItemCount();
|
|
900
|
-
|
|
901
794
|
if (itemCount <= 0 || !isOpen) {
|
|
902
795
|
return;
|
|
903
|
-
}
|
|
904
|
-
|
|
796
|
+
}
|
|
905
797
|
|
|
798
|
+
// get next non-disabled starting upwards from last index if that's disabled.
|
|
906
799
|
const newHighlightedIndex = getNextNonDisabledIndex(-1, itemCount - 1, itemCount, index => this.getItemNodeFromIndex(index), false);
|
|
907
800
|
this.setHighlightedIndex(newHighlightedIndex, {
|
|
908
801
|
type: keyDownEnd
|
|
909
802
|
});
|
|
910
803
|
}
|
|
911
|
-
|
|
912
804
|
};
|
|
913
|
-
|
|
914
805
|
this.getToggleButtonProps = function (_temp3) {
|
|
915
806
|
let {
|
|
916
807
|
onClick,
|
|
@@ -920,11 +811,9 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
920
811
|
onBlur,
|
|
921
812
|
...rest
|
|
922
813
|
} = _temp3 === void 0 ? {} : _temp3;
|
|
923
|
-
|
|
924
814
|
const {
|
|
925
815
|
isOpen
|
|
926
816
|
} = _this.getState();
|
|
927
|
-
|
|
928
817
|
const enabledEventHandlers = /* istanbul ignore next (react-native) */
|
|
929
818
|
{
|
|
930
819
|
onPress: callAllEventHandlers(onPress, _this.buttonHandleClick)
|
|
@@ -940,26 +829,21 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
940
829
|
...rest
|
|
941
830
|
};
|
|
942
831
|
};
|
|
943
|
-
|
|
944
832
|
this.buttonHandleKeyUp = event => {
|
|
945
833
|
// Prevent click event from emitting in Firefox
|
|
946
834
|
event.preventDefault();
|
|
947
835
|
};
|
|
948
|
-
|
|
949
836
|
this.buttonHandleKeyDown = event => {
|
|
950
837
|
const key = normalizeArrowKey(event);
|
|
951
|
-
|
|
952
838
|
if (this.buttonKeyDownHandlers[key]) {
|
|
953
839
|
this.buttonKeyDownHandlers[key].call(this, event);
|
|
954
840
|
}
|
|
955
841
|
};
|
|
956
|
-
|
|
957
842
|
this.buttonHandleClick = event => {
|
|
958
|
-
event.preventDefault();
|
|
843
|
+
event.preventDefault();
|
|
844
|
+
// to simplify testing components that use downshift, we'll not wrap this in a setTimeout
|
|
959
845
|
// if the NODE_ENV is test. With the proper build system, this should be dead code eliminated
|
|
960
846
|
// when building for production and should therefore have no impact on production code.
|
|
961
|
-
|
|
962
|
-
|
|
963
847
|
if (process.env.NODE_ENV === 'test') {
|
|
964
848
|
this.toggleMenu({
|
|
965
849
|
type: clickButton
|
|
@@ -971,11 +855,9 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
971
855
|
}));
|
|
972
856
|
}
|
|
973
857
|
};
|
|
974
|
-
|
|
975
858
|
this.buttonHandleBlur = event => {
|
|
976
859
|
const blurTarget = event.target; // Save blur target for comparison with activeElement later
|
|
977
860
|
// Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not body element
|
|
978
|
-
|
|
979
861
|
this.internalSetTimeout(() => {
|
|
980
862
|
if (!this.isMouseDown && (this.props.environment.document.activeElement == null || this.props.environment.document.activeElement.id !== this.inputId) && this.props.environment.document.activeElement !== blurTarget // Do nothing if we refocus the same element again (to solve issue in Safari on iOS)
|
|
981
863
|
) {
|
|
@@ -985,7 +867,6 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
985
867
|
}
|
|
986
868
|
});
|
|
987
869
|
};
|
|
988
|
-
|
|
989
870
|
this.getLabelProps = props => {
|
|
990
871
|
return {
|
|
991
872
|
htmlFor: this.inputId,
|
|
@@ -993,7 +874,6 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
993
874
|
...props
|
|
994
875
|
};
|
|
995
876
|
};
|
|
996
|
-
|
|
997
877
|
this.getInputProps = function (_temp4) {
|
|
998
878
|
let {
|
|
999
879
|
onKeyDown,
|
|
@@ -1005,18 +885,16 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1005
885
|
} = _temp4 === void 0 ? {} : _temp4;
|
|
1006
886
|
let onChangeKey;
|
|
1007
887
|
let eventHandlers = {};
|
|
1008
|
-
/* istanbul ignore next (preact) */
|
|
1009
888
|
|
|
889
|
+
/* istanbul ignore next (preact) */
|
|
1010
890
|
{
|
|
1011
891
|
onChangeKey = 'onChange';
|
|
1012
892
|
}
|
|
1013
|
-
|
|
1014
893
|
const {
|
|
1015
894
|
inputValue,
|
|
1016
895
|
isOpen,
|
|
1017
896
|
highlightedIndex
|
|
1018
897
|
} = _this.getState();
|
|
1019
|
-
|
|
1020
898
|
if (!rest.disabled) {
|
|
1021
899
|
eventHandlers = {
|
|
1022
900
|
[onChangeKey]: callAllEventHandlers(onChange, onInput, _this.inputHandleChange),
|
|
@@ -1024,9 +902,8 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1024
902
|
onBlur: callAllEventHandlers(onBlur, _this.inputHandleBlur)
|
|
1025
903
|
};
|
|
1026
904
|
}
|
|
1027
|
-
/* istanbul ignore if (react-native) */
|
|
1028
|
-
|
|
1029
905
|
|
|
906
|
+
/* istanbul ignore if (react-native) */
|
|
1030
907
|
{
|
|
1031
908
|
eventHandlers = {
|
|
1032
909
|
onChange: callAllEventHandlers(onChange, onInput, _this.inputHandleChange),
|
|
@@ -1038,7 +915,6 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1038
915
|
onBlur: callAllEventHandlers(onBlur, _this.inputHandleBlur)
|
|
1039
916
|
};
|
|
1040
917
|
}
|
|
1041
|
-
|
|
1042
918
|
return {
|
|
1043
919
|
'aria-autocomplete': 'list',
|
|
1044
920
|
'aria-activedescendant': isOpen && typeof highlightedIndex === 'number' && highlightedIndex >= 0 ? _this.getItemId(highlightedIndex) : null,
|
|
@@ -1053,30 +929,24 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1053
929
|
...rest
|
|
1054
930
|
};
|
|
1055
931
|
};
|
|
1056
|
-
|
|
1057
932
|
this.inputHandleKeyDown = event => {
|
|
1058
933
|
const key = normalizeArrowKey(event);
|
|
1059
|
-
|
|
1060
934
|
if (key && this.inputKeyDownHandlers[key]) {
|
|
1061
935
|
this.inputKeyDownHandlers[key].call(this, event);
|
|
1062
936
|
}
|
|
1063
937
|
};
|
|
1064
|
-
|
|
1065
938
|
this.inputHandleChange = event => {
|
|
1066
939
|
this.internalSetState({
|
|
1067
940
|
type: changeInput,
|
|
1068
941
|
isOpen: true,
|
|
1069
|
-
inputValue: /* istanbul ignore next (react-native) */
|
|
1070
|
-
event.nativeEvent.text ,
|
|
942
|
+
inputValue: /* istanbul ignore next (react-native) */event.nativeEvent.text ,
|
|
1071
943
|
highlightedIndex: this.props.defaultHighlightedIndex
|
|
1072
944
|
});
|
|
1073
945
|
};
|
|
1074
|
-
|
|
1075
946
|
this.inputHandleBlur = () => {
|
|
1076
947
|
// Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not the body element
|
|
1077
948
|
this.internalSetTimeout(() => {
|
|
1078
949
|
const downshiftButtonIsActive = this.props.environment.document && !!this.props.environment.document.activeElement && !!this.props.environment.document.activeElement.dataset && this.props.environment.document.activeElement.dataset.toggle && this._rootNode && this._rootNode.contains(this.props.environment.document.activeElement);
|
|
1079
|
-
|
|
1080
950
|
if (!this.isMouseDown && !downshiftButtonIsActive) {
|
|
1081
951
|
this.reset({
|
|
1082
952
|
type: blurInput
|
|
@@ -1084,11 +954,9 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1084
954
|
}
|
|
1085
955
|
});
|
|
1086
956
|
};
|
|
1087
|
-
|
|
1088
957
|
this.menuRef = node => {
|
|
1089
958
|
this._menuNode = node;
|
|
1090
959
|
};
|
|
1091
|
-
|
|
1092
960
|
this.getMenuProps = function (_temp5, _temp6) {
|
|
1093
961
|
let {
|
|
1094
962
|
refKey = 'ref',
|
|
@@ -1109,7 +977,6 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1109
977
|
...props
|
|
1110
978
|
};
|
|
1111
979
|
};
|
|
1112
|
-
|
|
1113
980
|
this.getItemProps = function (_temp7) {
|
|
1114
981
|
let {
|
|
1115
982
|
onMouseMove,
|
|
@@ -1117,24 +984,17 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1117
984
|
onClick,
|
|
1118
985
|
onPress,
|
|
1119
986
|
index,
|
|
1120
|
-
item = process.env.NODE_ENV === 'production' ?
|
|
1121
|
-
/* istanbul ignore next */
|
|
1122
|
-
undefined : requiredProp('getItemProps', 'item'),
|
|
987
|
+
item = process.env.NODE_ENV === 'production' ? /* istanbul ignore next */undefined : requiredProp('getItemProps', 'item'),
|
|
1123
988
|
...rest
|
|
1124
989
|
} = _temp7 === void 0 ? {} : _temp7;
|
|
1125
|
-
|
|
1126
990
|
if (index === undefined) {
|
|
1127
991
|
_this.items.push(item);
|
|
1128
|
-
|
|
1129
992
|
index = _this.items.indexOf(item);
|
|
1130
993
|
} else {
|
|
1131
994
|
_this.items[index] = item;
|
|
1132
995
|
}
|
|
1133
|
-
|
|
1134
|
-
const
|
|
1135
|
-
'onPress' ;
|
|
1136
|
-
const customClickHandler = /* istanbul ignore next (react-native) */
|
|
1137
|
-
onPress ;
|
|
996
|
+
const onSelectKey = /* istanbul ignore next (react-native) */'onPress' ;
|
|
997
|
+
const customClickHandler = /* istanbul ignore next (react-native) */onPress ;
|
|
1138
998
|
const enabledEventHandlers = {
|
|
1139
999
|
// onMouseMove is used over onMouseEnter here. onMouseMove
|
|
1140
1000
|
// is only triggered on actual mouse movement while onMouseEnter
|
|
@@ -1143,17 +1003,15 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1143
1003
|
if (index === _this.getState().highlightedIndex) {
|
|
1144
1004
|
return;
|
|
1145
1005
|
}
|
|
1146
|
-
|
|
1147
1006
|
_this.setHighlightedIndex(index, {
|
|
1148
1007
|
type: itemMouseEnter
|
|
1149
|
-
});
|
|
1008
|
+
});
|
|
1009
|
+
|
|
1010
|
+
// We never want to manually scroll when changing state based
|
|
1150
1011
|
// on `onMouseMove` because we will be moving the element out
|
|
1151
1012
|
// from under the user which is currently scrolling/moving the
|
|
1152
1013
|
// cursor
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
1014
|
_this.avoidScrolling = true;
|
|
1156
|
-
|
|
1157
1015
|
_this.internalSetTimeout(() => _this.avoidScrolling = false, 250);
|
|
1158
1016
|
}),
|
|
1159
1017
|
onMouseDown: callAllEventHandlers(onMouseDown, event => {
|
|
@@ -1167,9 +1025,10 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1167
1025
|
type: clickItem
|
|
1168
1026
|
});
|
|
1169
1027
|
})
|
|
1170
|
-
};
|
|
1171
|
-
// of the activeElement if clicking on disabled items
|
|
1028
|
+
};
|
|
1172
1029
|
|
|
1030
|
+
// Passing down the onMouseDown handler to prevent redirect
|
|
1031
|
+
// of the activeElement if clicking on disabled items
|
|
1173
1032
|
const eventHandlers = rest.disabled ? {
|
|
1174
1033
|
onMouseDown: enabledEventHandlers.onMouseDown
|
|
1175
1034
|
} : enabledEventHandlers;
|
|
@@ -1181,18 +1040,14 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1181
1040
|
...rest
|
|
1182
1041
|
};
|
|
1183
1042
|
};
|
|
1184
|
-
|
|
1185
1043
|
this.clearItems = () => {
|
|
1186
1044
|
this.items = [];
|
|
1187
1045
|
};
|
|
1188
|
-
|
|
1189
1046
|
this.reset = function (otherStateToSet, cb) {
|
|
1190
1047
|
if (otherStateToSet === void 0) {
|
|
1191
1048
|
otherStateToSet = {};
|
|
1192
1049
|
}
|
|
1193
|
-
|
|
1194
1050
|
otherStateToSet = pickState(otherStateToSet);
|
|
1195
|
-
|
|
1196
1051
|
_this.internalSetState(_ref => {
|
|
1197
1052
|
let {
|
|
1198
1053
|
selectedItem
|
|
@@ -1205,14 +1060,11 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1205
1060
|
};
|
|
1206
1061
|
}, cb);
|
|
1207
1062
|
};
|
|
1208
|
-
|
|
1209
1063
|
this.toggleMenu = function (otherStateToSet, cb) {
|
|
1210
1064
|
if (otherStateToSet === void 0) {
|
|
1211
1065
|
otherStateToSet = {};
|
|
1212
1066
|
}
|
|
1213
|
-
|
|
1214
1067
|
otherStateToSet = pickState(otherStateToSet);
|
|
1215
|
-
|
|
1216
1068
|
_this.internalSetState(_ref2 => {
|
|
1217
1069
|
let {
|
|
1218
1070
|
isOpen
|
|
@@ -1229,29 +1081,24 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1229
1081
|
isOpen,
|
|
1230
1082
|
highlightedIndex
|
|
1231
1083
|
} = _this.getState();
|
|
1232
|
-
|
|
1233
1084
|
if (isOpen) {
|
|
1234
1085
|
if (_this.getItemCount() > 0 && typeof highlightedIndex === 'number') {
|
|
1235
1086
|
_this.setHighlightedIndex(highlightedIndex, otherStateToSet);
|
|
1236
1087
|
}
|
|
1237
1088
|
}
|
|
1238
|
-
|
|
1239
1089
|
cbToCb(cb)();
|
|
1240
1090
|
});
|
|
1241
1091
|
};
|
|
1242
|
-
|
|
1243
1092
|
this.openMenu = cb => {
|
|
1244
1093
|
this.internalSetState({
|
|
1245
1094
|
isOpen: true
|
|
1246
1095
|
}, cb);
|
|
1247
1096
|
};
|
|
1248
|
-
|
|
1249
1097
|
this.closeMenu = cb => {
|
|
1250
1098
|
this.internalSetState({
|
|
1251
1099
|
isOpen: false
|
|
1252
1100
|
}, cb);
|
|
1253
1101
|
};
|
|
1254
|
-
|
|
1255
1102
|
this.updateStatus = debounce(() => {
|
|
1256
1103
|
const state = this.getState();
|
|
1257
1104
|
const item = this.items[state.highlightedIndex];
|
|
@@ -1277,21 +1124,17 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1277
1124
|
initialInputValue: _inputValue = '',
|
|
1278
1125
|
initialSelectedItem: _selectedItem = null
|
|
1279
1126
|
} = this.props;
|
|
1280
|
-
|
|
1281
1127
|
const _state = this.getState({
|
|
1282
1128
|
highlightedIndex: _highlightedIndex,
|
|
1283
1129
|
isOpen: _isOpen,
|
|
1284
1130
|
inputValue: _inputValue,
|
|
1285
1131
|
selectedItem: _selectedItem
|
|
1286
1132
|
});
|
|
1287
|
-
|
|
1288
1133
|
if (_state.selectedItem != null && this.props.initialInputValue === undefined) {
|
|
1289
1134
|
_state.inputValue = this.props.itemToString(_state.selectedItem);
|
|
1290
1135
|
}
|
|
1291
|
-
|
|
1292
1136
|
this.state = _state;
|
|
1293
1137
|
}
|
|
1294
|
-
|
|
1295
1138
|
/**
|
|
1296
1139
|
* Clear all running timeouts
|
|
1297
1140
|
*/
|
|
@@ -1301,6 +1144,7 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1301
1144
|
});
|
|
1302
1145
|
this.timeoutIds = [];
|
|
1303
1146
|
}
|
|
1147
|
+
|
|
1304
1148
|
/**
|
|
1305
1149
|
* Gets the state based on internal state or props
|
|
1306
1150
|
* If a state value is passed via props, then that
|
|
@@ -1310,51 +1154,40 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1310
1154
|
* @param {Object} stateToMerge defaults to this.state
|
|
1311
1155
|
* @return {Object} the state
|
|
1312
1156
|
*/
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
1157
|
getState(stateToMerge) {
|
|
1316
1158
|
if (stateToMerge === void 0) {
|
|
1317
1159
|
stateToMerge = this.state;
|
|
1318
1160
|
}
|
|
1319
|
-
|
|
1320
1161
|
return getState(stateToMerge, this.props);
|
|
1321
1162
|
}
|
|
1322
|
-
|
|
1323
1163
|
getItemCount() {
|
|
1324
1164
|
// things read better this way. They're in priority order:
|
|
1325
1165
|
// 1. `this.itemCount`
|
|
1326
1166
|
// 2. `this.props.itemCount`
|
|
1327
1167
|
// 3. `this.items.length`
|
|
1328
1168
|
let itemCount = this.items.length;
|
|
1329
|
-
|
|
1330
1169
|
if (this.itemCount != null) {
|
|
1331
1170
|
itemCount = this.itemCount;
|
|
1332
1171
|
} else if (this.props.itemCount !== undefined) {
|
|
1333
1172
|
itemCount = this.props.itemCount;
|
|
1334
1173
|
}
|
|
1335
|
-
|
|
1336
1174
|
return itemCount;
|
|
1337
1175
|
}
|
|
1338
|
-
|
|
1339
1176
|
getItemNodeFromIndex(index) {
|
|
1340
1177
|
return this.props.environment.document.getElementById(this.getItemId(index));
|
|
1341
1178
|
}
|
|
1342
|
-
|
|
1343
1179
|
scrollHighlightedItemIntoView() {
|
|
1344
1180
|
}
|
|
1345
|
-
|
|
1346
1181
|
moveHighlightedIndex(amount, otherStateToSet) {
|
|
1347
1182
|
const itemCount = this.getItemCount();
|
|
1348
1183
|
const {
|
|
1349
1184
|
highlightedIndex
|
|
1350
1185
|
} = this.getState();
|
|
1351
|
-
|
|
1352
1186
|
if (itemCount > 0) {
|
|
1353
1187
|
const nextHighlightedIndex = getNextWrappingIndex(amount, highlightedIndex, itemCount, index => this.getItemNodeFromIndex(index));
|
|
1354
1188
|
this.setHighlightedIndex(nextHighlightedIndex, otherStateToSet);
|
|
1355
1189
|
}
|
|
1356
1190
|
}
|
|
1357
|
-
|
|
1358
1191
|
getStateAndHelpers() {
|
|
1359
1192
|
const {
|
|
1360
1193
|
highlightedIndex,
|
|
@@ -1421,24 +1254,23 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1421
1254
|
isOpen,
|
|
1422
1255
|
selectedItem
|
|
1423
1256
|
};
|
|
1424
|
-
}
|
|
1257
|
+
}
|
|
1425
1258
|
|
|
1259
|
+
//////////////////////////// ROOT
|
|
1426
1260
|
|
|
1427
1261
|
componentDidMount() {
|
|
1428
1262
|
/* istanbul ignore if (react-native) */
|
|
1429
1263
|
if (process.env.NODE_ENV !== 'production' && !true && this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
|
|
1430
1264
|
validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
|
|
1431
1265
|
}
|
|
1432
|
-
/* istanbul ignore if (react-native) */
|
|
1433
|
-
|
|
1434
1266
|
|
|
1267
|
+
/* istanbul ignore if (react-native) */
|
|
1435
1268
|
{
|
|
1436
1269
|
this.cleanup = () => {
|
|
1437
1270
|
this.internalClearTimeouts();
|
|
1438
1271
|
};
|
|
1439
1272
|
}
|
|
1440
1273
|
}
|
|
1441
|
-
|
|
1442
1274
|
shouldScroll(prevState, prevProps) {
|
|
1443
1275
|
const {
|
|
1444
1276
|
highlightedIndex: currentHighlightedIndex
|
|
@@ -1450,82 +1282,72 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1450
1282
|
const scrollWhenNavigating = currentHighlightedIndex !== prevHighlightedIndex;
|
|
1451
1283
|
return scrollWhenOpen || scrollWhenNavigating;
|
|
1452
1284
|
}
|
|
1453
|
-
|
|
1454
1285
|
componentDidUpdate(prevProps, prevState) {
|
|
1455
1286
|
if (process.env.NODE_ENV !== 'production') {
|
|
1456
1287
|
validateControlledUnchanged(this.state, prevProps, this.props);
|
|
1457
1288
|
}
|
|
1458
|
-
|
|
1459
1289
|
if (isControlledProp(this.props, 'selectedItem') && this.props.selectedItemChanged(prevProps.selectedItem, this.props.selectedItem)) {
|
|
1460
1290
|
this.internalSetState({
|
|
1461
1291
|
type: controlledPropUpdatedSelectedItem,
|
|
1462
1292
|
inputValue: this.props.itemToString(this.props.selectedItem)
|
|
1463
1293
|
});
|
|
1464
1294
|
}
|
|
1465
|
-
|
|
1466
1295
|
if (!this.avoidScrolling && this.shouldScroll(prevState, prevProps)) {
|
|
1467
1296
|
this.scrollHighlightedItemIntoView();
|
|
1468
1297
|
}
|
|
1469
1298
|
}
|
|
1470
|
-
|
|
1471
1299
|
componentWillUnmount() {
|
|
1472
1300
|
this.cleanup(); // avoids memory leak
|
|
1473
1301
|
}
|
|
1474
1302
|
|
|
1475
1303
|
render() {
|
|
1476
|
-
const children = unwrapArray(this.props.children, noop);
|
|
1304
|
+
const children = unwrapArray(this.props.children, noop);
|
|
1305
|
+
// because the items are rerendered every time we call the children
|
|
1477
1306
|
// we clear this out each render and it will be populated again as
|
|
1478
1307
|
// getItemProps is called.
|
|
1479
|
-
|
|
1480
|
-
|
|
1308
|
+
this.clearItems();
|
|
1309
|
+
// we reset this so we know whether the user calls getRootProps during
|
|
1481
1310
|
// this render. If they do then we don't need to do anything,
|
|
1482
1311
|
// if they don't then we need to clone the element they return and
|
|
1483
1312
|
// apply the props for them.
|
|
1484
|
-
|
|
1485
1313
|
this.getRootProps.called = false;
|
|
1486
1314
|
this.getRootProps.refKey = undefined;
|
|
1487
|
-
this.getRootProps.suppressRefError = undefined;
|
|
1488
|
-
|
|
1315
|
+
this.getRootProps.suppressRefError = undefined;
|
|
1316
|
+
// we do something similar for getMenuProps
|
|
1489
1317
|
this.getMenuProps.called = false;
|
|
1490
1318
|
this.getMenuProps.refKey = undefined;
|
|
1491
|
-
this.getMenuProps.suppressRefError = undefined;
|
|
1492
|
-
|
|
1493
|
-
this.getLabelProps.called = false;
|
|
1494
|
-
|
|
1319
|
+
this.getMenuProps.suppressRefError = undefined;
|
|
1320
|
+
// we do something similar for getLabelProps
|
|
1321
|
+
this.getLabelProps.called = false;
|
|
1322
|
+
// and something similar for getInputProps
|
|
1495
1323
|
this.getInputProps.called = false;
|
|
1496
1324
|
const element = unwrapArray(children(this.getStateAndHelpers()));
|
|
1497
|
-
|
|
1498
1325
|
if (!element) {
|
|
1499
1326
|
return null;
|
|
1500
1327
|
}
|
|
1501
|
-
|
|
1502
1328
|
if (this.getRootProps.called || this.props.suppressRefError) {
|
|
1503
1329
|
if (process.env.NODE_ENV !== 'production' && !this.getRootProps.suppressRefError && !this.props.suppressRefError) {
|
|
1504
1330
|
validateGetRootPropsCalledCorrectly(element, this.getRootProps);
|
|
1505
1331
|
}
|
|
1506
|
-
|
|
1507
1332
|
return element;
|
|
1508
1333
|
} else if (isDOMElement(element)) {
|
|
1509
1334
|
// they didn't apply the root props, but we can clone
|
|
1510
1335
|
// this and apply the props ourselves
|
|
1511
1336
|
return /*#__PURE__*/react.cloneElement(element, this.getRootProps(getElementProps(element)));
|
|
1512
1337
|
}
|
|
1513
|
-
/* istanbul ignore else */
|
|
1514
|
-
|
|
1515
1338
|
|
|
1339
|
+
/* istanbul ignore else */
|
|
1516
1340
|
if (process.env.NODE_ENV !== 'production') {
|
|
1517
1341
|
// they didn't apply the root props, but they need to
|
|
1518
1342
|
// otherwise we can't query around the autocomplete
|
|
1343
|
+
|
|
1519
1344
|
throw new Error('downshift: If you return a non-DOM element, you must apply the getRootProps function');
|
|
1520
1345
|
}
|
|
1521
|
-
/* istanbul ignore next */
|
|
1522
|
-
|
|
1523
1346
|
|
|
1347
|
+
/* istanbul ignore next */
|
|
1524
1348
|
return undefined;
|
|
1525
1349
|
}
|
|
1526
|
-
|
|
1527
1350
|
}
|
|
1528
|
-
|
|
1529
1351
|
Downshift.defaultProps = {
|
|
1530
1352
|
defaultHighlightedIndex: null,
|
|
1531
1353
|
defaultIsOpen: false,
|
|
@@ -1534,12 +1356,10 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1534
1356
|
if (i == null) {
|
|
1535
1357
|
return '';
|
|
1536
1358
|
}
|
|
1537
|
-
|
|
1538
1359
|
if (process.env.NODE_ENV !== 'production' && isPlainObject(i) && !i.hasOwnProperty('toString')) {
|
|
1539
1360
|
// eslint-disable-next-line no-console
|
|
1540
1361
|
console.warn('downshift: An object was passed to the default implementation of `itemToString`. You should probably provide your own `itemToString` implementation. Please refer to the `itemToString` API documentation.', 'The object that was passed:', i);
|
|
1541
1362
|
}
|
|
1542
|
-
|
|
1543
1363
|
return String(i);
|
|
1544
1364
|
},
|
|
1545
1365
|
onStateChange: noop,
|
|
@@ -1549,8 +1369,7 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1549
1369
|
onSelect: noop,
|
|
1550
1370
|
onOuterClick: noop,
|
|
1551
1371
|
selectedItemChanged: (prevItem, item) => prevItem !== item,
|
|
1552
|
-
environment:
|
|
1553
|
-
/* istanbul ignore next (ssr) */
|
|
1372
|
+
environment: /* istanbul ignore next (ssr) */
|
|
1554
1373
|
typeof window === 'undefined' ? {} : window,
|
|
1555
1374
|
stateReducer: (state, stateToSet) => stateToSet,
|
|
1556
1375
|
suppressRefError: false,
|
|
@@ -1559,7 +1378,6 @@ const Downshift = /*#__PURE__*/(() => {
|
|
|
1559
1378
|
Downshift.stateChangeTypes = stateChangeTypes$3;
|
|
1560
1379
|
return Downshift;
|
|
1561
1380
|
})();
|
|
1562
|
-
|
|
1563
1381
|
process.env.NODE_ENV !== "production" ? Downshift.propTypes = {
|
|
1564
1382
|
children: PropTypes__default["default"].func,
|
|
1565
1383
|
defaultHighlightedIndex: PropTypes__default["default"].number,
|
|
@@ -1593,7 +1411,6 @@ process.env.NODE_ENV !== "production" ? Downshift.propTypes = {
|
|
|
1593
1411
|
scrollIntoView: PropTypes__default["default"].func,
|
|
1594
1412
|
// things we keep in state for uncontrolled components
|
|
1595
1413
|
// but can accept as props for controlled components
|
|
1596
|
-
|
|
1597
1414
|
/* eslint-disable react/no-unused-prop-types */
|
|
1598
1415
|
selectedItem: PropTypes__default["default"].any,
|
|
1599
1416
|
isOpen: PropTypes__default["default"].bool,
|
|
@@ -1604,28 +1421,23 @@ process.env.NODE_ENV !== "production" ? Downshift.propTypes = {
|
|
|
1604
1421
|
menuId: PropTypes__default["default"].string,
|
|
1605
1422
|
getItemId: PropTypes__default["default"].func
|
|
1606
1423
|
/* eslint-enable react/no-unused-prop-types */
|
|
1607
|
-
|
|
1608
1424
|
} : void 0;
|
|
1609
1425
|
var Downshift$1 = Downshift;
|
|
1610
|
-
|
|
1611
1426
|
function validateGetMenuPropsCalledCorrectly(node, _ref3) {
|
|
1612
1427
|
let {
|
|
1613
1428
|
refKey
|
|
1614
1429
|
} = _ref3;
|
|
1615
|
-
|
|
1616
1430
|
if (!node) {
|
|
1617
1431
|
// eslint-disable-next-line no-console
|
|
1618
1432
|
console.error(`downshift: The ref prop "${refKey}" from getMenuProps was not applied correctly on your menu element.`);
|
|
1619
1433
|
}
|
|
1620
1434
|
}
|
|
1621
|
-
|
|
1622
1435
|
function validateGetRootPropsCalledCorrectly(element, _ref4) {
|
|
1623
1436
|
let {
|
|
1624
1437
|
refKey
|
|
1625
1438
|
} = _ref4;
|
|
1626
1439
|
const refKeySpecified = refKey !== 'ref';
|
|
1627
1440
|
const isComposite = !isDOMElement(element);
|
|
1628
|
-
|
|
1629
1441
|
if (isComposite && !refKeySpecified && !reactIs.isForwardRef(element)) {
|
|
1630
1442
|
// eslint-disable-next-line no-console
|
|
1631
1443
|
console.error('downshift: You returned a non-DOM element. You must specify a refKey in getRootProps');
|
|
@@ -1633,7 +1445,6 @@ function validateGetRootPropsCalledCorrectly(element, _ref4) {
|
|
|
1633
1445
|
// eslint-disable-next-line no-console
|
|
1634
1446
|
console.error(`downshift: You returned a DOM element. You should not specify a refKey in getRootProps. You specified "${refKey}"`);
|
|
1635
1447
|
}
|
|
1636
|
-
|
|
1637
1448
|
if (!reactIs.isForwardRef(element) && !getElementProps(element)[refKey]) {
|
|
1638
1449
|
// eslint-disable-next-line no-console
|
|
1639
1450
|
console.error(`downshift: You must apply the ref prop "${refKey}" from getRootProps onto your root element.`);
|
|
@@ -1646,7 +1457,6 @@ const dropdownDefaultStateValues = {
|
|
|
1646
1457
|
selectedItem: null,
|
|
1647
1458
|
inputValue: ''
|
|
1648
1459
|
};
|
|
1649
|
-
|
|
1650
1460
|
function callOnChangeProps(action, state, newState) {
|
|
1651
1461
|
const {
|
|
1652
1462
|
props,
|
|
@@ -1655,12 +1465,10 @@ function callOnChangeProps(action, state, newState) {
|
|
|
1655
1465
|
const changes = {};
|
|
1656
1466
|
Object.keys(state).forEach(key => {
|
|
1657
1467
|
invokeOnChangeHandler(key, action, state, newState);
|
|
1658
|
-
|
|
1659
1468
|
if (newState[key] !== state[key]) {
|
|
1660
1469
|
changes[key] = newState[key];
|
|
1661
1470
|
}
|
|
1662
1471
|
});
|
|
1663
|
-
|
|
1664
1472
|
if (props.onStateChange && Object.keys(changes).length) {
|
|
1665
1473
|
props.onStateChange({
|
|
1666
1474
|
type,
|
|
@@ -1668,14 +1476,12 @@ function callOnChangeProps(action, state, newState) {
|
|
|
1668
1476
|
});
|
|
1669
1477
|
}
|
|
1670
1478
|
}
|
|
1671
|
-
|
|
1672
1479
|
function invokeOnChangeHandler(key, action, state, newState) {
|
|
1673
1480
|
const {
|
|
1674
1481
|
props,
|
|
1675
1482
|
type
|
|
1676
1483
|
} = action;
|
|
1677
1484
|
const handler = `on${capitalizeString(key)}Change`;
|
|
1678
|
-
|
|
1679
1485
|
if (props[handler] && newState[key] !== undefined && newState[key] !== state[key]) {
|
|
1680
1486
|
props[handler]({
|
|
1681
1487
|
type,
|
|
@@ -1683,6 +1489,7 @@ function invokeOnChangeHandler(key, action, state, newState) {
|
|
|
1683
1489
|
});
|
|
1684
1490
|
}
|
|
1685
1491
|
}
|
|
1492
|
+
|
|
1686
1493
|
/**
|
|
1687
1494
|
* Default state reducer that returns the changes.
|
|
1688
1495
|
*
|
|
@@ -1690,19 +1497,16 @@ function invokeOnChangeHandler(key, action, state, newState) {
|
|
|
1690
1497
|
* @param {Object} a action with changes.
|
|
1691
1498
|
* @returns {Object} changes.
|
|
1692
1499
|
*/
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
1500
|
function stateReducer(s, a) {
|
|
1696
1501
|
return a.changes;
|
|
1697
1502
|
}
|
|
1503
|
+
|
|
1698
1504
|
/**
|
|
1699
1505
|
* Returns a message to be added to aria-live region when item is selected.
|
|
1700
1506
|
*
|
|
1701
1507
|
* @param {Object} selectionParameters Parameters required to build the message.
|
|
1702
1508
|
* @returns {string} The a11y message.
|
|
1703
1509
|
*/
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
1510
|
function getA11ySelectionMessage(selectionParameters) {
|
|
1707
1511
|
const {
|
|
1708
1512
|
selectedItem,
|
|
@@ -1710,17 +1514,16 @@ function getA11ySelectionMessage(selectionParameters) {
|
|
|
1710
1514
|
} = selectionParameters;
|
|
1711
1515
|
return selectedItem ? `${itemToStringLocal(selectedItem)} has been selected.` : '';
|
|
1712
1516
|
}
|
|
1517
|
+
|
|
1713
1518
|
/**
|
|
1714
1519
|
* Debounced call for updating the a11y message.
|
|
1715
1520
|
*/
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
1521
|
const updateA11yStatus = debounce((getA11yMessage, document) => {
|
|
1719
1522
|
setStatus(getA11yMessage(), document);
|
|
1720
|
-
}, 200);
|
|
1523
|
+
}, 200);
|
|
1721
1524
|
|
|
1525
|
+
// istanbul ignore next
|
|
1722
1526
|
const useIsomorphicLayoutEffect = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined' ? react.useLayoutEffect : react.useEffect;
|
|
1723
|
-
|
|
1724
1527
|
function useElementIds(_ref) {
|
|
1725
1528
|
let {
|
|
1726
1529
|
id = `downshift-${generateId()}`,
|
|
@@ -1739,41 +1542,35 @@ function useElementIds(_ref) {
|
|
|
1739
1542
|
});
|
|
1740
1543
|
return elementIdsRef.current;
|
|
1741
1544
|
}
|
|
1742
|
-
|
|
1743
1545
|
function getItemIndex(index, item, items) {
|
|
1744
1546
|
if (index !== undefined) {
|
|
1745
1547
|
return index;
|
|
1746
1548
|
}
|
|
1747
|
-
|
|
1748
1549
|
if (items.length === 0) {
|
|
1749
1550
|
return -1;
|
|
1750
1551
|
}
|
|
1751
|
-
|
|
1752
1552
|
return items.indexOf(item);
|
|
1753
1553
|
}
|
|
1754
|
-
|
|
1755
1554
|
function itemToString(item) {
|
|
1756
1555
|
return item ? String(item) : '';
|
|
1757
1556
|
}
|
|
1758
|
-
|
|
1759
1557
|
function isAcceptedCharacterKey(key) {
|
|
1760
1558
|
return /^\S{1}$/.test(key);
|
|
1761
1559
|
}
|
|
1762
|
-
|
|
1763
1560
|
function capitalizeString(string) {
|
|
1764
1561
|
return `${string.slice(0, 1).toUpperCase()}${string.slice(1)}`;
|
|
1765
1562
|
}
|
|
1766
|
-
|
|
1767
1563
|
function useLatestRef(val) {
|
|
1768
|
-
const ref = react.useRef(val);
|
|
1564
|
+
const ref = react.useRef(val);
|
|
1565
|
+
// technically this is not "concurrent mode safe" because we're manipulating
|
|
1769
1566
|
// the value during render (so it's not idempotent). However, the places this
|
|
1770
1567
|
// hook is used is to support memoizing callbacks which will be called
|
|
1771
1568
|
// *during* render, so we need the latest values *during* render.
|
|
1772
1569
|
// If not for this, then we'd probably want to use useLayoutEffect instead.
|
|
1773
|
-
|
|
1774
1570
|
ref.current = val;
|
|
1775
1571
|
return ref;
|
|
1776
1572
|
}
|
|
1573
|
+
|
|
1777
1574
|
/**
|
|
1778
1575
|
* Computes the controlled state using a the previous state, props,
|
|
1779
1576
|
* two reducers, one from downshift and an optional one from the user.
|
|
@@ -1784,8 +1581,6 @@ function useLatestRef(val) {
|
|
|
1784
1581
|
* @param {Object} props The hook props.
|
|
1785
1582
|
* @returns {Array} An array with the state and an action dispatcher.
|
|
1786
1583
|
*/
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
1584
|
function useEnhancedReducer(reducer, initialState, props) {
|
|
1790
1585
|
const prevStateRef = react.useRef();
|
|
1791
1586
|
const actionRef = react.useRef();
|
|
@@ -1793,7 +1588,8 @@ function useEnhancedReducer(reducer, initialState, props) {
|
|
|
1793
1588
|
actionRef.current = action;
|
|
1794
1589
|
state = getState(state, action.props);
|
|
1795
1590
|
const changes = reducer(state, action);
|
|
1796
|
-
const newState = action.props.stateReducer(state, {
|
|
1591
|
+
const newState = action.props.stateReducer(state, {
|
|
1592
|
+
...action,
|
|
1797
1593
|
changes
|
|
1798
1594
|
});
|
|
1799
1595
|
return newState;
|
|
@@ -1809,11 +1605,11 @@ function useEnhancedReducer(reducer, initialState, props) {
|
|
|
1809
1605
|
if (action && prevStateRef.current && prevStateRef.current !== state) {
|
|
1810
1606
|
callOnChangeProps(action, getState(prevStateRef.current, action.props), state);
|
|
1811
1607
|
}
|
|
1812
|
-
|
|
1813
1608
|
prevStateRef.current = state;
|
|
1814
1609
|
}, [state, props, action]);
|
|
1815
1610
|
return [state, dispatchWithProps];
|
|
1816
1611
|
}
|
|
1612
|
+
|
|
1817
1613
|
/**
|
|
1818
1614
|
* Wraps the useEnhancedReducer and applies the controlled prop values before
|
|
1819
1615
|
* returning the new state.
|
|
@@ -1823,57 +1619,42 @@ function useEnhancedReducer(reducer, initialState, props) {
|
|
|
1823
1619
|
* @param {Object} props The hook props.
|
|
1824
1620
|
* @returns {Array} An array with the state and an action dispatcher.
|
|
1825
1621
|
*/
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
1622
|
function useControlledReducer$1(reducer, initialState, props) {
|
|
1829
1623
|
const [state, dispatch] = useEnhancedReducer(reducer, initialState, props);
|
|
1830
1624
|
return [getState(state, props), dispatch];
|
|
1831
1625
|
}
|
|
1832
|
-
|
|
1833
1626
|
const defaultProps$3 = {
|
|
1834
1627
|
itemToString,
|
|
1835
1628
|
stateReducer,
|
|
1836
1629
|
getA11ySelectionMessage,
|
|
1837
1630
|
scrollIntoView,
|
|
1838
|
-
environment:
|
|
1839
|
-
/* istanbul ignore next (ssr) */
|
|
1631
|
+
environment: /* istanbul ignore next (ssr) */
|
|
1840
1632
|
typeof window === 'undefined' ? {} : window
|
|
1841
1633
|
};
|
|
1842
|
-
|
|
1843
1634
|
function getDefaultValue$1(props, propKey, defaultStateValues) {
|
|
1844
1635
|
if (defaultStateValues === void 0) {
|
|
1845
1636
|
defaultStateValues = dropdownDefaultStateValues;
|
|
1846
1637
|
}
|
|
1847
|
-
|
|
1848
1638
|
const defaultValue = props[`default${capitalizeString(propKey)}`];
|
|
1849
|
-
|
|
1850
1639
|
if (defaultValue !== undefined) {
|
|
1851
1640
|
return defaultValue;
|
|
1852
1641
|
}
|
|
1853
|
-
|
|
1854
1642
|
return defaultStateValues[propKey];
|
|
1855
1643
|
}
|
|
1856
|
-
|
|
1857
1644
|
function getInitialValue$1(props, propKey, defaultStateValues) {
|
|
1858
1645
|
if (defaultStateValues === void 0) {
|
|
1859
1646
|
defaultStateValues = dropdownDefaultStateValues;
|
|
1860
1647
|
}
|
|
1861
|
-
|
|
1862
1648
|
const value = props[propKey];
|
|
1863
|
-
|
|
1864
1649
|
if (value !== undefined) {
|
|
1865
1650
|
return value;
|
|
1866
1651
|
}
|
|
1867
|
-
|
|
1868
1652
|
const initialValue = props[`initial${capitalizeString(propKey)}`];
|
|
1869
|
-
|
|
1870
1653
|
if (initialValue !== undefined) {
|
|
1871
1654
|
return initialValue;
|
|
1872
1655
|
}
|
|
1873
|
-
|
|
1874
1656
|
return getDefaultValue$1(props, propKey, defaultStateValues);
|
|
1875
1657
|
}
|
|
1876
|
-
|
|
1877
1658
|
function getInitialState$2(props) {
|
|
1878
1659
|
const selectedItem = getInitialValue$1(props, 'selectedItem');
|
|
1879
1660
|
const isOpen = getInitialValue$1(props, 'isOpen');
|
|
@@ -1886,7 +1667,6 @@ function getInitialState$2(props) {
|
|
|
1886
1667
|
inputValue
|
|
1887
1668
|
};
|
|
1888
1669
|
}
|
|
1889
|
-
|
|
1890
1670
|
function getHighlightedIndexOnOpen(props, state, offset) {
|
|
1891
1671
|
const {
|
|
1892
1672
|
items,
|
|
@@ -1897,30 +1677,26 @@ function getHighlightedIndexOnOpen(props, state, offset) {
|
|
|
1897
1677
|
selectedItem,
|
|
1898
1678
|
highlightedIndex
|
|
1899
1679
|
} = state;
|
|
1900
|
-
|
|
1901
1680
|
if (items.length === 0) {
|
|
1902
1681
|
return -1;
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1682
|
+
}
|
|
1905
1683
|
|
|
1684
|
+
// initialHighlightedIndex will give value to highlightedIndex on initial state only.
|
|
1906
1685
|
if (initialHighlightedIndex !== undefined && highlightedIndex === initialHighlightedIndex) {
|
|
1907
1686
|
return initialHighlightedIndex;
|
|
1908
1687
|
}
|
|
1909
|
-
|
|
1910
1688
|
if (defaultHighlightedIndex !== undefined) {
|
|
1911
1689
|
return defaultHighlightedIndex;
|
|
1912
1690
|
}
|
|
1913
|
-
|
|
1914
1691
|
if (selectedItem) {
|
|
1915
1692
|
return items.indexOf(selectedItem);
|
|
1916
1693
|
}
|
|
1917
|
-
|
|
1918
1694
|
if (offset === 0) {
|
|
1919
1695
|
return -1;
|
|
1920
1696
|
}
|
|
1921
|
-
|
|
1922
1697
|
return offset < 0 ? items.length - 1 : 0;
|
|
1923
1698
|
}
|
|
1699
|
+
|
|
1924
1700
|
/**
|
|
1925
1701
|
* Reuse the movement tracking of mouse and touch events.
|
|
1926
1702
|
*
|
|
@@ -1930,8 +1706,6 @@ function getHighlightedIndexOnOpen(props, state, offset) {
|
|
|
1930
1706
|
* @param {Function} handleBlur Handler on blur from mouse or touch.
|
|
1931
1707
|
* @returns {Object} Ref containing whether mouseDown or touchMove event is happening
|
|
1932
1708
|
*/
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
1709
|
function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, handleBlur) {
|
|
1936
1710
|
const mouseAndTouchTrackersRef = react.useRef({
|
|
1937
1711
|
isMouseDown: false,
|
|
@@ -1943,29 +1717,23 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
|
|
|
1943
1717
|
const onMouseDown = () => {
|
|
1944
1718
|
mouseAndTouchTrackersRef.current.isMouseDown = true;
|
|
1945
1719
|
};
|
|
1946
|
-
|
|
1947
1720
|
const onMouseUp = event => {
|
|
1948
1721
|
mouseAndTouchTrackersRef.current.isMouseDown = false;
|
|
1949
|
-
|
|
1950
1722
|
if (isOpen && !targetWithinDownshift(event.target, downshiftElementRefs.map(ref => ref.current), environment)) {
|
|
1951
1723
|
handleBlur();
|
|
1952
1724
|
}
|
|
1953
1725
|
};
|
|
1954
|
-
|
|
1955
1726
|
const onTouchStart = () => {
|
|
1956
1727
|
mouseAndTouchTrackersRef.current.isTouchMove = false;
|
|
1957
1728
|
};
|
|
1958
|
-
|
|
1959
1729
|
const onTouchMove = () => {
|
|
1960
1730
|
mouseAndTouchTrackersRef.current.isTouchMove = true;
|
|
1961
1731
|
};
|
|
1962
|
-
|
|
1963
1732
|
const onTouchEnd = event => {
|
|
1964
1733
|
if (isOpen && !mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, downshiftElementRefs.map(ref => ref.current), environment, false)) {
|
|
1965
1734
|
handleBlur();
|
|
1966
1735
|
}
|
|
1967
1736
|
};
|
|
1968
|
-
|
|
1969
1737
|
environment.addEventListener('mousedown', onMouseDown);
|
|
1970
1738
|
environment.addEventListener('mouseup', onMouseUp);
|
|
1971
1739
|
environment.addEventListener('touchstart', onTouchStart);
|
|
@@ -1977,14 +1745,14 @@ function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, hand
|
|
|
1977
1745
|
environment.removeEventListener('touchstart', onTouchStart);
|
|
1978
1746
|
environment.removeEventListener('touchmove', onTouchMove);
|
|
1979
1747
|
environment.removeEventListener('touchend', onTouchEnd);
|
|
1980
|
-
};
|
|
1748
|
+
};
|
|
1749
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1981
1750
|
}, [isOpen, environment]);
|
|
1982
1751
|
return mouseAndTouchTrackersRef;
|
|
1983
1752
|
}
|
|
1753
|
+
|
|
1984
1754
|
/* istanbul ignore next */
|
|
1985
1755
|
// eslint-disable-next-line import/no-mutable-exports
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
1756
|
let useGetterPropsCalledChecker = () => noop;
|
|
1989
1757
|
/**
|
|
1990
1758
|
* Custom hook that checks if getter props are called correctly.
|
|
@@ -1992,18 +1760,13 @@ let useGetterPropsCalledChecker = () => noop;
|
|
|
1992
1760
|
* @param {...any} propKeys Getter prop names to be handled.
|
|
1993
1761
|
* @returns {Function} Setter function called inside getter props to set call information.
|
|
1994
1762
|
*/
|
|
1995
|
-
|
|
1996
1763
|
/* istanbul ignore next */
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
1764
|
if (process.env.NODE_ENV !== 'production') {
|
|
2000
1765
|
useGetterPropsCalledChecker = function () {
|
|
2001
1766
|
const isInitialMountRef = react.useRef(true);
|
|
2002
|
-
|
|
2003
1767
|
for (var _len = arguments.length, propKeys = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
2004
1768
|
propKeys[_key] = arguments[_key];
|
|
2005
1769
|
}
|
|
2006
|
-
|
|
2007
1770
|
const getterPropsCalledRef = react.useRef(propKeys.reduce((acc, propKey) => {
|
|
2008
1771
|
acc[propKey] = {};
|
|
2009
1772
|
return acc;
|
|
@@ -2011,7 +1774,6 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
2011
1774
|
react.useEffect(() => {
|
|
2012
1775
|
Object.keys(getterPropsCalledRef.current).forEach(propKey => {
|
|
2013
1776
|
const propCallInfo = getterPropsCalledRef.current[propKey];
|
|
2014
|
-
|
|
2015
1777
|
if (isInitialMountRef.current) {
|
|
2016
1778
|
if (!Object.keys(propCallInfo).length) {
|
|
2017
1779
|
// eslint-disable-next-line no-console
|
|
@@ -2019,13 +1781,11 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
2019
1781
|
return;
|
|
2020
1782
|
}
|
|
2021
1783
|
}
|
|
2022
|
-
|
|
2023
1784
|
const {
|
|
2024
1785
|
suppressRefError,
|
|
2025
1786
|
refKey,
|
|
2026
1787
|
elementRef
|
|
2027
1788
|
} = propCallInfo;
|
|
2028
|
-
|
|
2029
1789
|
if ((!elementRef || !elementRef.current) && !suppressRefError) {
|
|
2030
1790
|
// eslint-disable-next-line no-console
|
|
2031
1791
|
console.error(`downshift: The ref prop "${refKey}" from ${propKey} was not applied correctly on your element.`);
|
|
@@ -2043,7 +1803,6 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
2043
1803
|
return setGetterPropCallInfo;
|
|
2044
1804
|
};
|
|
2045
1805
|
}
|
|
2046
|
-
|
|
2047
1806
|
function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref2) {
|
|
2048
1807
|
let {
|
|
2049
1808
|
isInitialMount,
|
|
@@ -2057,16 +1816,15 @@ function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref2) {
|
|
|
2057
1816
|
if (isInitialMount || true) {
|
|
2058
1817
|
return;
|
|
2059
1818
|
}
|
|
2060
|
-
|
|
2061
1819
|
updateA11yStatus(() => getA11yMessage({
|
|
2062
1820
|
highlightedIndex,
|
|
2063
1821
|
highlightedItem: items[highlightedIndex],
|
|
2064
1822
|
resultCount: items.length,
|
|
2065
1823
|
...rest
|
|
2066
|
-
}), environment.document);
|
|
1824
|
+
}), environment.document);
|
|
1825
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2067
1826
|
}, dependencyArray);
|
|
2068
1827
|
}
|
|
2069
|
-
|
|
2070
1828
|
function useScrollIntoView(_ref3) {
|
|
2071
1829
|
let {
|
|
2072
1830
|
highlightedIndex,
|
|
@@ -2077,27 +1835,25 @@ function useScrollIntoView(_ref3) {
|
|
|
2077
1835
|
scrollIntoView: scrollIntoViewProp
|
|
2078
1836
|
} = _ref3;
|
|
2079
1837
|
// used not to scroll on highlight by mouse.
|
|
2080
|
-
const shouldScrollRef = react.useRef(true);
|
|
2081
|
-
|
|
1838
|
+
const shouldScrollRef = react.useRef(true);
|
|
1839
|
+
// Scroll on highlighted item if change comes from keyboard.
|
|
2082
1840
|
useIsomorphicLayoutEffect(() => {
|
|
2083
1841
|
if (highlightedIndex < 0 || !isOpen || !Object.keys(itemRefs.current).length) {
|
|
2084
1842
|
return;
|
|
2085
1843
|
}
|
|
2086
|
-
|
|
2087
1844
|
if (shouldScrollRef.current === false) {
|
|
2088
1845
|
shouldScrollRef.current = true;
|
|
2089
1846
|
} else {
|
|
2090
1847
|
scrollIntoViewProp(getItemNodeFromIndex(highlightedIndex), menuElement);
|
|
2091
|
-
}
|
|
2092
|
-
|
|
1848
|
+
}
|
|
1849
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2093
1850
|
}, [highlightedIndex]);
|
|
2094
1851
|
return shouldScrollRef;
|
|
2095
|
-
}
|
|
2096
|
-
|
|
1852
|
+
}
|
|
2097
1853
|
|
|
1854
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
2098
1855
|
let useControlPropsValidator = noop;
|
|
2099
1856
|
/* istanbul ignore next */
|
|
2100
|
-
|
|
2101
1857
|
if (process.env.NODE_ENV !== 'production') {
|
|
2102
1858
|
useControlPropsValidator = _ref4 => {
|
|
2103
1859
|
let {
|
|
@@ -2111,7 +1867,6 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
2111
1867
|
if (isInitialMount) {
|
|
2112
1868
|
return;
|
|
2113
1869
|
}
|
|
2114
|
-
|
|
2115
1870
|
validateControlledUnchanged(state, prevPropsRef.current, props);
|
|
2116
1871
|
prevPropsRef.current = props;
|
|
2117
1872
|
}, [state, props, isInitialMount]);
|
|
@@ -2124,20 +1879,17 @@ function downshiftCommonReducer(state, action, stateChangeTypes) {
|
|
|
2124
1879
|
props
|
|
2125
1880
|
} = action;
|
|
2126
1881
|
let changes;
|
|
2127
|
-
|
|
2128
1882
|
switch (type) {
|
|
2129
1883
|
case stateChangeTypes.ItemMouseMove:
|
|
2130
1884
|
changes = {
|
|
2131
1885
|
highlightedIndex: action.disabled ? -1 : action.index
|
|
2132
1886
|
};
|
|
2133
1887
|
break;
|
|
2134
|
-
|
|
2135
1888
|
case stateChangeTypes.MenuMouseLeave:
|
|
2136
1889
|
changes = {
|
|
2137
1890
|
highlightedIndex: -1
|
|
2138
1891
|
};
|
|
2139
1892
|
break;
|
|
2140
|
-
|
|
2141
1893
|
case stateChangeTypes.ToggleButtonClick:
|
|
2142
1894
|
case stateChangeTypes.FunctionToggleMenu:
|
|
2143
1895
|
changes = {
|
|
@@ -2145,32 +1897,27 @@ function downshiftCommonReducer(state, action, stateChangeTypes) {
|
|
|
2145
1897
|
highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
|
|
2146
1898
|
};
|
|
2147
1899
|
break;
|
|
2148
|
-
|
|
2149
1900
|
case stateChangeTypes.FunctionOpenMenu:
|
|
2150
1901
|
changes = {
|
|
2151
1902
|
isOpen: true,
|
|
2152
1903
|
highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
|
|
2153
1904
|
};
|
|
2154
1905
|
break;
|
|
2155
|
-
|
|
2156
1906
|
case stateChangeTypes.FunctionCloseMenu:
|
|
2157
1907
|
changes = {
|
|
2158
1908
|
isOpen: false
|
|
2159
1909
|
};
|
|
2160
1910
|
break;
|
|
2161
|
-
|
|
2162
1911
|
case stateChangeTypes.FunctionSetHighlightedIndex:
|
|
2163
1912
|
changes = {
|
|
2164
1913
|
highlightedIndex: action.highlightedIndex
|
|
2165
1914
|
};
|
|
2166
1915
|
break;
|
|
2167
|
-
|
|
2168
1916
|
case stateChangeTypes.FunctionSetInputValue:
|
|
2169
1917
|
changes = {
|
|
2170
1918
|
inputValue: action.inputValue
|
|
2171
1919
|
};
|
|
2172
1920
|
break;
|
|
2173
|
-
|
|
2174
1921
|
case stateChangeTypes.FunctionReset:
|
|
2175
1922
|
changes = {
|
|
2176
1923
|
highlightedIndex: getDefaultValue$1(props, 'highlightedIndex'),
|
|
@@ -2179,12 +1926,11 @@ function downshiftCommonReducer(state, action, stateChangeTypes) {
|
|
|
2179
1926
|
inputValue: getDefaultValue$1(props, 'inputValue')
|
|
2180
1927
|
};
|
|
2181
1928
|
break;
|
|
2182
|
-
|
|
2183
1929
|
default:
|
|
2184
1930
|
throw new Error('Reducer called without proper action type.');
|
|
2185
1931
|
}
|
|
2186
|
-
|
|
2187
|
-
|
|
1932
|
+
return {
|
|
1933
|
+
...state,
|
|
2188
1934
|
...changes
|
|
2189
1935
|
};
|
|
2190
1936
|
}
|
|
@@ -2323,7 +2069,6 @@ var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
|
|
|
2323
2069
|
});
|
|
2324
2070
|
|
|
2325
2071
|
/* eslint-disable complexity */
|
|
2326
|
-
|
|
2327
2072
|
function downshiftSelectReducer(state, action) {
|
|
2328
2073
|
const {
|
|
2329
2074
|
type,
|
|
@@ -2331,7 +2076,6 @@ function downshiftSelectReducer(state, action) {
|
|
|
2331
2076
|
altKey
|
|
2332
2077
|
} = action;
|
|
2333
2078
|
let changes;
|
|
2334
|
-
|
|
2335
2079
|
switch (type) {
|
|
2336
2080
|
case ItemClick$1:
|
|
2337
2081
|
changes = {
|
|
@@ -2340,7 +2084,6 @@ function downshiftSelectReducer(state, action) {
|
|
|
2340
2084
|
selectedItem: props.items[action.index]
|
|
2341
2085
|
};
|
|
2342
2086
|
break;
|
|
2343
|
-
|
|
2344
2087
|
case ToggleButtonKeyDownCharacter:
|
|
2345
2088
|
{
|
|
2346
2089
|
const lowercasedKey = action.key;
|
|
@@ -2360,7 +2103,6 @@ function downshiftSelectReducer(state, action) {
|
|
|
2360
2103
|
};
|
|
2361
2104
|
}
|
|
2362
2105
|
break;
|
|
2363
|
-
|
|
2364
2106
|
case ToggleButtonKeyDownArrowDown:
|
|
2365
2107
|
{
|
|
2366
2108
|
const highlightedIndex = state.isOpen ? getNextWrappingIndex(1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false) : altKey && state.selectedItem == null ? -1 : getHighlightedIndexOnOpen(props, state, 1);
|
|
@@ -2370,7 +2112,6 @@ function downshiftSelectReducer(state, action) {
|
|
|
2370
2112
|
};
|
|
2371
2113
|
}
|
|
2372
2114
|
break;
|
|
2373
|
-
|
|
2374
2115
|
case ToggleButtonKeyDownArrowUp:
|
|
2375
2116
|
if (state.isOpen && altKey) {
|
|
2376
2117
|
changes = {
|
|
@@ -2387,10 +2128,8 @@ function downshiftSelectReducer(state, action) {
|
|
|
2387
2128
|
isOpen: true
|
|
2388
2129
|
};
|
|
2389
2130
|
}
|
|
2390
|
-
|
|
2391
2131
|
break;
|
|
2392
2132
|
// only triggered when menu is open.
|
|
2393
|
-
|
|
2394
2133
|
case ToggleButtonKeyDownEnter:
|
|
2395
2134
|
case ToggleButtonKeyDownSpaceButton:
|
|
2396
2135
|
changes = {
|
|
@@ -2401,40 +2140,34 @@ function downshiftSelectReducer(state, action) {
|
|
|
2401
2140
|
})
|
|
2402
2141
|
};
|
|
2403
2142
|
break;
|
|
2404
|
-
|
|
2405
2143
|
case ToggleButtonKeyDownHome:
|
|
2406
2144
|
changes = {
|
|
2407
2145
|
highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false),
|
|
2408
2146
|
isOpen: true
|
|
2409
2147
|
};
|
|
2410
2148
|
break;
|
|
2411
|
-
|
|
2412
2149
|
case ToggleButtonKeyDownEnd:
|
|
2413
2150
|
changes = {
|
|
2414
2151
|
highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false),
|
|
2415
2152
|
isOpen: true
|
|
2416
2153
|
};
|
|
2417
2154
|
break;
|
|
2418
|
-
|
|
2419
2155
|
case ToggleButtonKeyDownPageUp:
|
|
2420
2156
|
changes = {
|
|
2421
2157
|
highlightedIndex: getNextWrappingIndex(-10, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false)
|
|
2422
2158
|
};
|
|
2423
2159
|
break;
|
|
2424
|
-
|
|
2425
2160
|
case ToggleButtonKeyDownPageDown:
|
|
2426
2161
|
changes = {
|
|
2427
2162
|
highlightedIndex: getNextWrappingIndex(10, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false)
|
|
2428
2163
|
};
|
|
2429
2164
|
break;
|
|
2430
|
-
|
|
2431
2165
|
case ToggleButtonKeyDownEscape:
|
|
2432
2166
|
changes = {
|
|
2433
2167
|
isOpen: false,
|
|
2434
2168
|
highlightedIndex: -1
|
|
2435
2169
|
};
|
|
2436
2170
|
break;
|
|
2437
|
-
|
|
2438
2171
|
case ToggleButtonBlur:
|
|
2439
2172
|
changes = {
|
|
2440
2173
|
isOpen: false,
|
|
@@ -2444,33 +2177,30 @@ function downshiftSelectReducer(state, action) {
|
|
|
2444
2177
|
})
|
|
2445
2178
|
};
|
|
2446
2179
|
break;
|
|
2447
|
-
|
|
2448
2180
|
case FunctionSelectItem$1:
|
|
2449
2181
|
changes = {
|
|
2450
2182
|
selectedItem: action.selectedItem
|
|
2451
2183
|
};
|
|
2452
2184
|
break;
|
|
2453
|
-
|
|
2454
2185
|
default:
|
|
2455
2186
|
return downshiftCommonReducer(state, action, stateChangeTypes$2);
|
|
2456
2187
|
}
|
|
2457
|
-
|
|
2458
|
-
|
|
2188
|
+
return {
|
|
2189
|
+
...state,
|
|
2459
2190
|
...changes
|
|
2460
2191
|
};
|
|
2461
2192
|
}
|
|
2462
2193
|
/* eslint-enable complexity */
|
|
2463
2194
|
|
|
2464
2195
|
useSelect.stateChangeTypes = stateChangeTypes$2;
|
|
2465
|
-
|
|
2466
2196
|
function useSelect(userProps) {
|
|
2467
2197
|
if (userProps === void 0) {
|
|
2468
2198
|
userProps = {};
|
|
2469
2199
|
}
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2200
|
+
validatePropTypes$2(userProps, useSelect);
|
|
2201
|
+
// Props defaults and destructuring.
|
|
2202
|
+
const props = {
|
|
2203
|
+
...defaultProps$2,
|
|
2474
2204
|
...userProps
|
|
2475
2205
|
};
|
|
2476
2206
|
const {
|
|
@@ -2480,8 +2210,8 @@ function useSelect(userProps) {
|
|
|
2480
2210
|
itemToString,
|
|
2481
2211
|
getA11ySelectionMessage,
|
|
2482
2212
|
getA11yStatusMessage
|
|
2483
|
-
} = props;
|
|
2484
|
-
|
|
2213
|
+
} = props;
|
|
2214
|
+
// Initial state depending on controlled props.
|
|
2485
2215
|
const initialState = getInitialState$2(props);
|
|
2486
2216
|
const [state, dispatch] = useControlledReducer$1(downshiftSelectReducer, initialState, props);
|
|
2487
2217
|
const {
|
|
@@ -2489,27 +2219,30 @@ function useSelect(userProps) {
|
|
|
2489
2219
|
highlightedIndex,
|
|
2490
2220
|
selectedItem,
|
|
2491
2221
|
inputValue
|
|
2492
|
-
} = state;
|
|
2222
|
+
} = state;
|
|
2493
2223
|
|
|
2224
|
+
// Element efs.
|
|
2494
2225
|
const toggleButtonRef = react.useRef(null);
|
|
2495
2226
|
const menuRef = react.useRef(null);
|
|
2496
|
-
const itemRefs = react.useRef({});
|
|
2497
|
-
|
|
2498
|
-
const clearTimeoutRef = react.useRef(null);
|
|
2499
|
-
|
|
2500
|
-
const elementIds = useElementIds(props);
|
|
2501
|
-
|
|
2227
|
+
const itemRefs = react.useRef({});
|
|
2228
|
+
// used to keep the inputValue clearTimeout object between renders.
|
|
2229
|
+
const clearTimeoutRef = react.useRef(null);
|
|
2230
|
+
// prevent id re-generation between renders.
|
|
2231
|
+
const elementIds = useElementIds(props);
|
|
2232
|
+
// used to keep track of how many items we had on previous cycle.
|
|
2502
2233
|
const previousResultCountRef = react.useRef();
|
|
2503
|
-
const isInitialMountRef = react.useRef(true);
|
|
2504
|
-
|
|
2234
|
+
const isInitialMountRef = react.useRef(true);
|
|
2235
|
+
// utility callback to get item element.
|
|
2505
2236
|
const latest = useLatestRef({
|
|
2506
2237
|
state,
|
|
2507
2238
|
props
|
|
2508
|
-
});
|
|
2239
|
+
});
|
|
2509
2240
|
|
|
2510
|
-
|
|
2511
|
-
|
|
2241
|
+
// Some utils.
|
|
2242
|
+
const getItemNodeFromIndex = react.useCallback(index => itemRefs.current[elementIds.getItemId(index)], [elementIds]);
|
|
2512
2243
|
|
|
2244
|
+
// Effects.
|
|
2245
|
+
// Sets a11y status message on changes in state.
|
|
2513
2246
|
useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], {
|
|
2514
2247
|
isInitialMount: isInitialMountRef.current,
|
|
2515
2248
|
previousResultCount: previousResultCountRef.current,
|
|
@@ -2517,8 +2250,8 @@ function useSelect(userProps) {
|
|
|
2517
2250
|
environment,
|
|
2518
2251
|
itemToString,
|
|
2519
2252
|
...state
|
|
2520
|
-
});
|
|
2521
|
-
|
|
2253
|
+
});
|
|
2254
|
+
// Sets a11y status message on changes in selectedItem.
|
|
2522
2255
|
useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], {
|
|
2523
2256
|
isInitialMount: isInitialMountRef.current,
|
|
2524
2257
|
previousResultCount: previousResultCountRef.current,
|
|
@@ -2526,8 +2259,8 @@ function useSelect(userProps) {
|
|
|
2526
2259
|
environment,
|
|
2527
2260
|
itemToString,
|
|
2528
2261
|
...state
|
|
2529
|
-
});
|
|
2530
|
-
|
|
2262
|
+
});
|
|
2263
|
+
// Scroll on highlighted item if change comes from keyboard.
|
|
2531
2264
|
const shouldScrollRef = useScrollIntoView({
|
|
2532
2265
|
menuElement: menuRef.current,
|
|
2533
2266
|
highlightedIndex,
|
|
@@ -2535,8 +2268,9 @@ function useSelect(userProps) {
|
|
|
2535
2268
|
itemRefs,
|
|
2536
2269
|
scrollIntoView,
|
|
2537
2270
|
getItemNodeFromIndex
|
|
2538
|
-
});
|
|
2271
|
+
});
|
|
2539
2272
|
|
|
2273
|
+
// Sets cleanup for the keysSoFar callback, debounded after 500ms.
|
|
2540
2274
|
react.useEffect(() => {
|
|
2541
2275
|
// init the clean function here as we need access to dispatch.
|
|
2542
2276
|
clearTimeoutRef.current = debounce(outerDispatch => {
|
|
@@ -2544,18 +2278,19 @@ function useSelect(userProps) {
|
|
|
2544
2278
|
type: FunctionSetInputValue$1,
|
|
2545
2279
|
inputValue: ''
|
|
2546
2280
|
});
|
|
2547
|
-
}, 500);
|
|
2281
|
+
}, 500);
|
|
2548
2282
|
|
|
2283
|
+
// Cancel any pending debounced calls on mount
|
|
2549
2284
|
return () => {
|
|
2550
2285
|
clearTimeoutRef.current.cancel();
|
|
2551
2286
|
};
|
|
2552
|
-
}, []);
|
|
2287
|
+
}, []);
|
|
2553
2288
|
|
|
2289
|
+
// Invokes the keysSoFar callback set up above.
|
|
2554
2290
|
react.useEffect(() => {
|
|
2555
2291
|
if (!inputValue) {
|
|
2556
2292
|
return;
|
|
2557
2293
|
}
|
|
2558
|
-
|
|
2559
2294
|
clearTimeoutRef.current(dispatch);
|
|
2560
2295
|
}, [dispatch, inputValue]);
|
|
2561
2296
|
useControlPropsValidator({
|
|
@@ -2567,27 +2302,27 @@ function useSelect(userProps) {
|
|
|
2567
2302
|
if (isInitialMountRef.current) {
|
|
2568
2303
|
return;
|
|
2569
2304
|
}
|
|
2570
|
-
|
|
2571
2305
|
previousResultCountRef.current = items.length;
|
|
2572
|
-
});
|
|
2573
|
-
|
|
2306
|
+
});
|
|
2307
|
+
// Add mouse/touch events to document.
|
|
2574
2308
|
const mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [menuRef, toggleButtonRef], environment, () => {
|
|
2575
2309
|
dispatch({
|
|
2576
2310
|
type: ToggleButtonBlur
|
|
2577
2311
|
});
|
|
2578
2312
|
});
|
|
2579
|
-
const setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
|
|
2580
|
-
|
|
2313
|
+
const setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
|
|
2314
|
+
// Make initial ref false.
|
|
2581
2315
|
react.useEffect(() => {
|
|
2582
2316
|
isInitialMountRef.current = false;
|
|
2583
|
-
}, []);
|
|
2584
|
-
|
|
2317
|
+
}, []);
|
|
2318
|
+
// Reset itemRefs on close.
|
|
2585
2319
|
react.useEffect(() => {
|
|
2586
2320
|
if (!isOpen) {
|
|
2587
2321
|
itemRefs.current = {};
|
|
2588
2322
|
}
|
|
2589
|
-
}, [isOpen]);
|
|
2323
|
+
}, [isOpen]);
|
|
2590
2324
|
|
|
2325
|
+
// Event handler functions.
|
|
2591
2326
|
const toggleButtonKeyDownHandlers = react.useMemo(() => ({
|
|
2592
2327
|
ArrowDown(event) {
|
|
2593
2328
|
event.preventDefault();
|
|
@@ -2597,7 +2332,6 @@ function useSelect(userProps) {
|
|
|
2597
2332
|
altKey: event.altKey
|
|
2598
2333
|
});
|
|
2599
2334
|
},
|
|
2600
|
-
|
|
2601
2335
|
ArrowUp(event) {
|
|
2602
2336
|
event.preventDefault();
|
|
2603
2337
|
dispatch({
|
|
@@ -2606,7 +2340,6 @@ function useSelect(userProps) {
|
|
|
2606
2340
|
altKey: event.altKey
|
|
2607
2341
|
});
|
|
2608
2342
|
},
|
|
2609
|
-
|
|
2610
2343
|
Home(event) {
|
|
2611
2344
|
event.preventDefault();
|
|
2612
2345
|
dispatch({
|
|
@@ -2614,7 +2347,6 @@ function useSelect(userProps) {
|
|
|
2614
2347
|
getItemNodeFromIndex
|
|
2615
2348
|
});
|
|
2616
2349
|
},
|
|
2617
|
-
|
|
2618
2350
|
End(event) {
|
|
2619
2351
|
event.preventDefault();
|
|
2620
2352
|
dispatch({
|
|
@@ -2622,7 +2354,6 @@ function useSelect(userProps) {
|
|
|
2622
2354
|
getItemNodeFromIndex
|
|
2623
2355
|
});
|
|
2624
2356
|
},
|
|
2625
|
-
|
|
2626
2357
|
Escape() {
|
|
2627
2358
|
if (latest.current.state.isOpen) {
|
|
2628
2359
|
dispatch({
|
|
@@ -2630,16 +2361,12 @@ function useSelect(userProps) {
|
|
|
2630
2361
|
});
|
|
2631
2362
|
}
|
|
2632
2363
|
},
|
|
2633
|
-
|
|
2634
2364
|
Enter(event) {
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
});
|
|
2640
|
-
}
|
|
2365
|
+
event.preventDefault();
|
|
2366
|
+
dispatch({
|
|
2367
|
+
type: latest.current.state.isOpen ? ToggleButtonKeyDownEnter : ToggleButtonClick$1
|
|
2368
|
+
});
|
|
2641
2369
|
},
|
|
2642
|
-
|
|
2643
2370
|
PageUp(event) {
|
|
2644
2371
|
if (latest.current.state.isOpen) {
|
|
2645
2372
|
event.preventDefault();
|
|
@@ -2649,7 +2376,6 @@ function useSelect(userProps) {
|
|
|
2649
2376
|
});
|
|
2650
2377
|
}
|
|
2651
2378
|
},
|
|
2652
|
-
|
|
2653
2379
|
PageDown(event) {
|
|
2654
2380
|
if (latest.current.state.isOpen) {
|
|
2655
2381
|
event.preventDefault();
|
|
@@ -2659,18 +2385,15 @@ function useSelect(userProps) {
|
|
|
2659
2385
|
});
|
|
2660
2386
|
}
|
|
2661
2387
|
},
|
|
2662
|
-
|
|
2663
2388
|
' '(event) {
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
});
|
|
2669
|
-
}
|
|
2389
|
+
event.preventDefault();
|
|
2390
|
+
dispatch({
|
|
2391
|
+
type: latest.current.state.isOpen ? ToggleButtonKeyDownSpaceButton : ToggleButtonClick$1
|
|
2392
|
+
});
|
|
2670
2393
|
}
|
|
2394
|
+
}), [dispatch, getItemNodeFromIndex, latest]);
|
|
2671
2395
|
|
|
2672
|
-
|
|
2673
|
-
|
|
2396
|
+
// Action functions.
|
|
2674
2397
|
const toggleMenu = react.useCallback(() => {
|
|
2675
2398
|
dispatch({
|
|
2676
2399
|
type: FunctionToggleMenu$1
|
|
@@ -2708,8 +2431,8 @@ function useSelect(userProps) {
|
|
|
2708
2431
|
type: FunctionSetInputValue$1,
|
|
2709
2432
|
inputValue: newInputValue
|
|
2710
2433
|
});
|
|
2711
|
-
}, [dispatch]);
|
|
2712
|
-
|
|
2434
|
+
}, [dispatch]);
|
|
2435
|
+
// Getter functions.
|
|
2713
2436
|
const getLabelProps = react.useCallback(labelProps => ({
|
|
2714
2437
|
id: elementIds.labelId,
|
|
2715
2438
|
htmlFor: elementIds.toggleButtonId,
|
|
@@ -2727,13 +2450,11 @@ function useSelect(userProps) {
|
|
|
2727
2450
|
let {
|
|
2728
2451
|
suppressRefError = false
|
|
2729
2452
|
} = _temp2 === void 0 ? {} : _temp2;
|
|
2730
|
-
|
|
2731
2453
|
const menuHandleMouseLeave = () => {
|
|
2732
2454
|
dispatch({
|
|
2733
2455
|
type: MenuMouseLeave$1
|
|
2734
2456
|
});
|
|
2735
2457
|
};
|
|
2736
|
-
|
|
2737
2458
|
setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
|
|
2738
2459
|
return {
|
|
2739
2460
|
[refKey]: handleRefs(ref, menuNode => {
|
|
@@ -2760,13 +2481,11 @@ function useSelect(userProps) {
|
|
|
2760
2481
|
suppressRefError = false
|
|
2761
2482
|
} = _temp4 === void 0 ? {} : _temp4;
|
|
2762
2483
|
const latestState = latest.current.state;
|
|
2763
|
-
|
|
2764
2484
|
const toggleButtonHandleClick = () => {
|
|
2765
2485
|
dispatch({
|
|
2766
2486
|
type: ToggleButtonClick$1
|
|
2767
2487
|
});
|
|
2768
2488
|
};
|
|
2769
|
-
|
|
2770
2489
|
const toggleButtonHandleBlur = () => {
|
|
2771
2490
|
if (latestState.isOpen && !mouseAndTouchTrackersRef.current.isMouseDown) {
|
|
2772
2491
|
dispatch({
|
|
@@ -2774,10 +2493,8 @@ function useSelect(userProps) {
|
|
|
2774
2493
|
});
|
|
2775
2494
|
}
|
|
2776
2495
|
};
|
|
2777
|
-
|
|
2778
2496
|
const toggleButtonHandleKeyDown = event => {
|
|
2779
2497
|
const key = normalizeArrowKey(event);
|
|
2780
|
-
|
|
2781
2498
|
if (key && toggleButtonKeyDownHandlers[key]) {
|
|
2782
2499
|
toggleButtonKeyDownHandlers[key](event);
|
|
2783
2500
|
} else if (isAcceptedCharacterKey(key)) {
|
|
@@ -2788,7 +2505,6 @@ function useSelect(userProps) {
|
|
|
2788
2505
|
});
|
|
2789
2506
|
}
|
|
2790
2507
|
};
|
|
2791
|
-
|
|
2792
2508
|
const toggleProps = {
|
|
2793
2509
|
[refKey]: handleRefs(ref, toggleButtonNode => {
|
|
2794
2510
|
toggleButtonRef.current = toggleButtonNode;
|
|
@@ -2804,12 +2520,10 @@ function useSelect(userProps) {
|
|
|
2804
2520
|
onBlur: callAllEventHandlers(onBlur, toggleButtonHandleBlur),
|
|
2805
2521
|
...rest
|
|
2806
2522
|
};
|
|
2807
|
-
|
|
2808
2523
|
if (!rest.disabled) {
|
|
2809
2524
|
toggleProps.onClick = callAllEventHandlers(onClick, toggleButtonHandleClick);
|
|
2810
2525
|
toggleProps.onKeyDown = callAllEventHandlers(onKeyDown, toggleButtonHandleKeyDown);
|
|
2811
2526
|
}
|
|
2812
|
-
|
|
2813
2527
|
setGetterPropCallInfo('getToggleButtonProps', suppressRefError, refKey, toggleButtonRef);
|
|
2814
2528
|
return toggleProps;
|
|
2815
2529
|
}, [latest, elementIds, setGetterPropCallInfo, dispatch, mouseAndTouchTrackersRef, toggleButtonKeyDownHandlers, getItemNodeFromIndex]);
|
|
@@ -2830,12 +2544,10 @@ function useSelect(userProps) {
|
|
|
2830
2544
|
} = latest.current;
|
|
2831
2545
|
const item = itemProp ?? items[indexProp];
|
|
2832
2546
|
const index = getItemIndex(indexProp, item, latestProps.items);
|
|
2833
|
-
|
|
2834
2547
|
const itemHandleMouseMove = () => {
|
|
2835
2548
|
if (index === latestState.highlightedIndex) {
|
|
2836
2549
|
return;
|
|
2837
2550
|
}
|
|
2838
|
-
|
|
2839
2551
|
shouldScrollRef.current = false;
|
|
2840
2552
|
dispatch({
|
|
2841
2553
|
type: ItemMouseMove$1,
|
|
@@ -2843,20 +2555,16 @@ function useSelect(userProps) {
|
|
|
2843
2555
|
disabled
|
|
2844
2556
|
});
|
|
2845
2557
|
};
|
|
2846
|
-
|
|
2847
2558
|
const itemHandleClick = () => {
|
|
2848
2559
|
dispatch({
|
|
2849
2560
|
type: ItemClick$1,
|
|
2850
2561
|
index
|
|
2851
2562
|
});
|
|
2852
2563
|
};
|
|
2853
|
-
|
|
2854
2564
|
const itemIndex = getItemIndex(index, item, latestProps.items);
|
|
2855
|
-
|
|
2856
2565
|
if (itemIndex < 0) {
|
|
2857
2566
|
throw new Error('Pass either item or item index in getItemProps!');
|
|
2858
2567
|
}
|
|
2859
|
-
|
|
2860
2568
|
const itemProps = {
|
|
2861
2569
|
disabled,
|
|
2862
2570
|
role: 'option',
|
|
@@ -2869,11 +2577,9 @@ function useSelect(userProps) {
|
|
|
2869
2577
|
}),
|
|
2870
2578
|
...rest
|
|
2871
2579
|
};
|
|
2872
|
-
|
|
2873
2580
|
if (!disabled) {
|
|
2874
2581
|
itemProps.onClick = callAllEventHandlers(onClick, itemHandleClick);
|
|
2875
2582
|
}
|
|
2876
|
-
|
|
2877
2583
|
itemProps.onMouseMove = callAllEventHandlers(onMouseMove, itemHandleMouseMove);
|
|
2878
2584
|
return itemProps;
|
|
2879
2585
|
}, [latest, items, selectedItem, elementIds, shouldScrollRef, dispatch]);
|
|
@@ -2958,16 +2664,14 @@ function getInitialState$1(props) {
|
|
|
2958
2664
|
let {
|
|
2959
2665
|
inputValue
|
|
2960
2666
|
} = initialState;
|
|
2961
|
-
|
|
2962
2667
|
if (inputValue === '' && selectedItem && props.defaultInputValue === undefined && props.initialInputValue === undefined && props.inputValue === undefined) {
|
|
2963
2668
|
inputValue = props.itemToString(selectedItem);
|
|
2964
2669
|
}
|
|
2965
|
-
|
|
2966
|
-
|
|
2670
|
+
return {
|
|
2671
|
+
...initialState,
|
|
2967
2672
|
inputValue
|
|
2968
2673
|
};
|
|
2969
2674
|
}
|
|
2970
|
-
|
|
2971
2675
|
const propTypes$1 = {
|
|
2972
2676
|
items: PropTypes__default["default"].array.isRequired,
|
|
2973
2677
|
itemToString: PropTypes__default["default"].func,
|
|
@@ -3007,6 +2711,7 @@ const propTypes$1 = {
|
|
|
3007
2711
|
})
|
|
3008
2712
|
})
|
|
3009
2713
|
};
|
|
2714
|
+
|
|
3010
2715
|
/**
|
|
3011
2716
|
* The useCombobox version of useControlledReducer, which also
|
|
3012
2717
|
* checks if the controlled prop selectedItem changed between
|
|
@@ -3019,11 +2724,11 @@ const propTypes$1 = {
|
|
|
3019
2724
|
* @param {Object} props The hook props.
|
|
3020
2725
|
* @returns {Array} An array with the state and an action dispatcher.
|
|
3021
2726
|
*/
|
|
3022
|
-
|
|
3023
2727
|
function useControlledReducer(reducer, initialState, props) {
|
|
3024
2728
|
const previousSelectedItemRef = react.useRef();
|
|
3025
|
-
const [state, dispatch] = useEnhancedReducer(reducer, initialState, props);
|
|
2729
|
+
const [state, dispatch] = useEnhancedReducer(reducer, initialState, props);
|
|
3026
2730
|
|
|
2731
|
+
// ToDo: if needed, make same approach as selectedItemChanged from Downshift.
|
|
3027
2732
|
react.useEffect(() => {
|
|
3028
2733
|
if (isControlledProp(props, 'selectedItem')) {
|
|
3029
2734
|
if (previousSelectedItemRef.current !== props.selectedItem) {
|
|
@@ -3032,29 +2737,26 @@ function useControlledReducer(reducer, initialState, props) {
|
|
|
3032
2737
|
inputValue: props.itemToString(props.selectedItem)
|
|
3033
2738
|
});
|
|
3034
2739
|
}
|
|
3035
|
-
|
|
3036
2740
|
previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
|
|
3037
2741
|
}
|
|
3038
2742
|
});
|
|
3039
2743
|
return [getState(state, props), dispatch];
|
|
3040
|
-
}
|
|
3041
|
-
|
|
2744
|
+
}
|
|
3042
2745
|
|
|
2746
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
3043
2747
|
let validatePropTypes$1 = noop;
|
|
3044
2748
|
/* istanbul ignore next */
|
|
3045
|
-
|
|
3046
2749
|
if (process.env.NODE_ENV !== 'production') {
|
|
3047
2750
|
validatePropTypes$1 = (options, caller) => {
|
|
3048
2751
|
PropTypes__default["default"].checkPropTypes(propTypes$1, options, 'prop', caller.name);
|
|
3049
2752
|
};
|
|
3050
2753
|
}
|
|
3051
|
-
|
|
3052
|
-
|
|
2754
|
+
const defaultProps$1 = {
|
|
2755
|
+
...defaultProps$3,
|
|
3053
2756
|
getA11yStatusMessage: getA11yStatusMessage$1
|
|
3054
2757
|
};
|
|
3055
2758
|
|
|
3056
2759
|
/* eslint-disable complexity */
|
|
3057
|
-
|
|
3058
2760
|
function downshiftUseComboboxReducer(state, action) {
|
|
3059
2761
|
const {
|
|
3060
2762
|
type,
|
|
@@ -3062,7 +2764,6 @@ function downshiftUseComboboxReducer(state, action) {
|
|
|
3062
2764
|
altKey
|
|
3063
2765
|
} = action;
|
|
3064
2766
|
let changes;
|
|
3065
|
-
|
|
3066
2767
|
switch (type) {
|
|
3067
2768
|
case ItemClick:
|
|
3068
2769
|
changes = {
|
|
@@ -3072,7 +2773,6 @@ function downshiftUseComboboxReducer(state, action) {
|
|
|
3072
2773
|
inputValue: props.itemToString(props.items[action.index])
|
|
3073
2774
|
};
|
|
3074
2775
|
break;
|
|
3075
|
-
|
|
3076
2776
|
case InputKeyDownArrowDown:
|
|
3077
2777
|
if (state.isOpen) {
|
|
3078
2778
|
changes = {
|
|
@@ -3084,9 +2784,7 @@ function downshiftUseComboboxReducer(state, action) {
|
|
|
3084
2784
|
isOpen: props.items.length >= 0
|
|
3085
2785
|
};
|
|
3086
2786
|
}
|
|
3087
|
-
|
|
3088
2787
|
break;
|
|
3089
|
-
|
|
3090
2788
|
case InputKeyDownArrowUp:
|
|
3091
2789
|
if (state.isOpen) {
|
|
3092
2790
|
if (altKey) {
|
|
@@ -3109,9 +2807,7 @@ function downshiftUseComboboxReducer(state, action) {
|
|
|
3109
2807
|
isOpen: props.items.length >= 0
|
|
3110
2808
|
};
|
|
3111
2809
|
}
|
|
3112
|
-
|
|
3113
2810
|
break;
|
|
3114
|
-
|
|
3115
2811
|
case InputKeyDownEnter:
|
|
3116
2812
|
changes = {
|
|
3117
2813
|
isOpen: getDefaultValue$1(props, 'isOpen'),
|
|
@@ -3122,7 +2818,6 @@ function downshiftUseComboboxReducer(state, action) {
|
|
|
3122
2818
|
})
|
|
3123
2819
|
};
|
|
3124
2820
|
break;
|
|
3125
|
-
|
|
3126
2821
|
case InputKeyDownEscape:
|
|
3127
2822
|
changes = {
|
|
3128
2823
|
isOpen: false,
|
|
@@ -3133,31 +2828,26 @@ function downshiftUseComboboxReducer(state, action) {
|
|
|
3133
2828
|
})
|
|
3134
2829
|
};
|
|
3135
2830
|
break;
|
|
3136
|
-
|
|
3137
2831
|
case InputKeyDownPageUp:
|
|
3138
2832
|
changes = {
|
|
3139
2833
|
highlightedIndex: getNextWrappingIndex(-10, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false)
|
|
3140
2834
|
};
|
|
3141
2835
|
break;
|
|
3142
|
-
|
|
3143
2836
|
case InputKeyDownPageDown:
|
|
3144
2837
|
changes = {
|
|
3145
2838
|
highlightedIndex: getNextWrappingIndex(10, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false)
|
|
3146
2839
|
};
|
|
3147
2840
|
break;
|
|
3148
|
-
|
|
3149
2841
|
case InputKeyDownHome:
|
|
3150
2842
|
changes = {
|
|
3151
2843
|
highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false)
|
|
3152
2844
|
};
|
|
3153
2845
|
break;
|
|
3154
|
-
|
|
3155
2846
|
case InputKeyDownEnd:
|
|
3156
2847
|
changes = {
|
|
3157
2848
|
highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false)
|
|
3158
2849
|
};
|
|
3159
2850
|
break;
|
|
3160
|
-
|
|
3161
2851
|
case InputBlur:
|
|
3162
2852
|
changes = {
|
|
3163
2853
|
isOpen: false,
|
|
@@ -3168,7 +2858,6 @@ function downshiftUseComboboxReducer(state, action) {
|
|
|
3168
2858
|
})
|
|
3169
2859
|
};
|
|
3170
2860
|
break;
|
|
3171
|
-
|
|
3172
2861
|
case InputChange:
|
|
3173
2862
|
changes = {
|
|
3174
2863
|
isOpen: true,
|
|
@@ -3176,32 +2865,28 @@ function downshiftUseComboboxReducer(state, action) {
|
|
|
3176
2865
|
inputValue: action.inputValue
|
|
3177
2866
|
};
|
|
3178
2867
|
break;
|
|
3179
|
-
|
|
3180
2868
|
case InputFocus:
|
|
3181
2869
|
changes = {
|
|
3182
2870
|
isOpen: true,
|
|
3183
2871
|
highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
|
|
3184
2872
|
};
|
|
3185
2873
|
break;
|
|
3186
|
-
|
|
3187
2874
|
case FunctionSelectItem:
|
|
3188
2875
|
changes = {
|
|
3189
2876
|
selectedItem: action.selectedItem,
|
|
3190
2877
|
inputValue: props.itemToString(action.selectedItem)
|
|
3191
2878
|
};
|
|
3192
2879
|
break;
|
|
3193
|
-
|
|
3194
2880
|
case ControlledPropUpdatedSelectedItem:
|
|
3195
2881
|
changes = {
|
|
3196
2882
|
inputValue: action.inputValue
|
|
3197
2883
|
};
|
|
3198
2884
|
break;
|
|
3199
|
-
|
|
3200
2885
|
default:
|
|
3201
2886
|
return downshiftCommonReducer(state, action, stateChangeTypes$1);
|
|
3202
2887
|
}
|
|
3203
|
-
|
|
3204
|
-
|
|
2888
|
+
return {
|
|
2889
|
+
...state,
|
|
3205
2890
|
...changes
|
|
3206
2891
|
};
|
|
3207
2892
|
}
|
|
@@ -3209,15 +2894,14 @@ function downshiftUseComboboxReducer(state, action) {
|
|
|
3209
2894
|
|
|
3210
2895
|
/* eslint-disable max-statements */
|
|
3211
2896
|
useCombobox.stateChangeTypes = stateChangeTypes$1;
|
|
3212
|
-
|
|
3213
2897
|
function useCombobox(userProps) {
|
|
3214
2898
|
if (userProps === void 0) {
|
|
3215
2899
|
userProps = {};
|
|
3216
2900
|
}
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
2901
|
+
validatePropTypes$1(userProps, useCombobox);
|
|
2902
|
+
// Props defaults and destructuring.
|
|
2903
|
+
const props = {
|
|
2904
|
+
...defaultProps$1,
|
|
3221
2905
|
...userProps
|
|
3222
2906
|
};
|
|
3223
2907
|
const {
|
|
@@ -3229,8 +2913,8 @@ function useCombobox(userProps) {
|
|
|
3229
2913
|
getA11yStatusMessage,
|
|
3230
2914
|
getA11ySelectionMessage,
|
|
3231
2915
|
itemToString
|
|
3232
|
-
} = props;
|
|
3233
|
-
|
|
2916
|
+
} = props;
|
|
2917
|
+
// Initial state depending on controlled props.
|
|
3234
2918
|
const initialState = getInitialState$1(props);
|
|
3235
2919
|
const [state, dispatch] = useControlledReducer(downshiftUseComboboxReducer, initialState, props);
|
|
3236
2920
|
const {
|
|
@@ -3238,25 +2922,27 @@ function useCombobox(userProps) {
|
|
|
3238
2922
|
highlightedIndex,
|
|
3239
2923
|
selectedItem,
|
|
3240
2924
|
inputValue
|
|
3241
|
-
} = state;
|
|
2925
|
+
} = state;
|
|
3242
2926
|
|
|
2927
|
+
// Element refs.
|
|
3243
2928
|
const menuRef = react.useRef(null);
|
|
3244
2929
|
const itemRefs = react.useRef({});
|
|
3245
2930
|
const inputRef = react.useRef(null);
|
|
3246
2931
|
const toggleButtonRef = react.useRef(null);
|
|
3247
|
-
const isInitialMountRef = react.useRef(true);
|
|
3248
|
-
|
|
3249
|
-
const elementIds = useElementIds(props);
|
|
3250
|
-
|
|
3251
|
-
const previousResultCountRef = react.useRef();
|
|
3252
|
-
|
|
2932
|
+
const isInitialMountRef = react.useRef(true);
|
|
2933
|
+
// prevent id re-generation between renders.
|
|
2934
|
+
const elementIds = useElementIds(props);
|
|
2935
|
+
// used to keep track of how many items we had on previous cycle.
|
|
2936
|
+
const previousResultCountRef = react.useRef();
|
|
2937
|
+
// utility callback to get item element.
|
|
3253
2938
|
const latest = useLatestRef({
|
|
3254
2939
|
state,
|
|
3255
2940
|
props
|
|
3256
2941
|
});
|
|
3257
|
-
const getItemNodeFromIndex = react.useCallback(index => itemRefs.current[elementIds.getItemId(index)], [elementIds]);
|
|
3258
|
-
// Sets a11y status message on changes in state.
|
|
2942
|
+
const getItemNodeFromIndex = react.useCallback(index => itemRefs.current[elementIds.getItemId(index)], [elementIds]);
|
|
3259
2943
|
|
|
2944
|
+
// Effects.
|
|
2945
|
+
// Sets a11y status message on changes in state.
|
|
3260
2946
|
useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], {
|
|
3261
2947
|
isInitialMount: isInitialMountRef.current,
|
|
3262
2948
|
previousResultCount: previousResultCountRef.current,
|
|
@@ -3264,8 +2950,8 @@ function useCombobox(userProps) {
|
|
|
3264
2950
|
environment,
|
|
3265
2951
|
itemToString,
|
|
3266
2952
|
...state
|
|
3267
|
-
});
|
|
3268
|
-
|
|
2953
|
+
});
|
|
2954
|
+
// Sets a11y status message on changes in selectedItem.
|
|
3269
2955
|
useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], {
|
|
3270
2956
|
isInitialMount: isInitialMountRef.current,
|
|
3271
2957
|
previousResultCount: previousResultCountRef.current,
|
|
@@ -3273,8 +2959,8 @@ function useCombobox(userProps) {
|
|
|
3273
2959
|
environment,
|
|
3274
2960
|
itemToString,
|
|
3275
2961
|
...state
|
|
3276
|
-
});
|
|
3277
|
-
|
|
2962
|
+
});
|
|
2963
|
+
// Scroll on highlighted item if change comes from keyboard.
|
|
3278
2964
|
const shouldScrollRef = useScrollIntoView({
|
|
3279
2965
|
menuElement: menuRef.current,
|
|
3280
2966
|
highlightedIndex,
|
|
@@ -3287,47 +2973,44 @@ function useCombobox(userProps) {
|
|
|
3287
2973
|
isInitialMount: isInitialMountRef.current,
|
|
3288
2974
|
props,
|
|
3289
2975
|
state
|
|
3290
|
-
});
|
|
3291
|
-
|
|
2976
|
+
});
|
|
2977
|
+
// Focus the input on first render if required.
|
|
3292
2978
|
react.useEffect(() => {
|
|
3293
2979
|
const focusOnOpen = initialIsOpen || defaultIsOpen || isOpen;
|
|
3294
|
-
|
|
3295
2980
|
if (focusOnOpen && inputRef.current) {
|
|
3296
2981
|
inputRef.current.focus();
|
|
3297
|
-
}
|
|
3298
|
-
|
|
2982
|
+
}
|
|
2983
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3299
2984
|
}, []);
|
|
3300
2985
|
react.useEffect(() => {
|
|
3301
2986
|
if (isInitialMountRef.current) {
|
|
3302
2987
|
return;
|
|
3303
2988
|
}
|
|
3304
|
-
|
|
3305
2989
|
previousResultCountRef.current = items.length;
|
|
3306
|
-
});
|
|
3307
|
-
|
|
2990
|
+
});
|
|
2991
|
+
// Add mouse/touch events to document.
|
|
3308
2992
|
const mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [inputRef, menuRef, toggleButtonRef], environment, () => {
|
|
3309
2993
|
dispatch({
|
|
3310
2994
|
type: InputBlur,
|
|
3311
2995
|
selectItem: false
|
|
3312
2996
|
});
|
|
3313
2997
|
});
|
|
3314
|
-
const setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
|
|
3315
|
-
|
|
2998
|
+
const setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
|
|
2999
|
+
// Make initial ref false.
|
|
3316
3000
|
react.useEffect(() => {
|
|
3317
3001
|
isInitialMountRef.current = false;
|
|
3318
|
-
}, []);
|
|
3319
|
-
|
|
3002
|
+
}, []);
|
|
3003
|
+
// Reset itemRefs on close.
|
|
3320
3004
|
react.useEffect(() => {
|
|
3321
3005
|
if (!isOpen) {
|
|
3322
3006
|
itemRefs.current = {};
|
|
3323
3007
|
} else if (document.activeElement !== inputRef.current) {
|
|
3324
3008
|
var _inputRef$current;
|
|
3325
|
-
|
|
3326
3009
|
inputRef == null ? void 0 : (_inputRef$current = inputRef.current) == null ? void 0 : _inputRef$current.focus();
|
|
3327
3010
|
}
|
|
3328
3011
|
}, [isOpen]);
|
|
3329
|
-
/* Event handler functions */
|
|
3330
3012
|
|
|
3013
|
+
/* Event handler functions */
|
|
3331
3014
|
const inputKeyDownHandlers = react.useMemo(() => ({
|
|
3332
3015
|
ArrowDown(event) {
|
|
3333
3016
|
event.preventDefault();
|
|
@@ -3337,7 +3020,6 @@ function useCombobox(userProps) {
|
|
|
3337
3020
|
getItemNodeFromIndex
|
|
3338
3021
|
});
|
|
3339
3022
|
},
|
|
3340
|
-
|
|
3341
3023
|
ArrowUp(event) {
|
|
3342
3024
|
event.preventDefault();
|
|
3343
3025
|
dispatch({
|
|
@@ -3346,34 +3028,28 @@ function useCombobox(userProps) {
|
|
|
3346
3028
|
getItemNodeFromIndex
|
|
3347
3029
|
});
|
|
3348
3030
|
},
|
|
3349
|
-
|
|
3350
3031
|
Home(event) {
|
|
3351
3032
|
if (!latest.current.state.isOpen) {
|
|
3352
3033
|
return;
|
|
3353
3034
|
}
|
|
3354
|
-
|
|
3355
3035
|
event.preventDefault();
|
|
3356
3036
|
dispatch({
|
|
3357
3037
|
type: InputKeyDownHome,
|
|
3358
3038
|
getItemNodeFromIndex
|
|
3359
3039
|
});
|
|
3360
3040
|
},
|
|
3361
|
-
|
|
3362
3041
|
End(event) {
|
|
3363
3042
|
if (!latest.current.state.isOpen) {
|
|
3364
3043
|
return;
|
|
3365
3044
|
}
|
|
3366
|
-
|
|
3367
3045
|
event.preventDefault();
|
|
3368
3046
|
dispatch({
|
|
3369
3047
|
type: InputKeyDownEnd,
|
|
3370
3048
|
getItemNodeFromIndex
|
|
3371
3049
|
});
|
|
3372
3050
|
},
|
|
3373
|
-
|
|
3374
3051
|
Escape(event) {
|
|
3375
3052
|
const latestState = latest.current.state;
|
|
3376
|
-
|
|
3377
3053
|
if (latestState.isOpen || latestState.inputValue || latestState.selectedItem || latestState.highlightedIndex > -1) {
|
|
3378
3054
|
event.preventDefault();
|
|
3379
3055
|
dispatch({
|
|
@@ -3381,22 +3057,19 @@ function useCombobox(userProps) {
|
|
|
3381
3057
|
});
|
|
3382
3058
|
}
|
|
3383
3059
|
},
|
|
3384
|
-
|
|
3385
3060
|
Enter(event) {
|
|
3386
|
-
const latestState = latest.current.state;
|
|
3387
|
-
|
|
3061
|
+
const latestState = latest.current.state;
|
|
3062
|
+
// if closed or no highlighted index, do nothing.
|
|
3388
3063
|
if (!latestState.isOpen || event.which === 229 // if IME composing, wait for next Enter keydown event.
|
|
3389
3064
|
) {
|
|
3390
3065
|
return;
|
|
3391
3066
|
}
|
|
3392
|
-
|
|
3393
3067
|
event.preventDefault();
|
|
3394
3068
|
dispatch({
|
|
3395
3069
|
type: InputKeyDownEnter,
|
|
3396
3070
|
getItemNodeFromIndex
|
|
3397
3071
|
});
|
|
3398
3072
|
},
|
|
3399
|
-
|
|
3400
3073
|
PageUp(event) {
|
|
3401
3074
|
if (latest.current.state.isOpen) {
|
|
3402
3075
|
event.preventDefault();
|
|
@@ -3406,7 +3079,6 @@ function useCombobox(userProps) {
|
|
|
3406
3079
|
});
|
|
3407
3080
|
}
|
|
3408
3081
|
},
|
|
3409
|
-
|
|
3410
3082
|
PageDown(event) {
|
|
3411
3083
|
if (latest.current.state.isOpen) {
|
|
3412
3084
|
event.preventDefault();
|
|
@@ -3416,9 +3088,9 @@ function useCombobox(userProps) {
|
|
|
3416
3088
|
});
|
|
3417
3089
|
}
|
|
3418
3090
|
}
|
|
3091
|
+
}), [dispatch, latest, getItemNodeFromIndex]);
|
|
3419
3092
|
|
|
3420
|
-
|
|
3421
|
-
|
|
3093
|
+
// Getter props.
|
|
3422
3094
|
const getLabelProps = react.useCallback(labelProps => ({
|
|
3423
3095
|
id: elementIds.labelId,
|
|
3424
3096
|
htmlFor: elementIds.inputId,
|
|
@@ -3468,21 +3140,15 @@ function useCombobox(userProps) {
|
|
|
3468
3140
|
state: latestState
|
|
3469
3141
|
} = latest.current;
|
|
3470
3142
|
const itemIndex = getItemIndex(index, item, latestProps.items);
|
|
3471
|
-
|
|
3472
3143
|
if (itemIndex < 0) {
|
|
3473
3144
|
throw new Error('Pass either item or item index in getItemProps!');
|
|
3474
3145
|
}
|
|
3475
|
-
|
|
3476
|
-
const
|
|
3477
|
-
'onPress' ;
|
|
3478
|
-
const customClickHandler = /* istanbul ignore next (react-native) */
|
|
3479
|
-
onPress ;
|
|
3480
|
-
|
|
3146
|
+
const onSelectKey = /* istanbul ignore next (react-native) */'onPress' ;
|
|
3147
|
+
const customClickHandler = /* istanbul ignore next (react-native) */onPress ;
|
|
3481
3148
|
const itemHandleMouseMove = () => {
|
|
3482
3149
|
if (index === latestState.highlightedIndex) {
|
|
3483
3150
|
return;
|
|
3484
3151
|
}
|
|
3485
|
-
|
|
3486
3152
|
shouldScrollRef.current = false;
|
|
3487
3153
|
dispatch({
|
|
3488
3154
|
type: ItemMouseMove,
|
|
@@ -3490,16 +3156,13 @@ function useCombobox(userProps) {
|
|
|
3490
3156
|
disabled
|
|
3491
3157
|
});
|
|
3492
3158
|
};
|
|
3493
|
-
|
|
3494
3159
|
const itemHandleClick = () => {
|
|
3495
3160
|
dispatch({
|
|
3496
3161
|
type: ItemClick,
|
|
3497
3162
|
index
|
|
3498
3163
|
});
|
|
3499
3164
|
};
|
|
3500
|
-
|
|
3501
3165
|
const itemHandleMouseDown = e => e.preventDefault();
|
|
3502
|
-
|
|
3503
3166
|
return {
|
|
3504
3167
|
[refKey]: handleRefs(ref, itemNode => {
|
|
3505
3168
|
if (itemNode) {
|
|
@@ -3527,13 +3190,11 @@ function useCombobox(userProps) {
|
|
|
3527
3190
|
...rest
|
|
3528
3191
|
} = _temp4 === void 0 ? {} : _temp4;
|
|
3529
3192
|
const latestState = latest.current.state;
|
|
3530
|
-
|
|
3531
3193
|
const toggleButtonHandleClick = () => {
|
|
3532
3194
|
dispatch({
|
|
3533
3195
|
type: ToggleButtonClick
|
|
3534
3196
|
});
|
|
3535
3197
|
};
|
|
3536
|
-
|
|
3537
3198
|
return {
|
|
3538
3199
|
[refKey]: handleRefs(ref, toggleButtonNode => {
|
|
3539
3200
|
toggleButtonRef.current = toggleButtonNode;
|
|
@@ -3542,8 +3203,8 @@ function useCombobox(userProps) {
|
|
|
3542
3203
|
'aria-expanded': latestState.isOpen,
|
|
3543
3204
|
id: elementIds.toggleButtonId,
|
|
3544
3205
|
tabIndex: -1,
|
|
3545
|
-
...(!rest.disabled && {
|
|
3546
|
-
{
|
|
3206
|
+
...(!rest.disabled && {
|
|
3207
|
+
...(/* istanbul ignore next (react-native) */{
|
|
3547
3208
|
onPress: callAllEventHandlers(onPress, toggleButtonHandleClick)
|
|
3548
3209
|
} )
|
|
3549
3210
|
}),
|
|
@@ -3567,23 +3228,18 @@ function useCombobox(userProps) {
|
|
|
3567
3228
|
} = _temp6 === void 0 ? {} : _temp6;
|
|
3568
3229
|
setGetterPropCallInfo('getInputProps', suppressRefError, refKey, inputRef);
|
|
3569
3230
|
const latestState = latest.current.state;
|
|
3570
|
-
|
|
3571
3231
|
const inputHandleKeyDown = event => {
|
|
3572
3232
|
const key = normalizeArrowKey(event);
|
|
3573
|
-
|
|
3574
3233
|
if (key && inputKeyDownHandlers[key]) {
|
|
3575
3234
|
inputKeyDownHandlers[key](event);
|
|
3576
3235
|
}
|
|
3577
3236
|
};
|
|
3578
|
-
|
|
3579
3237
|
const inputHandleChange = event => {
|
|
3580
3238
|
dispatch({
|
|
3581
3239
|
type: InputChange,
|
|
3582
|
-
inputValue: /* istanbul ignore next (react-native) */
|
|
3583
|
-
event.nativeEvent.text
|
|
3240
|
+
inputValue: /* istanbul ignore next (react-native) */event.nativeEvent.text
|
|
3584
3241
|
});
|
|
3585
3242
|
};
|
|
3586
|
-
|
|
3587
3243
|
const inputHandleBlur = () => {
|
|
3588
3244
|
/* istanbul ignore else */
|
|
3589
3245
|
if (latestState.isOpen && !mouseAndTouchTrackersRef.current.isMouseDown) {
|
|
@@ -3593,7 +3249,6 @@ function useCombobox(userProps) {
|
|
|
3593
3249
|
});
|
|
3594
3250
|
}
|
|
3595
3251
|
};
|
|
3596
|
-
|
|
3597
3252
|
const inputHandleFocus = () => {
|
|
3598
3253
|
if (!latestState.isOpen) {
|
|
3599
3254
|
dispatch({
|
|
@@ -3601,12 +3256,10 @@ function useCombobox(userProps) {
|
|
|
3601
3256
|
});
|
|
3602
3257
|
}
|
|
3603
3258
|
};
|
|
3604
|
-
/* istanbul ignore next (preact) */
|
|
3605
|
-
|
|
3606
3259
|
|
|
3260
|
+
/* istanbul ignore next (preact) */
|
|
3607
3261
|
const onChangeKey = 'onChange';
|
|
3608
3262
|
let eventHandlers = {};
|
|
3609
|
-
|
|
3610
3263
|
if (!rest.disabled) {
|
|
3611
3264
|
eventHandlers = {
|
|
3612
3265
|
[onChangeKey]: callAllEventHandlers(onChange, onInput, inputHandleChange),
|
|
@@ -3615,9 +3268,8 @@ function useCombobox(userProps) {
|
|
|
3615
3268
|
onFocus: callAllEventHandlers(onFocus, inputHandleFocus)
|
|
3616
3269
|
};
|
|
3617
3270
|
}
|
|
3618
|
-
/* istanbul ignore if (react-native) */
|
|
3619
|
-
|
|
3620
3271
|
|
|
3272
|
+
/* istanbul ignore if (react-native) */
|
|
3621
3273
|
{
|
|
3622
3274
|
eventHandlers.onChange = callAllEventHandlers(onChange, onInput, inputHandleChange);
|
|
3623
3275
|
eventHandlers.onChangeText = callAllEventHandlers(onChangeText, onInput, text => {
|
|
@@ -3628,7 +3280,6 @@ function useCombobox(userProps) {
|
|
|
3628
3280
|
});
|
|
3629
3281
|
});
|
|
3630
3282
|
}
|
|
3631
|
-
|
|
3632
3283
|
return {
|
|
3633
3284
|
[refKey]: handleRefs(ref, inputNode => {
|
|
3634
3285
|
inputRef.current = inputNode;
|
|
@@ -3647,8 +3298,9 @@ function useCombobox(userProps) {
|
|
|
3647
3298
|
...eventHandlers,
|
|
3648
3299
|
...rest
|
|
3649
3300
|
};
|
|
3650
|
-
}, [dispatch, inputKeyDownHandlers, latest, mouseAndTouchTrackersRef, setGetterPropCallInfo, elementIds]);
|
|
3301
|
+
}, [dispatch, inputKeyDownHandlers, latest, mouseAndTouchTrackersRef, setGetterPropCallInfo, elementIds]);
|
|
3651
3302
|
|
|
3303
|
+
// returns
|
|
3652
3304
|
const toggleMenu = react.useCallback(() => {
|
|
3653
3305
|
dispatch({
|
|
3654
3306
|
type: FunctionToggleMenu
|
|
@@ -3714,6 +3366,7 @@ const defaultStateValues = {
|
|
|
3714
3366
|
activeIndex: -1,
|
|
3715
3367
|
selectedItems: []
|
|
3716
3368
|
};
|
|
3369
|
+
|
|
3717
3370
|
/**
|
|
3718
3371
|
* Returns the initial value for a state key in the following order:
|
|
3719
3372
|
* 1. controlled prop, 2. initial prop, 3. default prop, 4. default
|
|
@@ -3723,10 +3376,10 @@ const defaultStateValues = {
|
|
|
3723
3376
|
* @param {string} propKey Props key to generate the value for.
|
|
3724
3377
|
* @returns {any} The initial value for that prop.
|
|
3725
3378
|
*/
|
|
3726
|
-
|
|
3727
3379
|
function getInitialValue(props, propKey) {
|
|
3728
3380
|
return getInitialValue$1(props, propKey, defaultStateValues);
|
|
3729
3381
|
}
|
|
3382
|
+
|
|
3730
3383
|
/**
|
|
3731
3384
|
* Returns the default value for a state key in the following order:
|
|
3732
3385
|
* 1. controlled prop, 2. default prop, 3. default value from Downshift.
|
|
@@ -3735,11 +3388,10 @@ function getInitialValue(props, propKey) {
|
|
|
3735
3388
|
* @param {string} propKey Props key to generate the value for.
|
|
3736
3389
|
* @returns {any} The initial value for that prop.
|
|
3737
3390
|
*/
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
3391
|
function getDefaultValue(props, propKey) {
|
|
3741
3392
|
return getDefaultValue$1(props, propKey, defaultStateValues);
|
|
3742
3393
|
}
|
|
3394
|
+
|
|
3743
3395
|
/**
|
|
3744
3396
|
* Gets the initial state based on the provided props. It uses initial, default
|
|
3745
3397
|
* and controlled props related to state in order to compute the initial value.
|
|
@@ -3747,8 +3399,6 @@ function getDefaultValue(props, propKey) {
|
|
|
3747
3399
|
* @param {Object} props Props passed to the hook.
|
|
3748
3400
|
* @returns {Object} The initial state.
|
|
3749
3401
|
*/
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
3402
|
function getInitialState(props) {
|
|
3753
3403
|
const activeIndex = getInitialValue(props, 'activeIndex');
|
|
3754
3404
|
const selectedItems = getInitialValue(props, 'selectedItems');
|
|
@@ -3757,6 +3407,7 @@ function getInitialState(props) {
|
|
|
3757
3407
|
selectedItems
|
|
3758
3408
|
};
|
|
3759
3409
|
}
|
|
3410
|
+
|
|
3760
3411
|
/**
|
|
3761
3412
|
* Returns true if dropdown keydown operation is permitted. Should not be
|
|
3762
3413
|
* allowed on keydown with modifier keys (ctrl, alt, shift, meta), on
|
|
@@ -3766,32 +3417,28 @@ function getInitialState(props) {
|
|
|
3766
3417
|
* @param {KeyboardEvent} event The event from keydown.
|
|
3767
3418
|
* @returns {boolean} Whether the operation is allowed.
|
|
3768
3419
|
*/
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
3420
|
function isKeyDownOperationPermitted(event) {
|
|
3772
3421
|
if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) {
|
|
3773
3422
|
return false;
|
|
3774
3423
|
}
|
|
3775
|
-
|
|
3776
3424
|
const element = event.target;
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
element.value !== '' && (
|
|
3425
|
+
if (element instanceof HTMLInputElement &&
|
|
3426
|
+
// if element is a text input
|
|
3427
|
+
element.value !== '' && (
|
|
3428
|
+
// and we have text in it
|
|
3780
3429
|
// and cursor is either not at the start or is currently highlighting text.
|
|
3781
3430
|
element.selectionStart !== 0 || element.selectionEnd !== 0)) {
|
|
3782
3431
|
return false;
|
|
3783
3432
|
}
|
|
3784
|
-
|
|
3785
3433
|
return true;
|
|
3786
3434
|
}
|
|
3435
|
+
|
|
3787
3436
|
/**
|
|
3788
3437
|
* Returns a message to be added to aria-live region when item is removed.
|
|
3789
3438
|
*
|
|
3790
3439
|
* @param {Object} selectionParameters Parameters required to build the message.
|
|
3791
3440
|
* @returns {string} The a11y message.
|
|
3792
3441
|
*/
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
3442
|
function getA11yRemovalMessage(selectionParameters) {
|
|
3796
3443
|
const {
|
|
3797
3444
|
removedSelectedItem,
|
|
@@ -3799,7 +3446,6 @@ function getA11yRemovalMessage(selectionParameters) {
|
|
|
3799
3446
|
} = selectionParameters;
|
|
3800
3447
|
return `${itemToStringLocal(removedSelectedItem)} has been removed.`;
|
|
3801
3448
|
}
|
|
3802
|
-
|
|
3803
3449
|
const propTypes = {
|
|
3804
3450
|
selectedItems: PropTypes__default["default"].array,
|
|
3805
3451
|
initialSelectedItems: PropTypes__default["default"].array,
|
|
@@ -3831,11 +3477,11 @@ const defaultProps = {
|
|
|
3831
3477
|
getA11yRemovalMessage,
|
|
3832
3478
|
keyNavigationNext: 'ArrowRight',
|
|
3833
3479
|
keyNavigationPrevious: 'ArrowLeft'
|
|
3834
|
-
};
|
|
3480
|
+
};
|
|
3835
3481
|
|
|
3482
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
3836
3483
|
let validatePropTypes = noop;
|
|
3837
3484
|
/* istanbul ignore next */
|
|
3838
|
-
|
|
3839
3485
|
if (process.env.NODE_ENV !== 'production') {
|
|
3840
3486
|
validatePropTypes = (options, caller) => {
|
|
3841
3487
|
PropTypes__default["default"].checkPropTypes(propTypes, options, 'prop', caller.name);
|
|
@@ -3874,7 +3520,6 @@ var stateChangeTypes = /*#__PURE__*/Object.freeze({
|
|
|
3874
3520
|
});
|
|
3875
3521
|
|
|
3876
3522
|
/* eslint-disable complexity */
|
|
3877
|
-
|
|
3878
3523
|
function downshiftMultipleSelectionReducer(state, action) {
|
|
3879
3524
|
const {
|
|
3880
3525
|
type,
|
|
@@ -3887,37 +3532,31 @@ function downshiftMultipleSelectionReducer(state, action) {
|
|
|
3887
3532
|
selectedItems
|
|
3888
3533
|
} = state;
|
|
3889
3534
|
let changes;
|
|
3890
|
-
|
|
3891
3535
|
switch (type) {
|
|
3892
3536
|
case SelectedItemClick:
|
|
3893
3537
|
changes = {
|
|
3894
3538
|
activeIndex: index
|
|
3895
3539
|
};
|
|
3896
3540
|
break;
|
|
3897
|
-
|
|
3898
3541
|
case SelectedItemKeyDownNavigationPrevious:
|
|
3899
3542
|
changes = {
|
|
3900
3543
|
activeIndex: activeIndex - 1 < 0 ? 0 : activeIndex - 1
|
|
3901
3544
|
};
|
|
3902
3545
|
break;
|
|
3903
|
-
|
|
3904
3546
|
case SelectedItemKeyDownNavigationNext:
|
|
3905
3547
|
changes = {
|
|
3906
3548
|
activeIndex: activeIndex + 1 >= selectedItems.length ? -1 : activeIndex + 1
|
|
3907
3549
|
};
|
|
3908
3550
|
break;
|
|
3909
|
-
|
|
3910
3551
|
case SelectedItemKeyDownBackspace:
|
|
3911
3552
|
case SelectedItemKeyDownDelete:
|
|
3912
3553
|
{
|
|
3913
3554
|
let newActiveIndex = activeIndex;
|
|
3914
|
-
|
|
3915
3555
|
if (selectedItems.length === 1) {
|
|
3916
3556
|
newActiveIndex = -1;
|
|
3917
3557
|
} else if (activeIndex === selectedItems.length - 1) {
|
|
3918
3558
|
newActiveIndex = selectedItems.length - 2;
|
|
3919
3559
|
}
|
|
3920
|
-
|
|
3921
3560
|
changes = {
|
|
3922
3561
|
selectedItems: [...selectedItems.slice(0, activeIndex), ...selectedItems.slice(activeIndex + 1)],
|
|
3923
3562
|
...{
|
|
@@ -3926,52 +3565,43 @@ function downshiftMultipleSelectionReducer(state, action) {
|
|
|
3926
3565
|
};
|
|
3927
3566
|
break;
|
|
3928
3567
|
}
|
|
3929
|
-
|
|
3930
3568
|
case DropdownKeyDownNavigationPrevious:
|
|
3931
3569
|
changes = {
|
|
3932
3570
|
activeIndex: selectedItems.length - 1
|
|
3933
3571
|
};
|
|
3934
3572
|
break;
|
|
3935
|
-
|
|
3936
3573
|
case DropdownKeyDownBackspace:
|
|
3937
3574
|
changes = {
|
|
3938
3575
|
selectedItems: selectedItems.slice(0, selectedItems.length - 1)
|
|
3939
3576
|
};
|
|
3940
3577
|
break;
|
|
3941
|
-
|
|
3942
3578
|
case FunctionAddSelectedItem:
|
|
3943
3579
|
changes = {
|
|
3944
3580
|
selectedItems: [...selectedItems, selectedItem]
|
|
3945
3581
|
};
|
|
3946
3582
|
break;
|
|
3947
|
-
|
|
3948
3583
|
case DropdownClick:
|
|
3949
3584
|
changes = {
|
|
3950
3585
|
activeIndex: -1
|
|
3951
3586
|
};
|
|
3952
3587
|
break;
|
|
3953
|
-
|
|
3954
3588
|
case FunctionRemoveSelectedItem:
|
|
3955
3589
|
{
|
|
3956
3590
|
let newActiveIndex = activeIndex;
|
|
3957
3591
|
const selectedItemIndex = selectedItems.indexOf(selectedItem);
|
|
3958
|
-
|
|
3959
3592
|
if (selectedItemIndex >= 0) {
|
|
3960
3593
|
if (selectedItems.length === 1) {
|
|
3961
3594
|
newActiveIndex = -1;
|
|
3962
3595
|
} else if (selectedItemIndex === selectedItems.length - 1) {
|
|
3963
3596
|
newActiveIndex = selectedItems.length - 2;
|
|
3964
3597
|
}
|
|
3965
|
-
|
|
3966
3598
|
changes = {
|
|
3967
3599
|
selectedItems: [...selectedItems.slice(0, selectedItemIndex), ...selectedItems.slice(selectedItemIndex + 1)],
|
|
3968
3600
|
activeIndex: newActiveIndex
|
|
3969
3601
|
};
|
|
3970
3602
|
}
|
|
3971
|
-
|
|
3972
3603
|
break;
|
|
3973
3604
|
}
|
|
3974
|
-
|
|
3975
3605
|
case FunctionSetSelectedItems:
|
|
3976
3606
|
{
|
|
3977
3607
|
const {
|
|
@@ -3982,7 +3612,6 @@ function downshiftMultipleSelectionReducer(state, action) {
|
|
|
3982
3612
|
};
|
|
3983
3613
|
break;
|
|
3984
3614
|
}
|
|
3985
|
-
|
|
3986
3615
|
case FunctionSetActiveIndex:
|
|
3987
3616
|
{
|
|
3988
3617
|
const {
|
|
@@ -3993,33 +3622,30 @@ function downshiftMultipleSelectionReducer(state, action) {
|
|
|
3993
3622
|
};
|
|
3994
3623
|
break;
|
|
3995
3624
|
}
|
|
3996
|
-
|
|
3997
3625
|
case FunctionReset:
|
|
3998
3626
|
changes = {
|
|
3999
3627
|
activeIndex: getDefaultValue(props, 'activeIndex'),
|
|
4000
3628
|
selectedItems: getDefaultValue(props, 'selectedItems')
|
|
4001
3629
|
};
|
|
4002
3630
|
break;
|
|
4003
|
-
|
|
4004
3631
|
default:
|
|
4005
3632
|
throw new Error('Reducer called without proper action type.');
|
|
4006
3633
|
}
|
|
4007
|
-
|
|
4008
|
-
|
|
3634
|
+
return {
|
|
3635
|
+
...state,
|
|
4009
3636
|
...changes
|
|
4010
3637
|
};
|
|
4011
3638
|
}
|
|
4012
3639
|
|
|
4013
3640
|
useMultipleSelection.stateChangeTypes = stateChangeTypes;
|
|
4014
|
-
|
|
4015
3641
|
function useMultipleSelection(userProps) {
|
|
4016
3642
|
if (userProps === void 0) {
|
|
4017
3643
|
userProps = {};
|
|
4018
3644
|
}
|
|
4019
|
-
|
|
4020
|
-
|
|
4021
|
-
|
|
4022
|
-
|
|
3645
|
+
validatePropTypes(userProps, useMultipleSelection);
|
|
3646
|
+
// Props defaults and destructuring.
|
|
3647
|
+
const props = {
|
|
3648
|
+
...defaultProps,
|
|
4023
3649
|
...userProps
|
|
4024
3650
|
};
|
|
4025
3651
|
const {
|
|
@@ -4028,14 +3654,16 @@ function useMultipleSelection(userProps) {
|
|
|
4028
3654
|
environment,
|
|
4029
3655
|
keyNavigationNext,
|
|
4030
3656
|
keyNavigationPrevious
|
|
4031
|
-
} = props;
|
|
3657
|
+
} = props;
|
|
4032
3658
|
|
|
3659
|
+
// Reducer init.
|
|
4033
3660
|
const [state, dispatch] = useControlledReducer$1(downshiftMultipleSelectionReducer, getInitialState(props), props);
|
|
4034
3661
|
const {
|
|
4035
3662
|
activeIndex,
|
|
4036
3663
|
selectedItems
|
|
4037
|
-
} = state;
|
|
3664
|
+
} = state;
|
|
4038
3665
|
|
|
3666
|
+
// Refs.
|
|
4039
3667
|
const isInitialMountRef = react.useRef(true);
|
|
4040
3668
|
const dropdownRef = react.useRef(null);
|
|
4041
3669
|
const previousSelectedItemsRef = react.useRef(selectedItems);
|
|
@@ -4044,15 +3672,14 @@ function useMultipleSelection(userProps) {
|
|
|
4044
3672
|
const latest = useLatestRef({
|
|
4045
3673
|
state,
|
|
4046
3674
|
props
|
|
4047
|
-
});
|
|
3675
|
+
});
|
|
4048
3676
|
|
|
3677
|
+
// Effects.
|
|
4049
3678
|
/* Sets a11y status message on changes in selectedItem. */
|
|
4050
|
-
|
|
4051
3679
|
react.useEffect(() => {
|
|
4052
3680
|
if (isInitialMountRef.current) {
|
|
4053
3681
|
return;
|
|
4054
3682
|
}
|
|
4055
|
-
|
|
4056
3683
|
if (selectedItems.length < previousSelectedItemsRef.current.length) {
|
|
4057
3684
|
const removedSelectedItem = previousSelectedItemsRef.current.find(item => selectedItems.indexOf(item) < 0);
|
|
4058
3685
|
setStatus(getA11yRemovalMessage({
|
|
@@ -4063,15 +3690,15 @@ function useMultipleSelection(userProps) {
|
|
|
4063
3690
|
activeSelectedItem: selectedItems[activeIndex]
|
|
4064
3691
|
}), environment.document);
|
|
4065
3692
|
}
|
|
3693
|
+
previousSelectedItemsRef.current = selectedItems;
|
|
4066
3694
|
|
|
4067
|
-
|
|
4068
|
-
}, [selectedItems.length]);
|
|
4069
|
-
|
|
3695
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3696
|
+
}, [selectedItems.length]);
|
|
3697
|
+
// Sets focus on active item.
|
|
4070
3698
|
react.useEffect(() => {
|
|
4071
3699
|
if (isInitialMountRef.current) {
|
|
4072
3700
|
return;
|
|
4073
3701
|
}
|
|
4074
|
-
|
|
4075
3702
|
if (activeIndex === -1 && dropdownRef.current) {
|
|
4076
3703
|
dropdownRef.current.focus();
|
|
4077
3704
|
} else if (selectedItemRefs.current[activeIndex]) {
|
|
@@ -4083,37 +3710,34 @@ function useMultipleSelection(userProps) {
|
|
|
4083
3710
|
props,
|
|
4084
3711
|
state
|
|
4085
3712
|
});
|
|
4086
|
-
const setGetterPropCallInfo = useGetterPropsCalledChecker('getDropdownProps');
|
|
4087
|
-
|
|
3713
|
+
const setGetterPropCallInfo = useGetterPropsCalledChecker('getDropdownProps');
|
|
3714
|
+
// Make initial ref false.
|
|
4088
3715
|
react.useEffect(() => {
|
|
4089
3716
|
isInitialMountRef.current = false;
|
|
4090
|
-
}, []);
|
|
3717
|
+
}, []);
|
|
4091
3718
|
|
|
3719
|
+
// Event handler functions.
|
|
4092
3720
|
const selectedItemKeyDownHandlers = react.useMemo(() => ({
|
|
4093
3721
|
[keyNavigationPrevious]() {
|
|
4094
3722
|
dispatch({
|
|
4095
3723
|
type: SelectedItemKeyDownNavigationPrevious
|
|
4096
3724
|
});
|
|
4097
3725
|
},
|
|
4098
|
-
|
|
4099
3726
|
[keyNavigationNext]() {
|
|
4100
3727
|
dispatch({
|
|
4101
3728
|
type: SelectedItemKeyDownNavigationNext
|
|
4102
3729
|
});
|
|
4103
3730
|
},
|
|
4104
|
-
|
|
4105
3731
|
Delete() {
|
|
4106
3732
|
dispatch({
|
|
4107
3733
|
type: SelectedItemKeyDownDelete
|
|
4108
3734
|
});
|
|
4109
3735
|
},
|
|
4110
|
-
|
|
4111
3736
|
Backspace() {
|
|
4112
3737
|
dispatch({
|
|
4113
3738
|
type: SelectedItemKeyDownBackspace
|
|
4114
3739
|
});
|
|
4115
3740
|
}
|
|
4116
|
-
|
|
4117
3741
|
}), [dispatch, keyNavigationNext, keyNavigationPrevious]);
|
|
4118
3742
|
const dropdownKeyDownHandlers = react.useMemo(() => ({
|
|
4119
3743
|
[keyNavigationPrevious](event) {
|
|
@@ -4123,7 +3747,6 @@ function useMultipleSelection(userProps) {
|
|
|
4123
3747
|
});
|
|
4124
3748
|
}
|
|
4125
3749
|
},
|
|
4126
|
-
|
|
4127
3750
|
Backspace(event) {
|
|
4128
3751
|
if (isKeyDownOperationPermitted(event)) {
|
|
4129
3752
|
dispatch({
|
|
@@ -4131,9 +3754,9 @@ function useMultipleSelection(userProps) {
|
|
|
4131
3754
|
});
|
|
4132
3755
|
}
|
|
4133
3756
|
}
|
|
3757
|
+
}), [dispatch, keyNavigationPrevious]);
|
|
4134
3758
|
|
|
4135
|
-
|
|
4136
|
-
|
|
3759
|
+
// Getter props.
|
|
4137
3760
|
const getSelectedItemProps = react.useCallback(function (_temp) {
|
|
4138
3761
|
let {
|
|
4139
3762
|
refKey = 'ref',
|
|
@@ -4148,26 +3771,21 @@ function useMultipleSelection(userProps) {
|
|
|
4148
3771
|
state: latestState
|
|
4149
3772
|
} = latest.current;
|
|
4150
3773
|
const itemIndex = getItemIndex(index, selectedItem, latestState.selectedItems);
|
|
4151
|
-
|
|
4152
3774
|
if (itemIndex < 0) {
|
|
4153
3775
|
throw new Error('Pass either selectedItem or index in getSelectedItemProps!');
|
|
4154
3776
|
}
|
|
4155
|
-
|
|
4156
3777
|
const selectedItemHandleClick = () => {
|
|
4157
3778
|
dispatch({
|
|
4158
3779
|
type: SelectedItemClick,
|
|
4159
3780
|
index
|
|
4160
3781
|
});
|
|
4161
3782
|
};
|
|
4162
|
-
|
|
4163
3783
|
const selectedItemHandleKeyDown = event => {
|
|
4164
3784
|
const key = normalizeArrowKey(event);
|
|
4165
|
-
|
|
4166
3785
|
if (key && selectedItemKeyDownHandlers[key]) {
|
|
4167
3786
|
selectedItemKeyDownHandlers[key](event);
|
|
4168
3787
|
}
|
|
4169
3788
|
};
|
|
4170
|
-
|
|
4171
3789
|
return {
|
|
4172
3790
|
[refKey]: handleRefs(ref, selectedItemNode => {
|
|
4173
3791
|
if (selectedItemNode) {
|
|
@@ -4193,21 +3811,17 @@ function useMultipleSelection(userProps) {
|
|
|
4193
3811
|
suppressRefError = false
|
|
4194
3812
|
} = _temp3 === void 0 ? {} : _temp3;
|
|
4195
3813
|
setGetterPropCallInfo('getDropdownProps', suppressRefError, refKey, dropdownRef);
|
|
4196
|
-
|
|
4197
3814
|
const dropdownHandleKeyDown = event => {
|
|
4198
3815
|
const key = normalizeArrowKey(event);
|
|
4199
|
-
|
|
4200
3816
|
if (key && dropdownKeyDownHandlers[key]) {
|
|
4201
3817
|
dropdownKeyDownHandlers[key](event);
|
|
4202
3818
|
}
|
|
4203
3819
|
};
|
|
4204
|
-
|
|
4205
3820
|
const dropdownHandleClick = () => {
|
|
4206
3821
|
dispatch({
|
|
4207
3822
|
type: DropdownClick
|
|
4208
3823
|
});
|
|
4209
3824
|
};
|
|
4210
|
-
|
|
4211
3825
|
return {
|
|
4212
3826
|
[refKey]: handleRefs(ref, dropdownNode => {
|
|
4213
3827
|
if (dropdownNode) {
|
|
@@ -4220,8 +3834,9 @@ function useMultipleSelection(userProps) {
|
|
|
4220
3834
|
}),
|
|
4221
3835
|
...rest
|
|
4222
3836
|
};
|
|
4223
|
-
}, [dispatch, dropdownKeyDownHandlers, setGetterPropCallInfo]);
|
|
3837
|
+
}, [dispatch, dropdownKeyDownHandlers, setGetterPropCallInfo]);
|
|
4224
3838
|
|
|
3839
|
+
// returns
|
|
4225
3840
|
const addSelectedItem = react.useCallback(selectedItem => {
|
|
4226
3841
|
dispatch({
|
|
4227
3842
|
type: FunctionAddSelectedItem,
|