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