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.umd.js
CHANGED
|
@@ -1266,6 +1266,7 @@
|
|
|
1266
1266
|
function t(t){return "object"==typeof t&&null!=t&&1===t.nodeType}function e(t,e){return (!e||"hidden"!==t)&&"visible"!==t&&"clip"!==t}function n(t,n){if(t.clientHeight<t.scrollHeight||t.clientWidth<t.scrollWidth){var r=getComputedStyle(t,null);return e(r.overflowY,n)||e(r.overflowX,n)||function(t){var e=function(t){if(!t.ownerDocument||!t.ownerDocument.defaultView)return null;try{return t.ownerDocument.defaultView.frameElement}catch(t){return null}}(t);return !!e&&(e.clientHeight<t.scrollHeight||e.clientWidth<t.scrollWidth)}(t)}return !1}function r(t,e,n,r,i,o,l,d){return o<t&&l>e||o>t&&l<e?0:o<=t&&d<=n||l>=e&&d>=n?o-t-r:l>e&&d<n||o<t&&d>n?l-e+i:0}function computeScrollIntoView(e,i){var o=window,l=i.scrollMode,d=i.block,u=i.inline,h=i.boundary,a=i.skipOverflowHiddenElements,c="function"==typeof h?h:function(t){return t!==h};if(!t(e))throw new TypeError("Invalid target");for(var f=document.scrollingElement||document.documentElement,s=[],p=e;t(p)&&c(p);){if((p=p.parentElement)===f){s.push(p);break}null!=p&&p===document.body&&n(p)&&!n(document.documentElement)||null!=p&&n(p,a)&&s.push(p);}for(var m=o.visualViewport?o.visualViewport.width:innerWidth,g=o.visualViewport?o.visualViewport.height:innerHeight,w=window.scrollX||pageXOffset,v=window.scrollY||pageYOffset,W=e.getBoundingClientRect(),b=W.height,H=W.width,y=W.top,E=W.right,M=W.bottom,V=W.left,x="start"===d||"nearest"===d?y:"end"===d?M:y+b/2,I="center"===u?V+H/2:"end"===u?E:V,C=[],T=0;T<s.length;T++){var k=s[T],B=k.getBoundingClientRect(),D=B.height,O=B.width,R=B.top,X=B.right,Y=B.bottom,L=B.left;if("if-needed"===l&&y>=0&&V>=0&&M<=g&&E<=m&&y>=R&&M<=Y&&V>=L&&E<=X)return C;var S=getComputedStyle(k),j=parseInt(S.borderLeftWidth,10),q=parseInt(S.borderTopWidth,10),z=parseInt(S.borderRightWidth,10),A=parseInt(S.borderBottomWidth,10),F=0,G=0,J="offsetWidth"in k?k.offsetWidth-k.clientWidth-j-z:0,K="offsetHeight"in k?k.offsetHeight-k.clientHeight-q-A:0;if(f===k)F="start"===d?x:"end"===d?x-g:"nearest"===d?r(v,v+g,g,q,A,v+x,v+x+b,b):x-g/2,G="start"===u?I:"center"===u?I-m/2:"end"===u?I-m:r(w,w+m,m,j,z,w+I,w+I+H,H),F=Math.max(0,F+v),G=Math.max(0,G+w);else {F="start"===d?x-R-q:"end"===d?x-Y+A+K:"nearest"===d?r(R,Y,D,q,A+K,x,x+b,b):x-(R+D/2)+K/2,G="start"===u?I-L-j:"center"===u?I-(L+O/2)+J/2:"end"===u?I-X+z+J:r(L,X,O,j,z+J,I,I+H,H);var N=k.scrollLeft,P=k.scrollTop;x+=P-(F=Math.max(0,Math.min(P+F,k.scrollHeight-D+K))),I+=N-(G=Math.max(0,Math.min(N+G,k.scrollWidth-O+J)));}C.push({el:k,top:F,left:G});}return C}
|
|
1267
1267
|
|
|
1268
1268
|
let idCounter = 0;
|
|
1269
|
+
|
|
1269
1270
|
/**
|
|
1270
1271
|
* Accepts a parameter and returns it if it's a function
|
|
1271
1272
|
* or a noop function if it's not. This allows us to
|
|
@@ -1274,24 +1275,20 @@
|
|
|
1274
1275
|
* @param {Function} cb the callback
|
|
1275
1276
|
* @return {Function} a function
|
|
1276
1277
|
*/
|
|
1277
|
-
|
|
1278
1278
|
function cbToCb(cb) {
|
|
1279
1279
|
return typeof cb === 'function' ? cb : noop;
|
|
1280
1280
|
}
|
|
1281
|
-
|
|
1282
1281
|
function noop() {}
|
|
1282
|
+
|
|
1283
1283
|
/**
|
|
1284
1284
|
* Scroll node into view if necessary
|
|
1285
1285
|
* @param {HTMLElement} node the element that should scroll into view
|
|
1286
1286
|
* @param {HTMLElement} menuNode the menu element of the component
|
|
1287
1287
|
*/
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
1288
|
function scrollIntoView(node, menuNode) {
|
|
1291
1289
|
if (!node) {
|
|
1292
1290
|
return;
|
|
1293
1291
|
}
|
|
1294
|
-
|
|
1295
1292
|
const actions = computeScrollIntoView(node, {
|
|
1296
1293
|
boundary: menuNode,
|
|
1297
1294
|
block: 'nearest',
|
|
@@ -1307,18 +1304,18 @@
|
|
|
1307
1304
|
el.scrollLeft = left;
|
|
1308
1305
|
});
|
|
1309
1306
|
}
|
|
1307
|
+
|
|
1310
1308
|
/**
|
|
1311
1309
|
* @param {HTMLElement} parent the parent node
|
|
1312
1310
|
* @param {HTMLElement} child the child node
|
|
1313
1311
|
* @param {Window} environment The window context where downshift renders.
|
|
1314
1312
|
* @return {Boolean} whether the parent is the child or the child is in the parent
|
|
1315
1313
|
*/
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
1314
|
function isOrContainsNode(parent, child, environment) {
|
|
1319
1315
|
const result = parent === child || child instanceof environment.Node && parent.contains && parent.contains(child);
|
|
1320
1316
|
return result;
|
|
1321
1317
|
}
|
|
1318
|
+
|
|
1322
1319
|
/**
|
|
1323
1320
|
* Simple debounce implementation. Will call the given
|
|
1324
1321
|
* function once after the time given has passed since
|
|
@@ -1327,32 +1324,27 @@
|
|
|
1327
1324
|
* @param {Number} time the time to wait
|
|
1328
1325
|
* @return {Function} the debounced function
|
|
1329
1326
|
*/
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
1327
|
function debounce(fn, time) {
|
|
1333
1328
|
let timeoutId;
|
|
1334
|
-
|
|
1335
1329
|
function cancel() {
|
|
1336
1330
|
if (timeoutId) {
|
|
1337
1331
|
clearTimeout(timeoutId);
|
|
1338
1332
|
}
|
|
1339
1333
|
}
|
|
1340
|
-
|
|
1341
1334
|
function wrapper() {
|
|
1342
1335
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
1343
1336
|
args[_key] = arguments[_key];
|
|
1344
1337
|
}
|
|
1345
|
-
|
|
1346
1338
|
cancel();
|
|
1347
1339
|
timeoutId = setTimeout(() => {
|
|
1348
1340
|
timeoutId = null;
|
|
1349
1341
|
fn(...args);
|
|
1350
1342
|
}, time);
|
|
1351
1343
|
}
|
|
1352
|
-
|
|
1353
1344
|
wrapper.cancel = cancel;
|
|
1354
1345
|
return wrapper;
|
|
1355
1346
|
}
|
|
1347
|
+
|
|
1356
1348
|
/**
|
|
1357
1349
|
* This is intended to be used to compose event handlers.
|
|
1358
1350
|
* They are executed in order until one of them sets
|
|
@@ -1360,33 +1352,26 @@
|
|
|
1360
1352
|
* @param {...Function} fns the event handler functions
|
|
1361
1353
|
* @return {Function} the event handler to add to an element
|
|
1362
1354
|
*/
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
1355
|
function callAllEventHandlers() {
|
|
1366
1356
|
for (var _len2 = arguments.length, fns = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
|
|
1367
1357
|
fns[_key2] = arguments[_key2];
|
|
1368
1358
|
}
|
|
1369
|
-
|
|
1370
1359
|
return function (event) {
|
|
1371
1360
|
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
|
|
1372
1361
|
args[_key3 - 1] = arguments[_key3];
|
|
1373
1362
|
}
|
|
1374
|
-
|
|
1375
1363
|
return fns.some(fn => {
|
|
1376
1364
|
if (fn) {
|
|
1377
1365
|
fn(event, ...args);
|
|
1378
1366
|
}
|
|
1379
|
-
|
|
1380
1367
|
return event.preventDownshiftDefault || event.hasOwnProperty('nativeEvent') && event.nativeEvent.preventDownshiftDefault;
|
|
1381
1368
|
});
|
|
1382
1369
|
};
|
|
1383
1370
|
}
|
|
1384
|
-
|
|
1385
1371
|
function handleRefs() {
|
|
1386
1372
|
for (var _len4 = arguments.length, refs = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
|
|
1387
1373
|
refs[_key4] = arguments[_key4];
|
|
1388
1374
|
}
|
|
1389
|
-
|
|
1390
1375
|
return node => {
|
|
1391
1376
|
refs.forEach(ref => {
|
|
1392
1377
|
if (typeof ref === 'function') {
|
|
@@ -1397,23 +1382,22 @@
|
|
|
1397
1382
|
});
|
|
1398
1383
|
};
|
|
1399
1384
|
}
|
|
1385
|
+
|
|
1400
1386
|
/**
|
|
1401
1387
|
* This generates a unique ID for an instance of Downshift
|
|
1402
1388
|
* @return {String} the unique ID
|
|
1403
1389
|
*/
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
1390
|
function generateId() {
|
|
1407
1391
|
return String(idCounter++);
|
|
1408
1392
|
}
|
|
1393
|
+
|
|
1409
1394
|
/**
|
|
1410
1395
|
* Resets idCounter to 0. Used for SSR.
|
|
1411
1396
|
*/
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
1397
|
function resetIdCounter() {
|
|
1415
1398
|
idCounter = 0;
|
|
1416
1399
|
}
|
|
1400
|
+
|
|
1417
1401
|
/**
|
|
1418
1402
|
* Default implementation for status message. Only added when menu is open.
|
|
1419
1403
|
* Will specify if there are results in the list, and if so, how many,
|
|
@@ -1422,29 +1406,24 @@
|
|
|
1422
1406
|
* @param {Object} param the downshift state and other relevant properties
|
|
1423
1407
|
* @return {String} the a11y status message
|
|
1424
1408
|
*/
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
1409
|
function getA11yStatusMessage$1(_ref2) {
|
|
1428
1410
|
let {
|
|
1429
1411
|
isOpen,
|
|
1430
1412
|
resultCount,
|
|
1431
1413
|
previousResultCount
|
|
1432
1414
|
} = _ref2;
|
|
1433
|
-
|
|
1434
1415
|
if (!isOpen) {
|
|
1435
1416
|
return '';
|
|
1436
1417
|
}
|
|
1437
|
-
|
|
1438
1418
|
if (!resultCount) {
|
|
1439
1419
|
return 'No results are available.';
|
|
1440
1420
|
}
|
|
1441
|
-
|
|
1442
1421
|
if (resultCount !== previousResultCount) {
|
|
1443
1422
|
return `${resultCount} result${resultCount === 1 ? ' is' : 's are'} available, use up and down arrow keys to navigate. Press Enter key to select.`;
|
|
1444
1423
|
}
|
|
1445
|
-
|
|
1446
1424
|
return '';
|
|
1447
1425
|
}
|
|
1426
|
+
|
|
1448
1427
|
/**
|
|
1449
1428
|
* Takes an argument and if it's an array, returns the first item in the array
|
|
1450
1429
|
* otherwise returns the argument
|
|
@@ -1452,64 +1431,52 @@
|
|
|
1452
1431
|
* @param {*} defaultValue the value if arg is falsey not defined
|
|
1453
1432
|
* @return {*} the arg or it's first item
|
|
1454
1433
|
*/
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
1434
|
function unwrapArray(arg, defaultValue) {
|
|
1458
|
-
arg = Array.isArray(arg) ?
|
|
1459
|
-
/* istanbul ignore next (preact) */
|
|
1460
|
-
arg[0] : arg;
|
|
1461
|
-
|
|
1435
|
+
arg = Array.isArray(arg) ? /* istanbul ignore next (preact) */arg[0] : arg;
|
|
1462
1436
|
if (!arg && defaultValue) {
|
|
1463
1437
|
return defaultValue;
|
|
1464
1438
|
} else {
|
|
1465
1439
|
return arg;
|
|
1466
1440
|
}
|
|
1467
1441
|
}
|
|
1442
|
+
|
|
1468
1443
|
/**
|
|
1469
1444
|
* @param {Object} element (P)react element
|
|
1470
1445
|
* @return {Boolean} whether it's a DOM element
|
|
1471
1446
|
*/
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
1447
|
function isDOMElement(element) {
|
|
1475
1448
|
|
|
1476
|
-
|
|
1449
|
+
// then we assume this is react
|
|
1477
1450
|
return typeof element.type === 'string';
|
|
1478
1451
|
}
|
|
1452
|
+
|
|
1479
1453
|
/**
|
|
1480
1454
|
* @param {Object} element (P)react element
|
|
1481
1455
|
* @return {Object} the props
|
|
1482
1456
|
*/
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
1457
|
function getElementProps(element) {
|
|
1486
|
-
|
|
1487
1458
|
return element.props;
|
|
1488
1459
|
}
|
|
1460
|
+
|
|
1489
1461
|
/**
|
|
1490
1462
|
* Throws a helpful error message for required properties. Useful
|
|
1491
1463
|
* to be used as a default in destructuring or object params.
|
|
1492
1464
|
* @param {String} fnName the function name
|
|
1493
1465
|
* @param {String} propName the prop name
|
|
1494
1466
|
*/
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
1467
|
function requiredProp(fnName, propName) {
|
|
1498
1468
|
// eslint-disable-next-line no-console
|
|
1499
1469
|
console.error(`The property "${propName}" is required in "${fnName}"`);
|
|
1500
1470
|
}
|
|
1501
|
-
|
|
1502
1471
|
const stateKeys = ['highlightedIndex', 'inputValue', 'isOpen', 'selectedItem', 'type'];
|
|
1503
1472
|
/**
|
|
1504
1473
|
* @param {Object} state the state object
|
|
1505
1474
|
* @return {Object} state that is relevant to downshift
|
|
1506
1475
|
*/
|
|
1507
|
-
|
|
1508
1476
|
function pickState(state) {
|
|
1509
1477
|
if (state === void 0) {
|
|
1510
1478
|
state = {};
|
|
1511
1479
|
}
|
|
1512
|
-
|
|
1513
1480
|
const result = {};
|
|
1514
1481
|
stateKeys.forEach(k => {
|
|
1515
1482
|
if (state.hasOwnProperty(k)) {
|
|
@@ -1518,6 +1485,7 @@
|
|
|
1518
1485
|
});
|
|
1519
1486
|
return result;
|
|
1520
1487
|
}
|
|
1488
|
+
|
|
1521
1489
|
/**
|
|
1522
1490
|
* This will perform a shallow merge of the given state object
|
|
1523
1491
|
* with the state coming from props
|
|
@@ -1529,14 +1497,13 @@
|
|
|
1529
1497
|
* @param {Object} props The props that may contain controlled values.
|
|
1530
1498
|
* @returns {Object} The merged controlled state.
|
|
1531
1499
|
*/
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
1500
|
function getState(state, props) {
|
|
1535
1501
|
return Object.keys(state).reduce((prevState, key) => {
|
|
1536
1502
|
prevState[key] = isControlledProp(props, key) ? props[key] : state[key];
|
|
1537
1503
|
return prevState;
|
|
1538
1504
|
}, {});
|
|
1539
1505
|
}
|
|
1506
|
+
|
|
1540
1507
|
/**
|
|
1541
1508
|
* This determines whether a prop is a "controlled prop" meaning it is
|
|
1542
1509
|
* state which is controlled by the outside of this component rather
|
|
@@ -1546,41 +1513,36 @@
|
|
|
1546
1513
|
* @param {String} key the key to check
|
|
1547
1514
|
* @return {Boolean} whether it is a controlled controlled prop
|
|
1548
1515
|
*/
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
1516
|
function isControlledProp(props, key) {
|
|
1552
1517
|
return props[key] !== undefined;
|
|
1553
1518
|
}
|
|
1519
|
+
|
|
1554
1520
|
/**
|
|
1555
1521
|
* Normalizes the 'key' property of a KeyboardEvent in IE/Edge
|
|
1556
1522
|
* @param {Object} event a keyboardEvent object
|
|
1557
1523
|
* @return {String} keyboard key
|
|
1558
1524
|
*/
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
1525
|
function normalizeArrowKey(event) {
|
|
1562
1526
|
const {
|
|
1563
1527
|
key,
|
|
1564
1528
|
keyCode
|
|
1565
1529
|
} = event;
|
|
1566
1530
|
/* istanbul ignore next (ie) */
|
|
1567
|
-
|
|
1568
1531
|
if (keyCode >= 37 && keyCode <= 40 && key.indexOf('Arrow') !== 0) {
|
|
1569
1532
|
return `Arrow${key}`;
|
|
1570
1533
|
}
|
|
1571
|
-
|
|
1572
1534
|
return key;
|
|
1573
1535
|
}
|
|
1536
|
+
|
|
1574
1537
|
/**
|
|
1575
1538
|
* Simple check if the value passed is object literal
|
|
1576
1539
|
* @param {*} obj any things
|
|
1577
1540
|
* @return {Boolean} whether it's object literal
|
|
1578
1541
|
*/
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
1542
|
function isPlainObject(obj) {
|
|
1582
1543
|
return Object.prototype.toString.call(obj) === '[object Object]';
|
|
1583
1544
|
}
|
|
1545
|
+
|
|
1584
1546
|
/**
|
|
1585
1547
|
* Returns the new index in the list, in a circular way. If next value is out of bonds from the total,
|
|
1586
1548
|
* it will wrap to either 0 or itemCount - 1.
|
|
@@ -1592,39 +1554,30 @@
|
|
|
1592
1554
|
* @param {boolean} circular Specify if navigation is circular. Default is true.
|
|
1593
1555
|
* @returns {number} The new index after the move.
|
|
1594
1556
|
*/
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
1557
|
function getNextWrappingIndex(moveAmount, baseIndex, itemCount, getItemNodeFromIndex, circular) {
|
|
1598
1558
|
if (circular === void 0) {
|
|
1599
1559
|
circular = true;
|
|
1600
1560
|
}
|
|
1601
|
-
|
|
1602
1561
|
if (itemCount === 0) {
|
|
1603
1562
|
return -1;
|
|
1604
1563
|
}
|
|
1605
|
-
|
|
1606
1564
|
const itemsLastIndex = itemCount - 1;
|
|
1607
|
-
|
|
1608
1565
|
if (typeof baseIndex !== 'number' || baseIndex < 0 || baseIndex >= itemCount) {
|
|
1609
1566
|
baseIndex = moveAmount > 0 ? -1 : itemsLastIndex + 1;
|
|
1610
1567
|
}
|
|
1611
|
-
|
|
1612
1568
|
let newIndex = baseIndex + moveAmount;
|
|
1613
|
-
|
|
1614
1569
|
if (newIndex < 0) {
|
|
1615
1570
|
newIndex = circular ? itemsLastIndex : 0;
|
|
1616
1571
|
} else if (newIndex > itemsLastIndex) {
|
|
1617
1572
|
newIndex = circular ? 0 : itemsLastIndex;
|
|
1618
1573
|
}
|
|
1619
|
-
|
|
1620
1574
|
const nonDisabledNewIndex = getNextNonDisabledIndex(moveAmount, newIndex, itemCount, getItemNodeFromIndex, circular);
|
|
1621
|
-
|
|
1622
1575
|
if (nonDisabledNewIndex === -1) {
|
|
1623
1576
|
return baseIndex >= itemCount ? -1 : baseIndex;
|
|
1624
1577
|
}
|
|
1625
|
-
|
|
1626
1578
|
return nonDisabledNewIndex;
|
|
1627
1579
|
}
|
|
1580
|
+
|
|
1628
1581
|
/**
|
|
1629
1582
|
* Returns the next index in the list of an item that is not disabled.
|
|
1630
1583
|
*
|
|
@@ -1635,15 +1588,11 @@
|
|
|
1635
1588
|
* @param {boolean} circular Specify if navigation is circular. Default is true.
|
|
1636
1589
|
* @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.
|
|
1637
1590
|
*/
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
1591
|
function getNextNonDisabledIndex(moveAmount, baseIndex, itemCount, getItemNodeFromIndex, circular) {
|
|
1641
1592
|
const currentElementNode = getItemNodeFromIndex(baseIndex);
|
|
1642
|
-
|
|
1643
1593
|
if (!currentElementNode || !currentElementNode.hasAttribute('disabled')) {
|
|
1644
1594
|
return baseIndex;
|
|
1645
1595
|
}
|
|
1646
|
-
|
|
1647
1596
|
if (moveAmount > 0) {
|
|
1648
1597
|
for (let index = baseIndex + 1; index < itemCount; index++) {
|
|
1649
1598
|
if (!getItemNodeFromIndex(index).hasAttribute('disabled')) {
|
|
@@ -1657,13 +1606,12 @@
|
|
|
1657
1606
|
}
|
|
1658
1607
|
}
|
|
1659
1608
|
}
|
|
1660
|
-
|
|
1661
1609
|
if (circular) {
|
|
1662
1610
|
return moveAmount > 0 ? getNextNonDisabledIndex(1, 0, itemCount, getItemNodeFromIndex, false) : getNextNonDisabledIndex(-1, itemCount - 1, itemCount, getItemNodeFromIndex, false);
|
|
1663
1611
|
}
|
|
1664
|
-
|
|
1665
1612
|
return -1;
|
|
1666
1613
|
}
|
|
1614
|
+
|
|
1667
1615
|
/**
|
|
1668
1616
|
* Checks if event target is within the downshift elements.
|
|
1669
1617
|
*
|
|
@@ -1674,20 +1622,16 @@
|
|
|
1674
1622
|
*
|
|
1675
1623
|
* @returns {boolean} Whether or not the target is within downshift elements.
|
|
1676
1624
|
*/
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
1625
|
function targetWithinDownshift(target, downshiftElements, environment, checkActiveElement) {
|
|
1680
1626
|
if (checkActiveElement === void 0) {
|
|
1681
1627
|
checkActiveElement = true;
|
|
1682
1628
|
}
|
|
1683
|
-
|
|
1684
1629
|
return downshiftElements.some(contextNode => contextNode && (isOrContainsNode(contextNode, target, environment) || checkActiveElement && isOrContainsNode(contextNode, environment.document.activeElement, environment)));
|
|
1685
|
-
}
|
|
1686
|
-
|
|
1630
|
+
}
|
|
1687
1631
|
|
|
1632
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
1688
1633
|
let validateControlledUnchanged = noop;
|
|
1689
1634
|
/* istanbul ignore next */
|
|
1690
|
-
|
|
1691
1635
|
{
|
|
1692
1636
|
validateControlledUnchanged = (state, prevProps, nextProps) => {
|
|
1693
1637
|
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`;
|
|
@@ -1706,39 +1650,33 @@
|
|
|
1706
1650
|
const cleanupStatus = debounce(documentProp => {
|
|
1707
1651
|
getStatusDiv(documentProp).textContent = '';
|
|
1708
1652
|
}, 500);
|
|
1653
|
+
|
|
1709
1654
|
/**
|
|
1710
1655
|
* @param {String} status the status message
|
|
1711
1656
|
* @param {Object} documentProp document passed by the user.
|
|
1712
1657
|
*/
|
|
1713
|
-
|
|
1714
1658
|
function setStatus(status, documentProp) {
|
|
1715
1659
|
const div = getStatusDiv(documentProp);
|
|
1716
|
-
|
|
1717
1660
|
if (!status) {
|
|
1718
1661
|
return;
|
|
1719
1662
|
}
|
|
1720
|
-
|
|
1721
1663
|
div.textContent = status;
|
|
1722
1664
|
cleanupStatus(documentProp);
|
|
1723
1665
|
}
|
|
1666
|
+
|
|
1724
1667
|
/**
|
|
1725
1668
|
* Get the status node or create it if it does not already exist.
|
|
1726
1669
|
* @param {Object} documentProp document passed by the user.
|
|
1727
1670
|
* @return {HTMLElement} the status node.
|
|
1728
1671
|
*/
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
1672
|
function getStatusDiv(documentProp) {
|
|
1732
1673
|
if (documentProp === void 0) {
|
|
1733
1674
|
documentProp = document;
|
|
1734
1675
|
}
|
|
1735
|
-
|
|
1736
1676
|
let statusDiv = documentProp.getElementById('a11y-status-message');
|
|
1737
|
-
|
|
1738
1677
|
if (statusDiv) {
|
|
1739
1678
|
return statusDiv;
|
|
1740
1679
|
}
|
|
1741
|
-
|
|
1742
1680
|
statusDiv = documentProp.createElement('div');
|
|
1743
1681
|
statusDiv.setAttribute('id', 'a11y-status-message');
|
|
1744
1682
|
statusDiv.setAttribute('role', 'status');
|
|
@@ -1798,27 +1736,22 @@
|
|
|
1798
1736
|
});
|
|
1799
1737
|
|
|
1800
1738
|
/* eslint camelcase:0 */
|
|
1801
|
-
|
|
1802
1739
|
const Downshift = /*#__PURE__*/(() => {
|
|
1803
1740
|
class Downshift extends react.Component {
|
|
1804
1741
|
constructor(_props) {
|
|
1805
1742
|
var _this;
|
|
1806
|
-
|
|
1807
1743
|
super(_props);
|
|
1808
1744
|
_this = this;
|
|
1809
1745
|
this.id = this.props.id || `downshift-${generateId()}`;
|
|
1810
1746
|
this.menuId = this.props.menuId || `${this.id}-menu`;
|
|
1811
1747
|
this.labelId = this.props.labelId || `${this.id}-label`;
|
|
1812
1748
|
this.inputId = this.props.inputId || `${this.id}-input`;
|
|
1813
|
-
|
|
1814
1749
|
this.getItemId = this.props.getItemId || (index => `${this.id}-item-${index}`);
|
|
1815
|
-
|
|
1816
1750
|
this.input = null;
|
|
1817
1751
|
this.items = [];
|
|
1818
1752
|
this.itemCount = null;
|
|
1819
1753
|
this.previousResultCount = 0;
|
|
1820
1754
|
this.timeoutIds = [];
|
|
1821
|
-
|
|
1822
1755
|
this.internalSetTimeout = (fn, time) => {
|
|
1823
1756
|
const id = setTimeout(() => {
|
|
1824
1757
|
this.timeoutIds = this.timeoutIds.filter(i => i !== id);
|
|
@@ -1826,32 +1759,25 @@
|
|
|
1826
1759
|
}, time);
|
|
1827
1760
|
this.timeoutIds.push(id);
|
|
1828
1761
|
};
|
|
1829
|
-
|
|
1830
1762
|
this.setItemCount = count => {
|
|
1831
1763
|
this.itemCount = count;
|
|
1832
1764
|
};
|
|
1833
|
-
|
|
1834
1765
|
this.unsetItemCount = () => {
|
|
1835
1766
|
this.itemCount = null;
|
|
1836
1767
|
};
|
|
1837
|
-
|
|
1838
1768
|
this.setHighlightedIndex = function (highlightedIndex, otherStateToSet) {
|
|
1839
1769
|
if (highlightedIndex === void 0) {
|
|
1840
1770
|
highlightedIndex = _this.props.defaultHighlightedIndex;
|
|
1841
1771
|
}
|
|
1842
|
-
|
|
1843
1772
|
if (otherStateToSet === void 0) {
|
|
1844
1773
|
otherStateToSet = {};
|
|
1845
1774
|
}
|
|
1846
|
-
|
|
1847
1775
|
otherStateToSet = pickState(otherStateToSet);
|
|
1848
|
-
|
|
1849
1776
|
_this.internalSetState({
|
|
1850
1777
|
highlightedIndex,
|
|
1851
1778
|
...otherStateToSet
|
|
1852
1779
|
});
|
|
1853
1780
|
};
|
|
1854
|
-
|
|
1855
1781
|
this.clearSelection = cb => {
|
|
1856
1782
|
this.internalSetState({
|
|
1857
1783
|
selectedItem: null,
|
|
@@ -1860,7 +1786,6 @@
|
|
|
1860
1786
|
isOpen: this.props.defaultIsOpen
|
|
1861
1787
|
}, cb);
|
|
1862
1788
|
};
|
|
1863
|
-
|
|
1864
1789
|
this.selectItem = (item, otherStateToSet, cb) => {
|
|
1865
1790
|
otherStateToSet = pickState(otherStateToSet);
|
|
1866
1791
|
this.internalSetState({
|
|
@@ -1871,114 +1796,105 @@
|
|
|
1871
1796
|
...otherStateToSet
|
|
1872
1797
|
}, cb);
|
|
1873
1798
|
};
|
|
1874
|
-
|
|
1875
1799
|
this.selectItemAtIndex = (itemIndex, otherStateToSet, cb) => {
|
|
1876
1800
|
const item = this.items[itemIndex];
|
|
1877
|
-
|
|
1878
1801
|
if (item == null) {
|
|
1879
1802
|
return;
|
|
1880
1803
|
}
|
|
1881
|
-
|
|
1882
1804
|
this.selectItem(item, otherStateToSet, cb);
|
|
1883
1805
|
};
|
|
1884
|
-
|
|
1885
1806
|
this.selectHighlightedItem = (otherStateToSet, cb) => {
|
|
1886
1807
|
return this.selectItemAtIndex(this.getState().highlightedIndex, otherStateToSet, cb);
|
|
1887
1808
|
};
|
|
1888
|
-
|
|
1889
1809
|
this.internalSetState = (stateToSet, cb) => {
|
|
1890
1810
|
let isItemSelected, onChangeArg;
|
|
1891
1811
|
const onStateChangeArg = {};
|
|
1892
|
-
const isStateToSetFunction = typeof stateToSet === 'function';
|
|
1812
|
+
const isStateToSetFunction = typeof stateToSet === 'function';
|
|
1813
|
+
|
|
1814
|
+
// we want to call `onInputValueChange` before the `setState` call
|
|
1893
1815
|
// so someone controlling the `inputValue` state gets notified of
|
|
1894
1816
|
// the input change as soon as possible. This avoids issues with
|
|
1895
1817
|
// preserving the cursor position.
|
|
1896
1818
|
// See https://github.com/downshift-js/downshift/issues/217 for more info.
|
|
1897
|
-
|
|
1898
1819
|
if (!isStateToSetFunction && stateToSet.hasOwnProperty('inputValue')) {
|
|
1899
|
-
this.props.onInputValueChange(stateToSet.inputValue, {
|
|
1820
|
+
this.props.onInputValueChange(stateToSet.inputValue, {
|
|
1821
|
+
...this.getStateAndHelpers(),
|
|
1900
1822
|
...stateToSet
|
|
1901
1823
|
});
|
|
1902
1824
|
}
|
|
1903
|
-
|
|
1904
1825
|
return this.setState(state => {
|
|
1905
1826
|
state = this.getState(state);
|
|
1906
|
-
let newStateToSet = isStateToSetFunction ? stateToSet(state) : stateToSet;
|
|
1827
|
+
let newStateToSet = isStateToSetFunction ? stateToSet(state) : stateToSet;
|
|
1828
|
+
|
|
1829
|
+
// Your own function that could modify the state that will be set.
|
|
1830
|
+
newStateToSet = this.props.stateReducer(state, newStateToSet);
|
|
1907
1831
|
|
|
1908
|
-
|
|
1832
|
+
// checks if an item is selected, regardless of if it's different from
|
|
1909
1833
|
// what was selected before
|
|
1910
1834
|
// used to determine if onSelect and onChange callbacks should be called
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1835
|
+
isItemSelected = newStateToSet.hasOwnProperty('selectedItem');
|
|
1836
|
+
// this keeps track of the object we want to call with setState
|
|
1837
|
+
const nextState = {};
|
|
1838
|
+
// we need to call on change if the outside world is controlling any of our state
|
|
1915
1839
|
// and we're trying to update that state. OR if the selection has changed and we're
|
|
1916
1840
|
// trying to update the selection
|
|
1917
|
-
|
|
1918
1841
|
if (isItemSelected && newStateToSet.selectedItem !== state.selectedItem) {
|
|
1919
1842
|
onChangeArg = newStateToSet.selectedItem;
|
|
1920
1843
|
}
|
|
1921
|
-
|
|
1922
1844
|
newStateToSet.type = newStateToSet.type || unknown;
|
|
1923
1845
|
Object.keys(newStateToSet).forEach(key => {
|
|
1924
1846
|
// onStateChangeArg should only have the state that is
|
|
1925
1847
|
// actually changing
|
|
1926
1848
|
if (state[key] !== newStateToSet[key]) {
|
|
1927
1849
|
onStateChangeArg[key] = newStateToSet[key];
|
|
1928
|
-
}
|
|
1850
|
+
}
|
|
1851
|
+
// the type is useful for the onStateChangeArg
|
|
1929
1852
|
// but we don't actually want to set it in internal state.
|
|
1930
1853
|
// this is an undocumented feature for now... Not all internalSetState
|
|
1931
1854
|
// calls support it and I'm not certain we want them to yet.
|
|
1932
1855
|
// But it enables users controlling the isOpen state to know when
|
|
1933
1856
|
// the isOpen state changes due to mouseup events which is quite handy.
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
1857
|
if (key === 'type') {
|
|
1937
1858
|
return;
|
|
1938
1859
|
}
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1860
|
+
newStateToSet[key];
|
|
1861
|
+
// if it's coming from props, then we don't care to set it internally
|
|
1942
1862
|
if (!isControlledProp(this.props, key)) {
|
|
1943
1863
|
nextState[key] = newStateToSet[key];
|
|
1944
1864
|
}
|
|
1945
|
-
});
|
|
1946
|
-
// earlier, so we'll call it now that we know what the inputValue state will be.
|
|
1865
|
+
});
|
|
1947
1866
|
|
|
1867
|
+
// if stateToSet is a function, then we weren't able to call onInputValueChange
|
|
1868
|
+
// earlier, so we'll call it now that we know what the inputValue state will be.
|
|
1948
1869
|
if (isStateToSetFunction && newStateToSet.hasOwnProperty('inputValue')) {
|
|
1949
|
-
this.props.onInputValueChange(newStateToSet.inputValue, {
|
|
1870
|
+
this.props.onInputValueChange(newStateToSet.inputValue, {
|
|
1871
|
+
...this.getStateAndHelpers(),
|
|
1950
1872
|
...newStateToSet
|
|
1951
1873
|
});
|
|
1952
1874
|
}
|
|
1953
|
-
|
|
1954
1875
|
return nextState;
|
|
1955
1876
|
}, () => {
|
|
1956
1877
|
// call the provided callback if it's a function
|
|
1957
|
-
cbToCb(cb)();
|
|
1958
|
-
// we have relevant information to pass them.
|
|
1878
|
+
cbToCb(cb)();
|
|
1959
1879
|
|
|
1880
|
+
// only call the onStateChange and onChange callbacks if
|
|
1881
|
+
// we have relevant information to pass them.
|
|
1960
1882
|
const hasMoreStateThanType = Object.keys(onStateChangeArg).length > 1;
|
|
1961
|
-
|
|
1962
1883
|
if (hasMoreStateThanType) {
|
|
1963
1884
|
this.props.onStateChange(onStateChangeArg, this.getStateAndHelpers());
|
|
1964
1885
|
}
|
|
1965
|
-
|
|
1966
1886
|
if (isItemSelected) {
|
|
1967
1887
|
this.props.onSelect(stateToSet.selectedItem, this.getStateAndHelpers());
|
|
1968
1888
|
}
|
|
1969
|
-
|
|
1970
1889
|
if (onChangeArg !== undefined) {
|
|
1971
1890
|
this.props.onChange(onChangeArg, this.getStateAndHelpers());
|
|
1972
|
-
}
|
|
1891
|
+
}
|
|
1892
|
+
// this is currently undocumented and therefore subject to change
|
|
1973
1893
|
// We'll try to not break it, but just be warned.
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
1894
|
this.props.onUserAction(onStateChangeArg, this.getStateAndHelpers());
|
|
1977
1895
|
});
|
|
1978
1896
|
};
|
|
1979
|
-
|
|
1980
1897
|
this.rootRef = node => this._rootNode = node;
|
|
1981
|
-
|
|
1982
1898
|
this.getRootProps = function (_temp, _temp2) {
|
|
1983
1899
|
let {
|
|
1984
1900
|
refKey = 'ref',
|
|
@@ -1993,11 +1909,9 @@
|
|
|
1993
1909
|
_this.getRootProps.called = true;
|
|
1994
1910
|
_this.getRootProps.refKey = refKey;
|
|
1995
1911
|
_this.getRootProps.suppressRefError = suppressRefError;
|
|
1996
|
-
|
|
1997
1912
|
const {
|
|
1998
1913
|
isOpen
|
|
1999
1914
|
} = _this.getState();
|
|
2000
|
-
|
|
2001
1915
|
return {
|
|
2002
1916
|
[refKey]: handleRefs(ref, _this.rootRef),
|
|
2003
1917
|
role: 'combobox',
|
|
@@ -2008,11 +1922,9 @@
|
|
|
2008
1922
|
...rest
|
|
2009
1923
|
};
|
|
2010
1924
|
};
|
|
2011
|
-
|
|
2012
1925
|
this.keyDownHandlers = {
|
|
2013
1926
|
ArrowDown(event) {
|
|
2014
1927
|
event.preventDefault();
|
|
2015
|
-
|
|
2016
1928
|
if (this.getState().isOpen) {
|
|
2017
1929
|
const amount = event.shiftKey ? 5 : 1;
|
|
2018
1930
|
this.moveHighlightedIndex(amount, {
|
|
@@ -2024,7 +1936,6 @@
|
|
|
2024
1936
|
type: keyDownArrowDown
|
|
2025
1937
|
}, () => {
|
|
2026
1938
|
const itemCount = this.getItemCount();
|
|
2027
|
-
|
|
2028
1939
|
if (itemCount > 0) {
|
|
2029
1940
|
const {
|
|
2030
1941
|
highlightedIndex
|
|
@@ -2037,10 +1948,8 @@
|
|
|
2037
1948
|
});
|
|
2038
1949
|
}
|
|
2039
1950
|
},
|
|
2040
|
-
|
|
2041
1951
|
ArrowUp(event) {
|
|
2042
1952
|
event.preventDefault();
|
|
2043
|
-
|
|
2044
1953
|
if (this.getState().isOpen) {
|
|
2045
1954
|
const amount = event.shiftKey ? -5 : -1;
|
|
2046
1955
|
this.moveHighlightedIndex(amount, {
|
|
@@ -2052,7 +1961,6 @@
|
|
|
2052
1961
|
type: keyDownArrowUp
|
|
2053
1962
|
}, () => {
|
|
2054
1963
|
const itemCount = this.getItemCount();
|
|
2055
|
-
|
|
2056
1964
|
if (itemCount > 0) {
|
|
2057
1965
|
const {
|
|
2058
1966
|
highlightedIndex
|
|
@@ -2065,32 +1973,26 @@
|
|
|
2065
1973
|
});
|
|
2066
1974
|
}
|
|
2067
1975
|
},
|
|
2068
|
-
|
|
2069
1976
|
Enter(event) {
|
|
2070
1977
|
if (event.which === 229) {
|
|
2071
1978
|
return;
|
|
2072
1979
|
}
|
|
2073
|
-
|
|
2074
1980
|
const {
|
|
2075
1981
|
isOpen,
|
|
2076
1982
|
highlightedIndex
|
|
2077
1983
|
} = this.getState();
|
|
2078
|
-
|
|
2079
1984
|
if (isOpen && highlightedIndex != null) {
|
|
2080
1985
|
event.preventDefault();
|
|
2081
1986
|
const item = this.items[highlightedIndex];
|
|
2082
1987
|
const itemNode = this.getItemNodeFromIndex(highlightedIndex);
|
|
2083
|
-
|
|
2084
1988
|
if (item == null || itemNode && itemNode.hasAttribute('disabled')) {
|
|
2085
1989
|
return;
|
|
2086
1990
|
}
|
|
2087
|
-
|
|
2088
1991
|
this.selectHighlightedItem({
|
|
2089
1992
|
type: keyDownEnter
|
|
2090
1993
|
});
|
|
2091
1994
|
}
|
|
2092
1995
|
},
|
|
2093
|
-
|
|
2094
1996
|
Escape(event) {
|
|
2095
1997
|
event.preventDefault();
|
|
2096
1998
|
this.reset({
|
|
@@ -2101,68 +2003,57 @@
|
|
|
2101
2003
|
})
|
|
2102
2004
|
});
|
|
2103
2005
|
}
|
|
2104
|
-
|
|
2105
2006
|
};
|
|
2106
|
-
this.buttonKeyDownHandlers = {
|
|
2107
|
-
|
|
2007
|
+
this.buttonKeyDownHandlers = {
|
|
2008
|
+
...this.keyDownHandlers,
|
|
2108
2009
|
' '(event) {
|
|
2109
2010
|
event.preventDefault();
|
|
2110
2011
|
this.toggleMenu({
|
|
2111
2012
|
type: keyDownSpaceButton
|
|
2112
2013
|
});
|
|
2113
2014
|
}
|
|
2114
|
-
|
|
2115
2015
|
};
|
|
2116
|
-
this.inputKeyDownHandlers = {
|
|
2117
|
-
|
|
2016
|
+
this.inputKeyDownHandlers = {
|
|
2017
|
+
...this.keyDownHandlers,
|
|
2118
2018
|
Home(event) {
|
|
2119
2019
|
const {
|
|
2120
2020
|
isOpen
|
|
2121
2021
|
} = this.getState();
|
|
2122
|
-
|
|
2123
2022
|
if (!isOpen) {
|
|
2124
2023
|
return;
|
|
2125
2024
|
}
|
|
2126
|
-
|
|
2127
2025
|
event.preventDefault();
|
|
2128
2026
|
const itemCount = this.getItemCount();
|
|
2129
|
-
|
|
2130
2027
|
if (itemCount <= 0 || !isOpen) {
|
|
2131
2028
|
return;
|
|
2132
|
-
}
|
|
2133
|
-
|
|
2029
|
+
}
|
|
2134
2030
|
|
|
2031
|
+
// get next non-disabled starting downwards from 0 if that's disabled.
|
|
2135
2032
|
const newHighlightedIndex = getNextNonDisabledIndex(1, 0, itemCount, index => this.getItemNodeFromIndex(index), false);
|
|
2136
2033
|
this.setHighlightedIndex(newHighlightedIndex, {
|
|
2137
2034
|
type: keyDownHome
|
|
2138
2035
|
});
|
|
2139
2036
|
},
|
|
2140
|
-
|
|
2141
2037
|
End(event) {
|
|
2142
2038
|
const {
|
|
2143
2039
|
isOpen
|
|
2144
2040
|
} = this.getState();
|
|
2145
|
-
|
|
2146
2041
|
if (!isOpen) {
|
|
2147
2042
|
return;
|
|
2148
2043
|
}
|
|
2149
|
-
|
|
2150
2044
|
event.preventDefault();
|
|
2151
2045
|
const itemCount = this.getItemCount();
|
|
2152
|
-
|
|
2153
2046
|
if (itemCount <= 0 || !isOpen) {
|
|
2154
2047
|
return;
|
|
2155
|
-
}
|
|
2156
|
-
|
|
2048
|
+
}
|
|
2157
2049
|
|
|
2050
|
+
// get next non-disabled starting upwards from last index if that's disabled.
|
|
2158
2051
|
const newHighlightedIndex = getNextNonDisabledIndex(-1, itemCount - 1, itemCount, index => this.getItemNodeFromIndex(index), false);
|
|
2159
2052
|
this.setHighlightedIndex(newHighlightedIndex, {
|
|
2160
2053
|
type: keyDownEnd
|
|
2161
2054
|
});
|
|
2162
2055
|
}
|
|
2163
|
-
|
|
2164
2056
|
};
|
|
2165
|
-
|
|
2166
2057
|
this.getToggleButtonProps = function (_temp3) {
|
|
2167
2058
|
let {
|
|
2168
2059
|
onClick,
|
|
@@ -2172,11 +2063,9 @@
|
|
|
2172
2063
|
onBlur,
|
|
2173
2064
|
...rest
|
|
2174
2065
|
} = _temp3 === void 0 ? {} : _temp3;
|
|
2175
|
-
|
|
2176
2066
|
const {
|
|
2177
2067
|
isOpen
|
|
2178
2068
|
} = _this.getState();
|
|
2179
|
-
|
|
2180
2069
|
const enabledEventHandlers = {
|
|
2181
2070
|
onClick: callAllEventHandlers(onClick, _this.buttonHandleClick),
|
|
2182
2071
|
onKeyDown: callAllEventHandlers(onKeyDown, _this.buttonHandleKeyDown),
|
|
@@ -2194,33 +2083,27 @@
|
|
|
2194
2083
|
...rest
|
|
2195
2084
|
};
|
|
2196
2085
|
};
|
|
2197
|
-
|
|
2198
2086
|
this.buttonHandleKeyUp = event => {
|
|
2199
2087
|
// Prevent click event from emitting in Firefox
|
|
2200
2088
|
event.preventDefault();
|
|
2201
2089
|
};
|
|
2202
|
-
|
|
2203
2090
|
this.buttonHandleKeyDown = event => {
|
|
2204
2091
|
const key = normalizeArrowKey(event);
|
|
2205
|
-
|
|
2206
2092
|
if (this.buttonKeyDownHandlers[key]) {
|
|
2207
2093
|
this.buttonKeyDownHandlers[key].call(this, event);
|
|
2208
2094
|
}
|
|
2209
2095
|
};
|
|
2210
|
-
|
|
2211
2096
|
this.buttonHandleClick = event => {
|
|
2212
|
-
event.preventDefault();
|
|
2097
|
+
event.preventDefault();
|
|
2098
|
+
// handle odd case for Safari and Firefox which
|
|
2213
2099
|
// don't give the button the focus properly.
|
|
2214
|
-
|
|
2215
2100
|
/* istanbul ignore if (can't reasonably test this) */
|
|
2216
|
-
|
|
2217
2101
|
if (this.props.environment.document.activeElement === this.props.environment.document.body) {
|
|
2218
2102
|
event.target.focus();
|
|
2219
|
-
}
|
|
2103
|
+
}
|
|
2104
|
+
// to simplify testing components that use downshift, we'll not wrap this in a setTimeout
|
|
2220
2105
|
// if the NODE_ENV is test. With the proper build system, this should be dead code eliminated
|
|
2221
2106
|
// when building for production and should therefore have no impact on production code.
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
2107
|
{
|
|
2225
2108
|
// Ensure that toggle of menu occurs after the potential blur event in iOS
|
|
2226
2109
|
this.internalSetTimeout(() => this.toggleMenu({
|
|
@@ -2228,11 +2111,9 @@
|
|
|
2228
2111
|
}));
|
|
2229
2112
|
}
|
|
2230
2113
|
};
|
|
2231
|
-
|
|
2232
2114
|
this.buttonHandleBlur = event => {
|
|
2233
2115
|
const blurTarget = event.target; // Save blur target for comparison with activeElement later
|
|
2234
2116
|
// Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not body element
|
|
2235
|
-
|
|
2236
2117
|
this.internalSetTimeout(() => {
|
|
2237
2118
|
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)
|
|
2238
2119
|
) {
|
|
@@ -2242,7 +2123,6 @@
|
|
|
2242
2123
|
}
|
|
2243
2124
|
});
|
|
2244
2125
|
};
|
|
2245
|
-
|
|
2246
2126
|
this.getLabelProps = props => {
|
|
2247
2127
|
return {
|
|
2248
2128
|
htmlFor: this.inputId,
|
|
@@ -2250,7 +2130,6 @@
|
|
|
2250
2130
|
...props
|
|
2251
2131
|
};
|
|
2252
2132
|
};
|
|
2253
|
-
|
|
2254
2133
|
this.getInputProps = function (_temp4) {
|
|
2255
2134
|
let {
|
|
2256
2135
|
onKeyDown,
|
|
@@ -2262,18 +2141,16 @@
|
|
|
2262
2141
|
} = _temp4 === void 0 ? {} : _temp4;
|
|
2263
2142
|
let onChangeKey;
|
|
2264
2143
|
let eventHandlers = {};
|
|
2265
|
-
/* istanbul ignore next (preact) */
|
|
2266
2144
|
|
|
2145
|
+
/* istanbul ignore next (preact) */
|
|
2267
2146
|
{
|
|
2268
2147
|
onChangeKey = 'onChange';
|
|
2269
2148
|
}
|
|
2270
|
-
|
|
2271
2149
|
const {
|
|
2272
2150
|
inputValue,
|
|
2273
2151
|
isOpen,
|
|
2274
2152
|
highlightedIndex
|
|
2275
2153
|
} = _this.getState();
|
|
2276
|
-
|
|
2277
2154
|
if (!rest.disabled) {
|
|
2278
2155
|
eventHandlers = {
|
|
2279
2156
|
[onChangeKey]: callAllEventHandlers(onChange, onInput, _this.inputHandleChange),
|
|
@@ -2281,7 +2158,6 @@
|
|
|
2281
2158
|
onBlur: callAllEventHandlers(onBlur, _this.inputHandleBlur)
|
|
2282
2159
|
};
|
|
2283
2160
|
}
|
|
2284
|
-
|
|
2285
2161
|
return {
|
|
2286
2162
|
'aria-autocomplete': 'list',
|
|
2287
2163
|
'aria-activedescendant': isOpen && typeof highlightedIndex === 'number' && highlightedIndex >= 0 ? _this.getItemId(highlightedIndex) : null,
|
|
@@ -2296,15 +2172,12 @@
|
|
|
2296
2172
|
...rest
|
|
2297
2173
|
};
|
|
2298
2174
|
};
|
|
2299
|
-
|
|
2300
2175
|
this.inputHandleKeyDown = event => {
|
|
2301
2176
|
const key = normalizeArrowKey(event);
|
|
2302
|
-
|
|
2303
2177
|
if (key && this.inputKeyDownHandlers[key]) {
|
|
2304
2178
|
this.inputKeyDownHandlers[key].call(this, event);
|
|
2305
2179
|
}
|
|
2306
2180
|
};
|
|
2307
|
-
|
|
2308
2181
|
this.inputHandleChange = event => {
|
|
2309
2182
|
this.internalSetState({
|
|
2310
2183
|
type: changeInput,
|
|
@@ -2313,12 +2186,10 @@
|
|
|
2313
2186
|
highlightedIndex: this.props.defaultHighlightedIndex
|
|
2314
2187
|
});
|
|
2315
2188
|
};
|
|
2316
|
-
|
|
2317
2189
|
this.inputHandleBlur = () => {
|
|
2318
2190
|
// Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not the body element
|
|
2319
2191
|
this.internalSetTimeout(() => {
|
|
2320
2192
|
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);
|
|
2321
|
-
|
|
2322
2193
|
if (!this.isMouseDown && !downshiftButtonIsActive) {
|
|
2323
2194
|
this.reset({
|
|
2324
2195
|
type: blurInput
|
|
@@ -2326,11 +2197,9 @@
|
|
|
2326
2197
|
}
|
|
2327
2198
|
});
|
|
2328
2199
|
};
|
|
2329
|
-
|
|
2330
2200
|
this.menuRef = node => {
|
|
2331
2201
|
this._menuNode = node;
|
|
2332
2202
|
};
|
|
2333
|
-
|
|
2334
2203
|
this.getMenuProps = function (_temp5, _temp6) {
|
|
2335
2204
|
let {
|
|
2336
2205
|
refKey = 'ref',
|
|
@@ -2351,7 +2220,6 @@
|
|
|
2351
2220
|
...props
|
|
2352
2221
|
};
|
|
2353
2222
|
};
|
|
2354
|
-
|
|
2355
2223
|
this.getItemProps = function (_temp7) {
|
|
2356
2224
|
let {
|
|
2357
2225
|
onMouseMove,
|
|
@@ -2362,15 +2230,12 @@
|
|
|
2362
2230
|
item = requiredProp('getItemProps', 'item'),
|
|
2363
2231
|
...rest
|
|
2364
2232
|
} = _temp7 === void 0 ? {} : _temp7;
|
|
2365
|
-
|
|
2366
2233
|
if (index === undefined) {
|
|
2367
2234
|
_this.items.push(item);
|
|
2368
|
-
|
|
2369
2235
|
index = _this.items.indexOf(item);
|
|
2370
2236
|
} else {
|
|
2371
2237
|
_this.items[index] = item;
|
|
2372
2238
|
}
|
|
2373
|
-
|
|
2374
2239
|
const onSelectKey = 'onClick';
|
|
2375
2240
|
const customClickHandler = onClick;
|
|
2376
2241
|
const enabledEventHandlers = {
|
|
@@ -2381,17 +2246,15 @@
|
|
|
2381
2246
|
if (index === _this.getState().highlightedIndex) {
|
|
2382
2247
|
return;
|
|
2383
2248
|
}
|
|
2384
|
-
|
|
2385
2249
|
_this.setHighlightedIndex(index, {
|
|
2386
2250
|
type: itemMouseEnter
|
|
2387
|
-
});
|
|
2251
|
+
});
|
|
2252
|
+
|
|
2253
|
+
// We never want to manually scroll when changing state based
|
|
2388
2254
|
// on `onMouseMove` because we will be moving the element out
|
|
2389
2255
|
// from under the user which is currently scrolling/moving the
|
|
2390
2256
|
// cursor
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
2257
|
_this.avoidScrolling = true;
|
|
2394
|
-
|
|
2395
2258
|
_this.internalSetTimeout(() => _this.avoidScrolling = false, 250);
|
|
2396
2259
|
}),
|
|
2397
2260
|
onMouseDown: callAllEventHandlers(onMouseDown, event => {
|
|
@@ -2405,9 +2268,10 @@
|
|
|
2405
2268
|
type: clickItem
|
|
2406
2269
|
});
|
|
2407
2270
|
})
|
|
2408
|
-
};
|
|
2409
|
-
// of the activeElement if clicking on disabled items
|
|
2271
|
+
};
|
|
2410
2272
|
|
|
2273
|
+
// Passing down the onMouseDown handler to prevent redirect
|
|
2274
|
+
// of the activeElement if clicking on disabled items
|
|
2411
2275
|
const eventHandlers = rest.disabled ? {
|
|
2412
2276
|
onMouseDown: enabledEventHandlers.onMouseDown
|
|
2413
2277
|
} : enabledEventHandlers;
|
|
@@ -2419,18 +2283,14 @@
|
|
|
2419
2283
|
...rest
|
|
2420
2284
|
};
|
|
2421
2285
|
};
|
|
2422
|
-
|
|
2423
2286
|
this.clearItems = () => {
|
|
2424
2287
|
this.items = [];
|
|
2425
2288
|
};
|
|
2426
|
-
|
|
2427
2289
|
this.reset = function (otherStateToSet, cb) {
|
|
2428
2290
|
if (otherStateToSet === void 0) {
|
|
2429
2291
|
otherStateToSet = {};
|
|
2430
2292
|
}
|
|
2431
|
-
|
|
2432
2293
|
otherStateToSet = pickState(otherStateToSet);
|
|
2433
|
-
|
|
2434
2294
|
_this.internalSetState(_ref => {
|
|
2435
2295
|
let {
|
|
2436
2296
|
selectedItem
|
|
@@ -2443,14 +2303,11 @@
|
|
|
2443
2303
|
};
|
|
2444
2304
|
}, cb);
|
|
2445
2305
|
};
|
|
2446
|
-
|
|
2447
2306
|
this.toggleMenu = function (otherStateToSet, cb) {
|
|
2448
2307
|
if (otherStateToSet === void 0) {
|
|
2449
2308
|
otherStateToSet = {};
|
|
2450
2309
|
}
|
|
2451
|
-
|
|
2452
2310
|
otherStateToSet = pickState(otherStateToSet);
|
|
2453
|
-
|
|
2454
2311
|
_this.internalSetState(_ref2 => {
|
|
2455
2312
|
let {
|
|
2456
2313
|
isOpen
|
|
@@ -2467,29 +2324,24 @@
|
|
|
2467
2324
|
isOpen,
|
|
2468
2325
|
highlightedIndex
|
|
2469
2326
|
} = _this.getState();
|
|
2470
|
-
|
|
2471
2327
|
if (isOpen) {
|
|
2472
2328
|
if (_this.getItemCount() > 0 && typeof highlightedIndex === 'number') {
|
|
2473
2329
|
_this.setHighlightedIndex(highlightedIndex, otherStateToSet);
|
|
2474
2330
|
}
|
|
2475
2331
|
}
|
|
2476
|
-
|
|
2477
2332
|
cbToCb(cb)();
|
|
2478
2333
|
});
|
|
2479
2334
|
};
|
|
2480
|
-
|
|
2481
2335
|
this.openMenu = cb => {
|
|
2482
2336
|
this.internalSetState({
|
|
2483
2337
|
isOpen: true
|
|
2484
2338
|
}, cb);
|
|
2485
2339
|
};
|
|
2486
|
-
|
|
2487
2340
|
this.closeMenu = cb => {
|
|
2488
2341
|
this.internalSetState({
|
|
2489
2342
|
isOpen: false
|
|
2490
2343
|
}, cb);
|
|
2491
2344
|
};
|
|
2492
|
-
|
|
2493
2345
|
this.updateStatus = debounce(() => {
|
|
2494
2346
|
const state = this.getState();
|
|
2495
2347
|
const item = this.items[state.highlightedIndex];
|
|
@@ -2515,21 +2367,17 @@
|
|
|
2515
2367
|
initialInputValue: _inputValue = '',
|
|
2516
2368
|
initialSelectedItem: _selectedItem = null
|
|
2517
2369
|
} = this.props;
|
|
2518
|
-
|
|
2519
2370
|
const _state = this.getState({
|
|
2520
2371
|
highlightedIndex: _highlightedIndex,
|
|
2521
2372
|
isOpen: _isOpen,
|
|
2522
2373
|
inputValue: _inputValue,
|
|
2523
2374
|
selectedItem: _selectedItem
|
|
2524
2375
|
});
|
|
2525
|
-
|
|
2526
2376
|
if (_state.selectedItem != null && this.props.initialInputValue === undefined) {
|
|
2527
2377
|
_state.inputValue = this.props.itemToString(_state.selectedItem);
|
|
2528
2378
|
}
|
|
2529
|
-
|
|
2530
2379
|
this.state = _state;
|
|
2531
2380
|
}
|
|
2532
|
-
|
|
2533
2381
|
/**
|
|
2534
2382
|
* Clear all running timeouts
|
|
2535
2383
|
*/
|
|
@@ -2539,6 +2387,7 @@
|
|
|
2539
2387
|
});
|
|
2540
2388
|
this.timeoutIds = [];
|
|
2541
2389
|
}
|
|
2390
|
+
|
|
2542
2391
|
/**
|
|
2543
2392
|
* Gets the state based on internal state or props
|
|
2544
2393
|
* If a state value is passed via props, then that
|
|
@@ -2548,36 +2397,28 @@
|
|
|
2548
2397
|
* @param {Object} stateToMerge defaults to this.state
|
|
2549
2398
|
* @return {Object} the state
|
|
2550
2399
|
*/
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
2400
|
getState(stateToMerge) {
|
|
2554
2401
|
if (stateToMerge === void 0) {
|
|
2555
2402
|
stateToMerge = this.state;
|
|
2556
2403
|
}
|
|
2557
|
-
|
|
2558
2404
|
return getState(stateToMerge, this.props);
|
|
2559
2405
|
}
|
|
2560
|
-
|
|
2561
2406
|
getItemCount() {
|
|
2562
2407
|
// things read better this way. They're in priority order:
|
|
2563
2408
|
// 1. `this.itemCount`
|
|
2564
2409
|
// 2. `this.props.itemCount`
|
|
2565
2410
|
// 3. `this.items.length`
|
|
2566
2411
|
let itemCount = this.items.length;
|
|
2567
|
-
|
|
2568
2412
|
if (this.itemCount != null) {
|
|
2569
2413
|
itemCount = this.itemCount;
|
|
2570
2414
|
} else if (this.props.itemCount !== undefined) {
|
|
2571
2415
|
itemCount = this.props.itemCount;
|
|
2572
2416
|
}
|
|
2573
|
-
|
|
2574
2417
|
return itemCount;
|
|
2575
2418
|
}
|
|
2576
|
-
|
|
2577
2419
|
getItemNodeFromIndex(index) {
|
|
2578
2420
|
return this.props.environment.document.getElementById(this.getItemId(index));
|
|
2579
2421
|
}
|
|
2580
|
-
|
|
2581
2422
|
scrollHighlightedItemIntoView() {
|
|
2582
2423
|
/* istanbul ignore else (react-native) */
|
|
2583
2424
|
{
|
|
@@ -2585,19 +2426,16 @@
|
|
|
2585
2426
|
this.props.scrollIntoView(node, this._menuNode);
|
|
2586
2427
|
}
|
|
2587
2428
|
}
|
|
2588
|
-
|
|
2589
2429
|
moveHighlightedIndex(amount, otherStateToSet) {
|
|
2590
2430
|
const itemCount = this.getItemCount();
|
|
2591
2431
|
const {
|
|
2592
2432
|
highlightedIndex
|
|
2593
2433
|
} = this.getState();
|
|
2594
|
-
|
|
2595
2434
|
if (itemCount > 0) {
|
|
2596
2435
|
const nextHighlightedIndex = getNextWrappingIndex(amount, highlightedIndex, itemCount, index => this.getItemNodeFromIndex(index));
|
|
2597
2436
|
this.setHighlightedIndex(nextHighlightedIndex, otherStateToSet);
|
|
2598
2437
|
}
|
|
2599
2438
|
}
|
|
2600
|
-
|
|
2601
2439
|
getStateAndHelpers() {
|
|
2602
2440
|
const {
|
|
2603
2441
|
highlightedIndex,
|
|
@@ -2664,17 +2502,17 @@
|
|
|
2664
2502
|
isOpen,
|
|
2665
2503
|
selectedItem
|
|
2666
2504
|
};
|
|
2667
|
-
}
|
|
2505
|
+
}
|
|
2668
2506
|
|
|
2507
|
+
//////////////////////////// ROOT
|
|
2669
2508
|
|
|
2670
2509
|
componentDidMount() {
|
|
2671
2510
|
/* istanbul ignore if (react-native) */
|
|
2672
2511
|
if (this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
|
|
2673
2512
|
validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
|
|
2674
2513
|
}
|
|
2675
|
-
/* istanbul ignore if (react-native) */
|
|
2676
|
-
|
|
2677
2514
|
|
|
2515
|
+
/* istanbul ignore if (react-native) */
|
|
2678
2516
|
{
|
|
2679
2517
|
// this.isMouseDown helps us track whether the mouse is currently held down.
|
|
2680
2518
|
// This is useful when the user clicks on an item in the list, but holds the mouse
|
|
@@ -2684,44 +2522,37 @@
|
|
|
2684
2522
|
const onMouseDown = () => {
|
|
2685
2523
|
this.isMouseDown = true;
|
|
2686
2524
|
};
|
|
2687
|
-
|
|
2688
2525
|
const onMouseUp = event => {
|
|
2689
|
-
this.isMouseDown = false;
|
|
2526
|
+
this.isMouseDown = false;
|
|
2527
|
+
// if the target element or the activeElement is within a downshift node
|
|
2690
2528
|
// then we don't want to reset downshift
|
|
2691
|
-
|
|
2692
2529
|
const contextWithinDownshift = targetWithinDownshift(event.target, [this._rootNode, this._menuNode], this.props.environment);
|
|
2693
|
-
|
|
2694
2530
|
if (!contextWithinDownshift && this.getState().isOpen) {
|
|
2695
2531
|
this.reset({
|
|
2696
2532
|
type: mouseUp
|
|
2697
2533
|
}, () => this.props.onOuterClick(this.getStateAndHelpers()));
|
|
2698
2534
|
}
|
|
2699
|
-
};
|
|
2535
|
+
};
|
|
2536
|
+
// Touching an element in iOS gives focus and hover states, but touching out of
|
|
2700
2537
|
// the element will remove hover, and persist the focus state, resulting in the
|
|
2701
2538
|
// blur event not being triggered.
|
|
2702
2539
|
// this.isTouchMove helps us track whether the user is tapping or swiping on a touch screen.
|
|
2703
2540
|
// If the user taps outside of Downshift, the component should be reset,
|
|
2704
2541
|
// but not if the user is swiping
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
2542
|
const onTouchStart = () => {
|
|
2708
2543
|
this.isTouchMove = false;
|
|
2709
2544
|
};
|
|
2710
|
-
|
|
2711
2545
|
const onTouchMove = () => {
|
|
2712
2546
|
this.isTouchMove = true;
|
|
2713
2547
|
};
|
|
2714
|
-
|
|
2715
2548
|
const onTouchEnd = event => {
|
|
2716
2549
|
const contextWithinDownshift = targetWithinDownshift(event.target, [this._rootNode, this._menuNode], this.props.environment, false);
|
|
2717
|
-
|
|
2718
2550
|
if (!this.isTouchMove && !contextWithinDownshift && this.getState().isOpen) {
|
|
2719
2551
|
this.reset({
|
|
2720
2552
|
type: touchEnd
|
|
2721
2553
|
}, () => this.props.onOuterClick(this.getStateAndHelpers()));
|
|
2722
2554
|
}
|
|
2723
2555
|
};
|
|
2724
|
-
|
|
2725
2556
|
const {
|
|
2726
2557
|
environment
|
|
2727
2558
|
} = this.props;
|
|
@@ -2730,7 +2561,6 @@
|
|
|
2730
2561
|
environment.addEventListener('touchstart', onTouchStart);
|
|
2731
2562
|
environment.addEventListener('touchmove', onTouchMove);
|
|
2732
2563
|
environment.addEventListener('touchend', onTouchEnd);
|
|
2733
|
-
|
|
2734
2564
|
this.cleanup = () => {
|
|
2735
2565
|
this.internalClearTimeouts();
|
|
2736
2566
|
this.updateStatus.cancel();
|
|
@@ -2742,7 +2572,6 @@
|
|
|
2742
2572
|
};
|
|
2743
2573
|
}
|
|
2744
2574
|
}
|
|
2745
|
-
|
|
2746
2575
|
shouldScroll(prevState, prevProps) {
|
|
2747
2576
|
const {
|
|
2748
2577
|
highlightedIndex: currentHighlightedIndex
|
|
@@ -2754,89 +2583,78 @@
|
|
|
2754
2583
|
const scrollWhenNavigating = currentHighlightedIndex !== prevHighlightedIndex;
|
|
2755
2584
|
return scrollWhenOpen || scrollWhenNavigating;
|
|
2756
2585
|
}
|
|
2757
|
-
|
|
2758
2586
|
componentDidUpdate(prevProps, prevState) {
|
|
2759
2587
|
{
|
|
2760
2588
|
validateControlledUnchanged(this.state, prevProps, this.props);
|
|
2761
2589
|
/* istanbul ignore if (react-native) */
|
|
2762
|
-
|
|
2763
2590
|
if (this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
|
|
2764
2591
|
validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
|
|
2765
2592
|
}
|
|
2766
2593
|
}
|
|
2767
|
-
|
|
2768
2594
|
if (isControlledProp(this.props, 'selectedItem') && this.props.selectedItemChanged(prevProps.selectedItem, this.props.selectedItem)) {
|
|
2769
2595
|
this.internalSetState({
|
|
2770
2596
|
type: controlledPropUpdatedSelectedItem,
|
|
2771
2597
|
inputValue: this.props.itemToString(this.props.selectedItem)
|
|
2772
2598
|
});
|
|
2773
2599
|
}
|
|
2774
|
-
|
|
2775
2600
|
if (!this.avoidScrolling && this.shouldScroll(prevState, prevProps)) {
|
|
2776
2601
|
this.scrollHighlightedItemIntoView();
|
|
2777
2602
|
}
|
|
2778
|
-
/* istanbul ignore else (react-native) */
|
|
2779
|
-
|
|
2780
2603
|
|
|
2604
|
+
/* istanbul ignore else (react-native) */
|
|
2781
2605
|
{
|
|
2782
2606
|
this.updateStatus();
|
|
2783
2607
|
}
|
|
2784
2608
|
}
|
|
2785
|
-
|
|
2786
2609
|
componentWillUnmount() {
|
|
2787
2610
|
this.cleanup(); // avoids memory leak
|
|
2788
2611
|
}
|
|
2789
2612
|
|
|
2790
2613
|
render() {
|
|
2791
|
-
const children = unwrapArray(this.props.children, noop);
|
|
2614
|
+
const children = unwrapArray(this.props.children, noop);
|
|
2615
|
+
// because the items are rerendered every time we call the children
|
|
2792
2616
|
// we clear this out each render and it will be populated again as
|
|
2793
2617
|
// getItemProps is called.
|
|
2794
|
-
|
|
2795
|
-
|
|
2618
|
+
this.clearItems();
|
|
2619
|
+
// we reset this so we know whether the user calls getRootProps during
|
|
2796
2620
|
// this render. If they do then we don't need to do anything,
|
|
2797
2621
|
// if they don't then we need to clone the element they return and
|
|
2798
2622
|
// apply the props for them.
|
|
2799
|
-
|
|
2800
2623
|
this.getRootProps.called = false;
|
|
2801
2624
|
this.getRootProps.refKey = undefined;
|
|
2802
|
-
this.getRootProps.suppressRefError = undefined;
|
|
2803
|
-
|
|
2625
|
+
this.getRootProps.suppressRefError = undefined;
|
|
2626
|
+
// we do something similar for getMenuProps
|
|
2804
2627
|
this.getMenuProps.called = false;
|
|
2805
2628
|
this.getMenuProps.refKey = undefined;
|
|
2806
|
-
this.getMenuProps.suppressRefError = undefined;
|
|
2807
|
-
|
|
2808
|
-
this.getLabelProps.called = false;
|
|
2809
|
-
|
|
2629
|
+
this.getMenuProps.suppressRefError = undefined;
|
|
2630
|
+
// we do something similar for getLabelProps
|
|
2631
|
+
this.getLabelProps.called = false;
|
|
2632
|
+
// and something similar for getInputProps
|
|
2810
2633
|
this.getInputProps.called = false;
|
|
2811
2634
|
const element = unwrapArray(children(this.getStateAndHelpers()));
|
|
2812
|
-
|
|
2813
2635
|
if (!element) {
|
|
2814
2636
|
return null;
|
|
2815
2637
|
}
|
|
2816
|
-
|
|
2817
2638
|
if (this.getRootProps.called || this.props.suppressRefError) {
|
|
2818
2639
|
if (!this.getRootProps.suppressRefError && !this.props.suppressRefError) {
|
|
2819
2640
|
validateGetRootPropsCalledCorrectly(element, this.getRootProps);
|
|
2820
2641
|
}
|
|
2821
|
-
|
|
2822
2642
|
return element;
|
|
2823
2643
|
} else if (isDOMElement(element)) {
|
|
2824
2644
|
// they didn't apply the root props, but we can clone
|
|
2825
2645
|
// this and apply the props ourselves
|
|
2826
2646
|
return /*#__PURE__*/react.cloneElement(element, this.getRootProps(getElementProps(element)));
|
|
2827
2647
|
}
|
|
2828
|
-
/* istanbul ignore else */
|
|
2829
|
-
|
|
2830
2648
|
|
|
2649
|
+
/* istanbul ignore else */
|
|
2831
2650
|
{
|
|
2832
2651
|
// they didn't apply the root props, but they need to
|
|
2833
2652
|
// otherwise we can't query around the autocomplete
|
|
2653
|
+
|
|
2834
2654
|
throw new Error('downshift: If you return a non-DOM element, you must apply the getRootProps function');
|
|
2835
2655
|
}
|
|
2836
2656
|
}
|
|
2837
|
-
|
|
2838
2657
|
}
|
|
2839
|
-
|
|
2840
2658
|
Downshift.defaultProps = {
|
|
2841
2659
|
defaultHighlightedIndex: null,
|
|
2842
2660
|
defaultIsOpen: false,
|
|
@@ -2845,12 +2663,10 @@
|
|
|
2845
2663
|
if (i == null) {
|
|
2846
2664
|
return '';
|
|
2847
2665
|
}
|
|
2848
|
-
|
|
2849
2666
|
if (isPlainObject(i) && !i.hasOwnProperty('toString')) {
|
|
2850
2667
|
// eslint-disable-next-line no-console
|
|
2851
2668
|
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);
|
|
2852
2669
|
}
|
|
2853
|
-
|
|
2854
2670
|
return String(i);
|
|
2855
2671
|
},
|
|
2856
2672
|
onStateChange: noop,
|
|
@@ -2860,8 +2676,7 @@
|
|
|
2860
2676
|
onSelect: noop,
|
|
2861
2677
|
onOuterClick: noop,
|
|
2862
2678
|
selectedItemChanged: (prevItem, item) => prevItem !== item,
|
|
2863
|
-
environment:
|
|
2864
|
-
/* istanbul ignore next (ssr) */
|
|
2679
|
+
environment: /* istanbul ignore next (ssr) */
|
|
2865
2680
|
typeof window === 'undefined' ? {} : window,
|
|
2866
2681
|
stateReducer: (state, stateToSet) => stateToSet,
|
|
2867
2682
|
suppressRefError: false,
|
|
@@ -2870,7 +2685,6 @@
|
|
|
2870
2685
|
Downshift.stateChangeTypes = stateChangeTypes$3;
|
|
2871
2686
|
return Downshift;
|
|
2872
2687
|
})();
|
|
2873
|
-
|
|
2874
2688
|
Downshift.propTypes = {
|
|
2875
2689
|
children: PropTypes.func,
|
|
2876
2690
|
defaultHighlightedIndex: PropTypes.number,
|
|
@@ -2904,7 +2718,6 @@
|
|
|
2904
2718
|
scrollIntoView: PropTypes.func,
|
|
2905
2719
|
// things we keep in state for uncontrolled components
|
|
2906
2720
|
// but can accept as props for controlled components
|
|
2907
|
-
|
|
2908
2721
|
/* eslint-disable react/no-unused-prop-types */
|
|
2909
2722
|
selectedItem: PropTypes.any,
|
|
2910
2723
|
isOpen: PropTypes.bool,
|
|
@@ -2915,28 +2728,23 @@
|
|
|
2915
2728
|
menuId: PropTypes.string,
|
|
2916
2729
|
getItemId: PropTypes.func
|
|
2917
2730
|
/* eslint-enable react/no-unused-prop-types */
|
|
2918
|
-
|
|
2919
2731
|
} ;
|
|
2920
2732
|
var Downshift$1 = Downshift;
|
|
2921
|
-
|
|
2922
2733
|
function validateGetMenuPropsCalledCorrectly(node, _ref3) {
|
|
2923
2734
|
let {
|
|
2924
2735
|
refKey
|
|
2925
2736
|
} = _ref3;
|
|
2926
|
-
|
|
2927
2737
|
if (!node) {
|
|
2928
2738
|
// eslint-disable-next-line no-console
|
|
2929
2739
|
console.error(`downshift: The ref prop "${refKey}" from getMenuProps was not applied correctly on your menu element.`);
|
|
2930
2740
|
}
|
|
2931
2741
|
}
|
|
2932
|
-
|
|
2933
2742
|
function validateGetRootPropsCalledCorrectly(element, _ref4) {
|
|
2934
2743
|
let {
|
|
2935
2744
|
refKey
|
|
2936
2745
|
} = _ref4;
|
|
2937
2746
|
const refKeySpecified = refKey !== 'ref';
|
|
2938
2747
|
const isComposite = !isDOMElement(element);
|
|
2939
|
-
|
|
2940
2748
|
if (isComposite && !refKeySpecified && !reactIs.exports.isForwardRef(element)) {
|
|
2941
2749
|
// eslint-disable-next-line no-console
|
|
2942
2750
|
console.error('downshift: You returned a non-DOM element. You must specify a refKey in getRootProps');
|
|
@@ -2944,7 +2752,6 @@
|
|
|
2944
2752
|
// eslint-disable-next-line no-console
|
|
2945
2753
|
console.error(`downshift: You returned a DOM element. You should not specify a refKey in getRootProps. You specified "${refKey}"`);
|
|
2946
2754
|
}
|
|
2947
|
-
|
|
2948
2755
|
if (!reactIs.exports.isForwardRef(element) && !getElementProps(element)[refKey]) {
|
|
2949
2756
|
// eslint-disable-next-line no-console
|
|
2950
2757
|
console.error(`downshift: You must apply the ref prop "${refKey}" from getRootProps onto your root element.`);
|
|
@@ -2957,7 +2764,6 @@
|
|
|
2957
2764
|
selectedItem: null,
|
|
2958
2765
|
inputValue: ''
|
|
2959
2766
|
};
|
|
2960
|
-
|
|
2961
2767
|
function callOnChangeProps(action, state, newState) {
|
|
2962
2768
|
const {
|
|
2963
2769
|
props,
|
|
@@ -2966,12 +2772,10 @@
|
|
|
2966
2772
|
const changes = {};
|
|
2967
2773
|
Object.keys(state).forEach(key => {
|
|
2968
2774
|
invokeOnChangeHandler(key, action, state, newState);
|
|
2969
|
-
|
|
2970
2775
|
if (newState[key] !== state[key]) {
|
|
2971
2776
|
changes[key] = newState[key];
|
|
2972
2777
|
}
|
|
2973
2778
|
});
|
|
2974
|
-
|
|
2975
2779
|
if (props.onStateChange && Object.keys(changes).length) {
|
|
2976
2780
|
props.onStateChange({
|
|
2977
2781
|
type,
|
|
@@ -2979,14 +2783,12 @@
|
|
|
2979
2783
|
});
|
|
2980
2784
|
}
|
|
2981
2785
|
}
|
|
2982
|
-
|
|
2983
2786
|
function invokeOnChangeHandler(key, action, state, newState) {
|
|
2984
2787
|
const {
|
|
2985
2788
|
props,
|
|
2986
2789
|
type
|
|
2987
2790
|
} = action;
|
|
2988
2791
|
const handler = `on${capitalizeString(key)}Change`;
|
|
2989
|
-
|
|
2990
2792
|
if (props[handler] && newState[key] !== undefined && newState[key] !== state[key]) {
|
|
2991
2793
|
props[handler]({
|
|
2992
2794
|
type,
|
|
@@ -2994,6 +2796,7 @@
|
|
|
2994
2796
|
});
|
|
2995
2797
|
}
|
|
2996
2798
|
}
|
|
2799
|
+
|
|
2997
2800
|
/**
|
|
2998
2801
|
* Default state reducer that returns the changes.
|
|
2999
2802
|
*
|
|
@@ -3001,19 +2804,16 @@
|
|
|
3001
2804
|
* @param {Object} a action with changes.
|
|
3002
2805
|
* @returns {Object} changes.
|
|
3003
2806
|
*/
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
2807
|
function stateReducer(s, a) {
|
|
3007
2808
|
return a.changes;
|
|
3008
2809
|
}
|
|
2810
|
+
|
|
3009
2811
|
/**
|
|
3010
2812
|
* Returns a message to be added to aria-live region when item is selected.
|
|
3011
2813
|
*
|
|
3012
2814
|
* @param {Object} selectionParameters Parameters required to build the message.
|
|
3013
2815
|
* @returns {string} The a11y message.
|
|
3014
2816
|
*/
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
2817
|
function getA11ySelectionMessage(selectionParameters) {
|
|
3018
2818
|
const {
|
|
3019
2819
|
selectedItem,
|
|
@@ -3021,17 +2821,16 @@
|
|
|
3021
2821
|
} = selectionParameters;
|
|
3022
2822
|
return selectedItem ? `${itemToStringLocal(selectedItem)} has been selected.` : '';
|
|
3023
2823
|
}
|
|
2824
|
+
|
|
3024
2825
|
/**
|
|
3025
2826
|
* Debounced call for updating the a11y message.
|
|
3026
2827
|
*/
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
2828
|
const updateA11yStatus = debounce((getA11yMessage, document) => {
|
|
3030
2829
|
setStatus(getA11yMessage(), document);
|
|
3031
|
-
}, 200);
|
|
2830
|
+
}, 200);
|
|
3032
2831
|
|
|
2832
|
+
// istanbul ignore next
|
|
3033
2833
|
const useIsomorphicLayoutEffect = typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined' ? react.useLayoutEffect : react.useEffect;
|
|
3034
|
-
|
|
3035
2834
|
function useElementIds(_ref) {
|
|
3036
2835
|
let {
|
|
3037
2836
|
id = `downshift-${generateId()}`,
|
|
@@ -3050,41 +2849,35 @@
|
|
|
3050
2849
|
});
|
|
3051
2850
|
return elementIdsRef.current;
|
|
3052
2851
|
}
|
|
3053
|
-
|
|
3054
2852
|
function getItemIndex(index, item, items) {
|
|
3055
2853
|
if (index !== undefined) {
|
|
3056
2854
|
return index;
|
|
3057
2855
|
}
|
|
3058
|
-
|
|
3059
2856
|
if (items.length === 0) {
|
|
3060
2857
|
return -1;
|
|
3061
2858
|
}
|
|
3062
|
-
|
|
3063
2859
|
return items.indexOf(item);
|
|
3064
2860
|
}
|
|
3065
|
-
|
|
3066
2861
|
function itemToString(item) {
|
|
3067
2862
|
return item ? String(item) : '';
|
|
3068
2863
|
}
|
|
3069
|
-
|
|
3070
2864
|
function isAcceptedCharacterKey(key) {
|
|
3071
2865
|
return /^\S{1}$/.test(key);
|
|
3072
2866
|
}
|
|
3073
|
-
|
|
3074
2867
|
function capitalizeString(string) {
|
|
3075
2868
|
return `${string.slice(0, 1).toUpperCase()}${string.slice(1)}`;
|
|
3076
2869
|
}
|
|
3077
|
-
|
|
3078
2870
|
function useLatestRef(val) {
|
|
3079
|
-
const ref = react.useRef(val);
|
|
2871
|
+
const ref = react.useRef(val);
|
|
2872
|
+
// technically this is not "concurrent mode safe" because we're manipulating
|
|
3080
2873
|
// the value during render (so it's not idempotent). However, the places this
|
|
3081
2874
|
// hook is used is to support memoizing callbacks which will be called
|
|
3082
2875
|
// *during* render, so we need the latest values *during* render.
|
|
3083
2876
|
// If not for this, then we'd probably want to use useLayoutEffect instead.
|
|
3084
|
-
|
|
3085
2877
|
ref.current = val;
|
|
3086
2878
|
return ref;
|
|
3087
2879
|
}
|
|
2880
|
+
|
|
3088
2881
|
/**
|
|
3089
2882
|
* Computes the controlled state using a the previous state, props,
|
|
3090
2883
|
* two reducers, one from downshift and an optional one from the user.
|
|
@@ -3095,8 +2888,6 @@
|
|
|
3095
2888
|
* @param {Object} props The hook props.
|
|
3096
2889
|
* @returns {Array} An array with the state and an action dispatcher.
|
|
3097
2890
|
*/
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
2891
|
function useEnhancedReducer(reducer, initialState, props) {
|
|
3101
2892
|
const prevStateRef = react.useRef();
|
|
3102
2893
|
const actionRef = react.useRef();
|
|
@@ -3104,7 +2895,8 @@
|
|
|
3104
2895
|
actionRef.current = action;
|
|
3105
2896
|
state = getState(state, action.props);
|
|
3106
2897
|
const changes = reducer(state, action);
|
|
3107
|
-
const newState = action.props.stateReducer(state, {
|
|
2898
|
+
const newState = action.props.stateReducer(state, {
|
|
2899
|
+
...action,
|
|
3108
2900
|
changes
|
|
3109
2901
|
});
|
|
3110
2902
|
return newState;
|
|
@@ -3120,11 +2912,11 @@
|
|
|
3120
2912
|
if (action && prevStateRef.current && prevStateRef.current !== state) {
|
|
3121
2913
|
callOnChangeProps(action, getState(prevStateRef.current, action.props), state);
|
|
3122
2914
|
}
|
|
3123
|
-
|
|
3124
2915
|
prevStateRef.current = state;
|
|
3125
2916
|
}, [state, props, action]);
|
|
3126
2917
|
return [state, dispatchWithProps];
|
|
3127
2918
|
}
|
|
2919
|
+
|
|
3128
2920
|
/**
|
|
3129
2921
|
* Wraps the useEnhancedReducer and applies the controlled prop values before
|
|
3130
2922
|
* returning the new state.
|
|
@@ -3134,57 +2926,42 @@
|
|
|
3134
2926
|
* @param {Object} props The hook props.
|
|
3135
2927
|
* @returns {Array} An array with the state and an action dispatcher.
|
|
3136
2928
|
*/
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
2929
|
function useControlledReducer$1(reducer, initialState, props) {
|
|
3140
2930
|
const [state, dispatch] = useEnhancedReducer(reducer, initialState, props);
|
|
3141
2931
|
return [getState(state, props), dispatch];
|
|
3142
2932
|
}
|
|
3143
|
-
|
|
3144
2933
|
const defaultProps$3 = {
|
|
3145
2934
|
itemToString,
|
|
3146
2935
|
stateReducer,
|
|
3147
2936
|
getA11ySelectionMessage,
|
|
3148
2937
|
scrollIntoView,
|
|
3149
|
-
environment:
|
|
3150
|
-
/* istanbul ignore next (ssr) */
|
|
2938
|
+
environment: /* istanbul ignore next (ssr) */
|
|
3151
2939
|
typeof window === 'undefined' ? {} : window
|
|
3152
2940
|
};
|
|
3153
|
-
|
|
3154
2941
|
function getDefaultValue$1(props, propKey, defaultStateValues) {
|
|
3155
2942
|
if (defaultStateValues === void 0) {
|
|
3156
2943
|
defaultStateValues = dropdownDefaultStateValues;
|
|
3157
2944
|
}
|
|
3158
|
-
|
|
3159
2945
|
const defaultValue = props[`default${capitalizeString(propKey)}`];
|
|
3160
|
-
|
|
3161
2946
|
if (defaultValue !== undefined) {
|
|
3162
2947
|
return defaultValue;
|
|
3163
2948
|
}
|
|
3164
|
-
|
|
3165
2949
|
return defaultStateValues[propKey];
|
|
3166
2950
|
}
|
|
3167
|
-
|
|
3168
2951
|
function getInitialValue$1(props, propKey, defaultStateValues) {
|
|
3169
2952
|
if (defaultStateValues === void 0) {
|
|
3170
2953
|
defaultStateValues = dropdownDefaultStateValues;
|
|
3171
2954
|
}
|
|
3172
|
-
|
|
3173
2955
|
const value = props[propKey];
|
|
3174
|
-
|
|
3175
2956
|
if (value !== undefined) {
|
|
3176
2957
|
return value;
|
|
3177
2958
|
}
|
|
3178
|
-
|
|
3179
2959
|
const initialValue = props[`initial${capitalizeString(propKey)}`];
|
|
3180
|
-
|
|
3181
2960
|
if (initialValue !== undefined) {
|
|
3182
2961
|
return initialValue;
|
|
3183
2962
|
}
|
|
3184
|
-
|
|
3185
2963
|
return getDefaultValue$1(props, propKey, defaultStateValues);
|
|
3186
2964
|
}
|
|
3187
|
-
|
|
3188
2965
|
function getInitialState$2(props) {
|
|
3189
2966
|
const selectedItem = getInitialValue$1(props, 'selectedItem');
|
|
3190
2967
|
const isOpen = getInitialValue$1(props, 'isOpen');
|
|
@@ -3197,7 +2974,6 @@
|
|
|
3197
2974
|
inputValue
|
|
3198
2975
|
};
|
|
3199
2976
|
}
|
|
3200
|
-
|
|
3201
2977
|
function getHighlightedIndexOnOpen(props, state, offset) {
|
|
3202
2978
|
const {
|
|
3203
2979
|
items,
|
|
@@ -3208,30 +2984,26 @@
|
|
|
3208
2984
|
selectedItem,
|
|
3209
2985
|
highlightedIndex
|
|
3210
2986
|
} = state;
|
|
3211
|
-
|
|
3212
2987
|
if (items.length === 0) {
|
|
3213
2988
|
return -1;
|
|
3214
|
-
}
|
|
3215
|
-
|
|
2989
|
+
}
|
|
3216
2990
|
|
|
2991
|
+
// initialHighlightedIndex will give value to highlightedIndex on initial state only.
|
|
3217
2992
|
if (initialHighlightedIndex !== undefined && highlightedIndex === initialHighlightedIndex) {
|
|
3218
2993
|
return initialHighlightedIndex;
|
|
3219
2994
|
}
|
|
3220
|
-
|
|
3221
2995
|
if (defaultHighlightedIndex !== undefined) {
|
|
3222
2996
|
return defaultHighlightedIndex;
|
|
3223
2997
|
}
|
|
3224
|
-
|
|
3225
2998
|
if (selectedItem) {
|
|
3226
2999
|
return items.indexOf(selectedItem);
|
|
3227
3000
|
}
|
|
3228
|
-
|
|
3229
3001
|
if (offset === 0) {
|
|
3230
3002
|
return -1;
|
|
3231
3003
|
}
|
|
3232
|
-
|
|
3233
3004
|
return offset < 0 ? items.length - 1 : 0;
|
|
3234
3005
|
}
|
|
3006
|
+
|
|
3235
3007
|
/**
|
|
3236
3008
|
* Reuse the movement tracking of mouse and touch events.
|
|
3237
3009
|
*
|
|
@@ -3241,8 +3013,6 @@
|
|
|
3241
3013
|
* @param {Function} handleBlur Handler on blur from mouse or touch.
|
|
3242
3014
|
* @returns {Object} Ref containing whether mouseDown or touchMove event is happening
|
|
3243
3015
|
*/
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
3016
|
function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, handleBlur) {
|
|
3247
3017
|
const mouseAndTouchTrackersRef = react.useRef({
|
|
3248
3018
|
isMouseDown: false,
|
|
@@ -3254,29 +3024,23 @@
|
|
|
3254
3024
|
const onMouseDown = () => {
|
|
3255
3025
|
mouseAndTouchTrackersRef.current.isMouseDown = true;
|
|
3256
3026
|
};
|
|
3257
|
-
|
|
3258
3027
|
const onMouseUp = event => {
|
|
3259
3028
|
mouseAndTouchTrackersRef.current.isMouseDown = false;
|
|
3260
|
-
|
|
3261
3029
|
if (isOpen && !targetWithinDownshift(event.target, downshiftElementRefs.map(ref => ref.current), environment)) {
|
|
3262
3030
|
handleBlur();
|
|
3263
3031
|
}
|
|
3264
3032
|
};
|
|
3265
|
-
|
|
3266
3033
|
const onTouchStart = () => {
|
|
3267
3034
|
mouseAndTouchTrackersRef.current.isTouchMove = false;
|
|
3268
3035
|
};
|
|
3269
|
-
|
|
3270
3036
|
const onTouchMove = () => {
|
|
3271
3037
|
mouseAndTouchTrackersRef.current.isTouchMove = true;
|
|
3272
3038
|
};
|
|
3273
|
-
|
|
3274
3039
|
const onTouchEnd = event => {
|
|
3275
3040
|
if (isOpen && !mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, downshiftElementRefs.map(ref => ref.current), environment, false)) {
|
|
3276
3041
|
handleBlur();
|
|
3277
3042
|
}
|
|
3278
3043
|
};
|
|
3279
|
-
|
|
3280
3044
|
environment.addEventListener('mousedown', onMouseDown);
|
|
3281
3045
|
environment.addEventListener('mouseup', onMouseUp);
|
|
3282
3046
|
environment.addEventListener('touchstart', onTouchStart);
|
|
@@ -3288,14 +3052,14 @@
|
|
|
3288
3052
|
environment.removeEventListener('touchstart', onTouchStart);
|
|
3289
3053
|
environment.removeEventListener('touchmove', onTouchMove);
|
|
3290
3054
|
environment.removeEventListener('touchend', onTouchEnd);
|
|
3291
|
-
};
|
|
3055
|
+
};
|
|
3056
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3292
3057
|
}, [isOpen, environment]);
|
|
3293
3058
|
return mouseAndTouchTrackersRef;
|
|
3294
3059
|
}
|
|
3060
|
+
|
|
3295
3061
|
/* istanbul ignore next */
|
|
3296
3062
|
// eslint-disable-next-line import/no-mutable-exports
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
3063
|
let useGetterPropsCalledChecker = () => noop;
|
|
3300
3064
|
/**
|
|
3301
3065
|
* Custom hook that checks if getter props are called correctly.
|
|
@@ -3303,18 +3067,13 @@
|
|
|
3303
3067
|
* @param {...any} propKeys Getter prop names to be handled.
|
|
3304
3068
|
* @returns {Function} Setter function called inside getter props to set call information.
|
|
3305
3069
|
*/
|
|
3306
|
-
|
|
3307
3070
|
/* istanbul ignore next */
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
3071
|
{
|
|
3311
3072
|
useGetterPropsCalledChecker = function () {
|
|
3312
3073
|
const isInitialMountRef = react.useRef(true);
|
|
3313
|
-
|
|
3314
3074
|
for (var _len = arguments.length, propKeys = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
3315
3075
|
propKeys[_key] = arguments[_key];
|
|
3316
3076
|
}
|
|
3317
|
-
|
|
3318
3077
|
const getterPropsCalledRef = react.useRef(propKeys.reduce((acc, propKey) => {
|
|
3319
3078
|
acc[propKey] = {};
|
|
3320
3079
|
return acc;
|
|
@@ -3322,7 +3081,6 @@
|
|
|
3322
3081
|
react.useEffect(() => {
|
|
3323
3082
|
Object.keys(getterPropsCalledRef.current).forEach(propKey => {
|
|
3324
3083
|
const propCallInfo = getterPropsCalledRef.current[propKey];
|
|
3325
|
-
|
|
3326
3084
|
if (isInitialMountRef.current) {
|
|
3327
3085
|
if (!Object.keys(propCallInfo).length) {
|
|
3328
3086
|
// eslint-disable-next-line no-console
|
|
@@ -3330,13 +3088,11 @@
|
|
|
3330
3088
|
return;
|
|
3331
3089
|
}
|
|
3332
3090
|
}
|
|
3333
|
-
|
|
3334
3091
|
const {
|
|
3335
3092
|
suppressRefError,
|
|
3336
3093
|
refKey,
|
|
3337
3094
|
elementRef
|
|
3338
3095
|
} = propCallInfo;
|
|
3339
|
-
|
|
3340
3096
|
if ((!elementRef || !elementRef.current) && !suppressRefError) {
|
|
3341
3097
|
// eslint-disable-next-line no-console
|
|
3342
3098
|
console.error(`downshift: The ref prop "${refKey}" from ${propKey} was not applied correctly on your element.`);
|
|
@@ -3354,7 +3110,6 @@
|
|
|
3354
3110
|
return setGetterPropCallInfo;
|
|
3355
3111
|
};
|
|
3356
3112
|
}
|
|
3357
|
-
|
|
3358
3113
|
function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref2) {
|
|
3359
3114
|
let {
|
|
3360
3115
|
isInitialMount,
|
|
@@ -3368,16 +3123,15 @@
|
|
|
3368
3123
|
if (isInitialMount || false) {
|
|
3369
3124
|
return;
|
|
3370
3125
|
}
|
|
3371
|
-
|
|
3372
3126
|
updateA11yStatus(() => getA11yMessage({
|
|
3373
3127
|
highlightedIndex,
|
|
3374
3128
|
highlightedItem: items[highlightedIndex],
|
|
3375
3129
|
resultCount: items.length,
|
|
3376
3130
|
...rest
|
|
3377
|
-
}), environment.document);
|
|
3131
|
+
}), environment.document);
|
|
3132
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3378
3133
|
}, dependencyArray);
|
|
3379
3134
|
}
|
|
3380
|
-
|
|
3381
3135
|
function useScrollIntoView(_ref3) {
|
|
3382
3136
|
let {
|
|
3383
3137
|
highlightedIndex,
|
|
@@ -3388,27 +3142,25 @@
|
|
|
3388
3142
|
scrollIntoView: scrollIntoViewProp
|
|
3389
3143
|
} = _ref3;
|
|
3390
3144
|
// used not to scroll on highlight by mouse.
|
|
3391
|
-
const shouldScrollRef = react.useRef(true);
|
|
3392
|
-
|
|
3145
|
+
const shouldScrollRef = react.useRef(true);
|
|
3146
|
+
// Scroll on highlighted item if change comes from keyboard.
|
|
3393
3147
|
useIsomorphicLayoutEffect(() => {
|
|
3394
3148
|
if (highlightedIndex < 0 || !isOpen || !Object.keys(itemRefs.current).length) {
|
|
3395
3149
|
return;
|
|
3396
3150
|
}
|
|
3397
|
-
|
|
3398
3151
|
if (shouldScrollRef.current === false) {
|
|
3399
3152
|
shouldScrollRef.current = true;
|
|
3400
3153
|
} else {
|
|
3401
3154
|
scrollIntoViewProp(getItemNodeFromIndex(highlightedIndex), menuElement);
|
|
3402
|
-
}
|
|
3403
|
-
|
|
3155
|
+
}
|
|
3156
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
3404
3157
|
}, [highlightedIndex]);
|
|
3405
3158
|
return shouldScrollRef;
|
|
3406
|
-
}
|
|
3407
|
-
|
|
3159
|
+
}
|
|
3408
3160
|
|
|
3161
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
3409
3162
|
let useControlPropsValidator = noop;
|
|
3410
3163
|
/* istanbul ignore next */
|
|
3411
|
-
|
|
3412
3164
|
{
|
|
3413
3165
|
useControlPropsValidator = _ref4 => {
|
|
3414
3166
|
let {
|
|
@@ -3422,7 +3174,6 @@
|
|
|
3422
3174
|
if (isInitialMount) {
|
|
3423
3175
|
return;
|
|
3424
3176
|
}
|
|
3425
|
-
|
|
3426
3177
|
validateControlledUnchanged(state, prevPropsRef.current, props);
|
|
3427
3178
|
prevPropsRef.current = props;
|
|
3428
3179
|
}, [state, props, isInitialMount]);
|
|
@@ -3435,20 +3186,17 @@
|
|
|
3435
3186
|
props
|
|
3436
3187
|
} = action;
|
|
3437
3188
|
let changes;
|
|
3438
|
-
|
|
3439
3189
|
switch (type) {
|
|
3440
3190
|
case stateChangeTypes.ItemMouseMove:
|
|
3441
3191
|
changes = {
|
|
3442
3192
|
highlightedIndex: action.disabled ? -1 : action.index
|
|
3443
3193
|
};
|
|
3444
3194
|
break;
|
|
3445
|
-
|
|
3446
3195
|
case stateChangeTypes.MenuMouseLeave:
|
|
3447
3196
|
changes = {
|
|
3448
3197
|
highlightedIndex: -1
|
|
3449
3198
|
};
|
|
3450
3199
|
break;
|
|
3451
|
-
|
|
3452
3200
|
case stateChangeTypes.ToggleButtonClick:
|
|
3453
3201
|
case stateChangeTypes.FunctionToggleMenu:
|
|
3454
3202
|
changes = {
|
|
@@ -3456,32 +3204,27 @@
|
|
|
3456
3204
|
highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
|
|
3457
3205
|
};
|
|
3458
3206
|
break;
|
|
3459
|
-
|
|
3460
3207
|
case stateChangeTypes.FunctionOpenMenu:
|
|
3461
3208
|
changes = {
|
|
3462
3209
|
isOpen: true,
|
|
3463
3210
|
highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
|
|
3464
3211
|
};
|
|
3465
3212
|
break;
|
|
3466
|
-
|
|
3467
3213
|
case stateChangeTypes.FunctionCloseMenu:
|
|
3468
3214
|
changes = {
|
|
3469
3215
|
isOpen: false
|
|
3470
3216
|
};
|
|
3471
3217
|
break;
|
|
3472
|
-
|
|
3473
3218
|
case stateChangeTypes.FunctionSetHighlightedIndex:
|
|
3474
3219
|
changes = {
|
|
3475
3220
|
highlightedIndex: action.highlightedIndex
|
|
3476
3221
|
};
|
|
3477
3222
|
break;
|
|
3478
|
-
|
|
3479
3223
|
case stateChangeTypes.FunctionSetInputValue:
|
|
3480
3224
|
changes = {
|
|
3481
3225
|
inputValue: action.inputValue
|
|
3482
3226
|
};
|
|
3483
3227
|
break;
|
|
3484
|
-
|
|
3485
3228
|
case stateChangeTypes.FunctionReset:
|
|
3486
3229
|
changes = {
|
|
3487
3230
|
highlightedIndex: getDefaultValue$1(props, 'highlightedIndex'),
|
|
@@ -3490,12 +3233,11 @@
|
|
|
3490
3233
|
inputValue: getDefaultValue$1(props, 'inputValue')
|
|
3491
3234
|
};
|
|
3492
3235
|
break;
|
|
3493
|
-
|
|
3494
3236
|
default:
|
|
3495
3237
|
throw new Error('Reducer called without proper action type.');
|
|
3496
3238
|
}
|
|
3497
|
-
|
|
3498
|
-
|
|
3239
|
+
return {
|
|
3240
|
+
...state,
|
|
3499
3241
|
...changes
|
|
3500
3242
|
};
|
|
3501
3243
|
}
|
|
@@ -3660,7 +3402,6 @@
|
|
|
3660
3402
|
});
|
|
3661
3403
|
|
|
3662
3404
|
/* eslint-disable complexity */
|
|
3663
|
-
|
|
3664
3405
|
function downshiftSelectReducer(state, action) {
|
|
3665
3406
|
const {
|
|
3666
3407
|
type,
|
|
@@ -3668,7 +3409,6 @@
|
|
|
3668
3409
|
altKey
|
|
3669
3410
|
} = action;
|
|
3670
3411
|
let changes;
|
|
3671
|
-
|
|
3672
3412
|
switch (type) {
|
|
3673
3413
|
case ItemClick$1:
|
|
3674
3414
|
changes = {
|
|
@@ -3677,7 +3417,6 @@
|
|
|
3677
3417
|
selectedItem: props.items[action.index]
|
|
3678
3418
|
};
|
|
3679
3419
|
break;
|
|
3680
|
-
|
|
3681
3420
|
case ToggleButtonKeyDownCharacter:
|
|
3682
3421
|
{
|
|
3683
3422
|
const lowercasedKey = action.key;
|
|
@@ -3697,7 +3436,6 @@
|
|
|
3697
3436
|
};
|
|
3698
3437
|
}
|
|
3699
3438
|
break;
|
|
3700
|
-
|
|
3701
3439
|
case ToggleButtonKeyDownArrowDown:
|
|
3702
3440
|
{
|
|
3703
3441
|
const highlightedIndex = state.isOpen ? getNextWrappingIndex(1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false) : altKey && state.selectedItem == null ? -1 : getHighlightedIndexOnOpen(props, state, 1);
|
|
@@ -3707,7 +3445,6 @@
|
|
|
3707
3445
|
};
|
|
3708
3446
|
}
|
|
3709
3447
|
break;
|
|
3710
|
-
|
|
3711
3448
|
case ToggleButtonKeyDownArrowUp:
|
|
3712
3449
|
if (state.isOpen && altKey) {
|
|
3713
3450
|
changes = {
|
|
@@ -3724,10 +3461,8 @@
|
|
|
3724
3461
|
isOpen: true
|
|
3725
3462
|
};
|
|
3726
3463
|
}
|
|
3727
|
-
|
|
3728
3464
|
break;
|
|
3729
3465
|
// only triggered when menu is open.
|
|
3730
|
-
|
|
3731
3466
|
case ToggleButtonKeyDownEnter:
|
|
3732
3467
|
case ToggleButtonKeyDownSpaceButton:
|
|
3733
3468
|
changes = {
|
|
@@ -3738,40 +3473,34 @@
|
|
|
3738
3473
|
})
|
|
3739
3474
|
};
|
|
3740
3475
|
break;
|
|
3741
|
-
|
|
3742
3476
|
case ToggleButtonKeyDownHome:
|
|
3743
3477
|
changes = {
|
|
3744
3478
|
highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false),
|
|
3745
3479
|
isOpen: true
|
|
3746
3480
|
};
|
|
3747
3481
|
break;
|
|
3748
|
-
|
|
3749
3482
|
case ToggleButtonKeyDownEnd:
|
|
3750
3483
|
changes = {
|
|
3751
3484
|
highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false),
|
|
3752
3485
|
isOpen: true
|
|
3753
3486
|
};
|
|
3754
3487
|
break;
|
|
3755
|
-
|
|
3756
3488
|
case ToggleButtonKeyDownPageUp:
|
|
3757
3489
|
changes = {
|
|
3758
3490
|
highlightedIndex: getNextWrappingIndex(-10, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false)
|
|
3759
3491
|
};
|
|
3760
3492
|
break;
|
|
3761
|
-
|
|
3762
3493
|
case ToggleButtonKeyDownPageDown:
|
|
3763
3494
|
changes = {
|
|
3764
3495
|
highlightedIndex: getNextWrappingIndex(10, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false)
|
|
3765
3496
|
};
|
|
3766
3497
|
break;
|
|
3767
|
-
|
|
3768
3498
|
case ToggleButtonKeyDownEscape:
|
|
3769
3499
|
changes = {
|
|
3770
3500
|
isOpen: false,
|
|
3771
3501
|
highlightedIndex: -1
|
|
3772
3502
|
};
|
|
3773
3503
|
break;
|
|
3774
|
-
|
|
3775
3504
|
case ToggleButtonBlur:
|
|
3776
3505
|
changes = {
|
|
3777
3506
|
isOpen: false,
|
|
@@ -3781,33 +3510,30 @@
|
|
|
3781
3510
|
})
|
|
3782
3511
|
};
|
|
3783
3512
|
break;
|
|
3784
|
-
|
|
3785
3513
|
case FunctionSelectItem$1:
|
|
3786
3514
|
changes = {
|
|
3787
3515
|
selectedItem: action.selectedItem
|
|
3788
3516
|
};
|
|
3789
3517
|
break;
|
|
3790
|
-
|
|
3791
3518
|
default:
|
|
3792
3519
|
return downshiftCommonReducer(state, action, stateChangeTypes$2);
|
|
3793
3520
|
}
|
|
3794
|
-
|
|
3795
|
-
|
|
3521
|
+
return {
|
|
3522
|
+
...state,
|
|
3796
3523
|
...changes
|
|
3797
3524
|
};
|
|
3798
3525
|
}
|
|
3799
3526
|
/* eslint-enable complexity */
|
|
3800
3527
|
|
|
3801
3528
|
useSelect.stateChangeTypes = stateChangeTypes$2;
|
|
3802
|
-
|
|
3803
3529
|
function useSelect(userProps) {
|
|
3804
3530
|
if (userProps === void 0) {
|
|
3805
3531
|
userProps = {};
|
|
3806
3532
|
}
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3533
|
+
validatePropTypes$2(userProps, useSelect);
|
|
3534
|
+
// Props defaults and destructuring.
|
|
3535
|
+
const props = {
|
|
3536
|
+
...defaultProps$2,
|
|
3811
3537
|
...userProps
|
|
3812
3538
|
};
|
|
3813
3539
|
const {
|
|
@@ -3817,8 +3543,8 @@
|
|
|
3817
3543
|
itemToString,
|
|
3818
3544
|
getA11ySelectionMessage,
|
|
3819
3545
|
getA11yStatusMessage
|
|
3820
|
-
} = props;
|
|
3821
|
-
|
|
3546
|
+
} = props;
|
|
3547
|
+
// Initial state depending on controlled props.
|
|
3822
3548
|
const initialState = getInitialState$2(props);
|
|
3823
3549
|
const [state, dispatch] = useControlledReducer$1(downshiftSelectReducer, initialState, props);
|
|
3824
3550
|
const {
|
|
@@ -3826,27 +3552,30 @@
|
|
|
3826
3552
|
highlightedIndex,
|
|
3827
3553
|
selectedItem,
|
|
3828
3554
|
inputValue
|
|
3829
|
-
} = state;
|
|
3555
|
+
} = state;
|
|
3830
3556
|
|
|
3557
|
+
// Element efs.
|
|
3831
3558
|
const toggleButtonRef = react.useRef(null);
|
|
3832
3559
|
const menuRef = react.useRef(null);
|
|
3833
|
-
const itemRefs = react.useRef({});
|
|
3834
|
-
|
|
3835
|
-
const clearTimeoutRef = react.useRef(null);
|
|
3836
|
-
|
|
3837
|
-
const elementIds = useElementIds(props);
|
|
3838
|
-
|
|
3560
|
+
const itemRefs = react.useRef({});
|
|
3561
|
+
// used to keep the inputValue clearTimeout object between renders.
|
|
3562
|
+
const clearTimeoutRef = react.useRef(null);
|
|
3563
|
+
// prevent id re-generation between renders.
|
|
3564
|
+
const elementIds = useElementIds(props);
|
|
3565
|
+
// used to keep track of how many items we had on previous cycle.
|
|
3839
3566
|
const previousResultCountRef = react.useRef();
|
|
3840
|
-
const isInitialMountRef = react.useRef(true);
|
|
3841
|
-
|
|
3567
|
+
const isInitialMountRef = react.useRef(true);
|
|
3568
|
+
// utility callback to get item element.
|
|
3842
3569
|
const latest = useLatestRef({
|
|
3843
3570
|
state,
|
|
3844
3571
|
props
|
|
3845
|
-
});
|
|
3572
|
+
});
|
|
3846
3573
|
|
|
3847
|
-
|
|
3848
|
-
|
|
3574
|
+
// Some utils.
|
|
3575
|
+
const getItemNodeFromIndex = react.useCallback(index => itemRefs.current[elementIds.getItemId(index)], [elementIds]);
|
|
3849
3576
|
|
|
3577
|
+
// Effects.
|
|
3578
|
+
// Sets a11y status message on changes in state.
|
|
3850
3579
|
useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], {
|
|
3851
3580
|
isInitialMount: isInitialMountRef.current,
|
|
3852
3581
|
previousResultCount: previousResultCountRef.current,
|
|
@@ -3854,8 +3583,8 @@
|
|
|
3854
3583
|
environment,
|
|
3855
3584
|
itemToString,
|
|
3856
3585
|
...state
|
|
3857
|
-
});
|
|
3858
|
-
|
|
3586
|
+
});
|
|
3587
|
+
// Sets a11y status message on changes in selectedItem.
|
|
3859
3588
|
useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], {
|
|
3860
3589
|
isInitialMount: isInitialMountRef.current,
|
|
3861
3590
|
previousResultCount: previousResultCountRef.current,
|
|
@@ -3863,8 +3592,8 @@
|
|
|
3863
3592
|
environment,
|
|
3864
3593
|
itemToString,
|
|
3865
3594
|
...state
|
|
3866
|
-
});
|
|
3867
|
-
|
|
3595
|
+
});
|
|
3596
|
+
// Scroll on highlighted item if change comes from keyboard.
|
|
3868
3597
|
const shouldScrollRef = useScrollIntoView({
|
|
3869
3598
|
menuElement: menuRef.current,
|
|
3870
3599
|
highlightedIndex,
|
|
@@ -3872,8 +3601,9 @@
|
|
|
3872
3601
|
itemRefs,
|
|
3873
3602
|
scrollIntoView,
|
|
3874
3603
|
getItemNodeFromIndex
|
|
3875
|
-
});
|
|
3604
|
+
});
|
|
3876
3605
|
|
|
3606
|
+
// Sets cleanup for the keysSoFar callback, debounded after 500ms.
|
|
3877
3607
|
react.useEffect(() => {
|
|
3878
3608
|
// init the clean function here as we need access to dispatch.
|
|
3879
3609
|
clearTimeoutRef.current = debounce(outerDispatch => {
|
|
@@ -3881,18 +3611,19 @@
|
|
|
3881
3611
|
type: FunctionSetInputValue$1,
|
|
3882
3612
|
inputValue: ''
|
|
3883
3613
|
});
|
|
3884
|
-
}, 500);
|
|
3614
|
+
}, 500);
|
|
3885
3615
|
|
|
3616
|
+
// Cancel any pending debounced calls on mount
|
|
3886
3617
|
return () => {
|
|
3887
3618
|
clearTimeoutRef.current.cancel();
|
|
3888
3619
|
};
|
|
3889
|
-
}, []);
|
|
3620
|
+
}, []);
|
|
3890
3621
|
|
|
3622
|
+
// Invokes the keysSoFar callback set up above.
|
|
3891
3623
|
react.useEffect(() => {
|
|
3892
3624
|
if (!inputValue) {
|
|
3893
3625
|
return;
|
|
3894
3626
|
}
|
|
3895
|
-
|
|
3896
3627
|
clearTimeoutRef.current(dispatch);
|
|
3897
3628
|
}, [dispatch, inputValue]);
|
|
3898
3629
|
useControlPropsValidator({
|
|
@@ -3904,27 +3635,27 @@
|
|
|
3904
3635
|
if (isInitialMountRef.current) {
|
|
3905
3636
|
return;
|
|
3906
3637
|
}
|
|
3907
|
-
|
|
3908
3638
|
previousResultCountRef.current = items.length;
|
|
3909
|
-
});
|
|
3910
|
-
|
|
3639
|
+
});
|
|
3640
|
+
// Add mouse/touch events to document.
|
|
3911
3641
|
const mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [menuRef, toggleButtonRef], environment, () => {
|
|
3912
3642
|
dispatch({
|
|
3913
3643
|
type: ToggleButtonBlur
|
|
3914
3644
|
});
|
|
3915
3645
|
});
|
|
3916
|
-
const setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
|
|
3917
|
-
|
|
3646
|
+
const setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
|
|
3647
|
+
// Make initial ref false.
|
|
3918
3648
|
react.useEffect(() => {
|
|
3919
3649
|
isInitialMountRef.current = false;
|
|
3920
|
-
}, []);
|
|
3921
|
-
|
|
3650
|
+
}, []);
|
|
3651
|
+
// Reset itemRefs on close.
|
|
3922
3652
|
react.useEffect(() => {
|
|
3923
3653
|
if (!isOpen) {
|
|
3924
3654
|
itemRefs.current = {};
|
|
3925
3655
|
}
|
|
3926
|
-
}, [isOpen]);
|
|
3656
|
+
}, [isOpen]);
|
|
3927
3657
|
|
|
3658
|
+
// Event handler functions.
|
|
3928
3659
|
const toggleButtonKeyDownHandlers = react.useMemo(() => ({
|
|
3929
3660
|
ArrowDown(event) {
|
|
3930
3661
|
event.preventDefault();
|
|
@@ -3934,7 +3665,6 @@
|
|
|
3934
3665
|
altKey: event.altKey
|
|
3935
3666
|
});
|
|
3936
3667
|
},
|
|
3937
|
-
|
|
3938
3668
|
ArrowUp(event) {
|
|
3939
3669
|
event.preventDefault();
|
|
3940
3670
|
dispatch({
|
|
@@ -3943,7 +3673,6 @@
|
|
|
3943
3673
|
altKey: event.altKey
|
|
3944
3674
|
});
|
|
3945
3675
|
},
|
|
3946
|
-
|
|
3947
3676
|
Home(event) {
|
|
3948
3677
|
event.preventDefault();
|
|
3949
3678
|
dispatch({
|
|
@@ -3951,7 +3680,6 @@
|
|
|
3951
3680
|
getItemNodeFromIndex
|
|
3952
3681
|
});
|
|
3953
3682
|
},
|
|
3954
|
-
|
|
3955
3683
|
End(event) {
|
|
3956
3684
|
event.preventDefault();
|
|
3957
3685
|
dispatch({
|
|
@@ -3959,7 +3687,6 @@
|
|
|
3959
3687
|
getItemNodeFromIndex
|
|
3960
3688
|
});
|
|
3961
3689
|
},
|
|
3962
|
-
|
|
3963
3690
|
Escape() {
|
|
3964
3691
|
if (latest.current.state.isOpen) {
|
|
3965
3692
|
dispatch({
|
|
@@ -3967,7 +3694,6 @@
|
|
|
3967
3694
|
});
|
|
3968
3695
|
}
|
|
3969
3696
|
},
|
|
3970
|
-
|
|
3971
3697
|
Enter(event) {
|
|
3972
3698
|
if (latest.current.state.isOpen) {
|
|
3973
3699
|
event.preventDefault();
|
|
@@ -3976,7 +3702,6 @@
|
|
|
3976
3702
|
});
|
|
3977
3703
|
}
|
|
3978
3704
|
},
|
|
3979
|
-
|
|
3980
3705
|
PageUp(event) {
|
|
3981
3706
|
if (latest.current.state.isOpen) {
|
|
3982
3707
|
event.preventDefault();
|
|
@@ -3986,7 +3711,6 @@
|
|
|
3986
3711
|
});
|
|
3987
3712
|
}
|
|
3988
3713
|
},
|
|
3989
|
-
|
|
3990
3714
|
PageDown(event) {
|
|
3991
3715
|
if (latest.current.state.isOpen) {
|
|
3992
3716
|
event.preventDefault();
|
|
@@ -3996,7 +3720,6 @@
|
|
|
3996
3720
|
});
|
|
3997
3721
|
}
|
|
3998
3722
|
},
|
|
3999
|
-
|
|
4000
3723
|
' '(event) {
|
|
4001
3724
|
if (latest.current.state.isOpen) {
|
|
4002
3725
|
event.preventDefault();
|
|
@@ -4005,9 +3728,9 @@
|
|
|
4005
3728
|
});
|
|
4006
3729
|
}
|
|
4007
3730
|
}
|
|
3731
|
+
}), [dispatch, getItemNodeFromIndex, latest]);
|
|
4008
3732
|
|
|
4009
|
-
|
|
4010
|
-
|
|
3733
|
+
// Action functions.
|
|
4011
3734
|
const toggleMenu = react.useCallback(() => {
|
|
4012
3735
|
dispatch({
|
|
4013
3736
|
type: FunctionToggleMenu$1
|
|
@@ -4045,8 +3768,8 @@
|
|
|
4045
3768
|
type: FunctionSetInputValue$1,
|
|
4046
3769
|
inputValue: newInputValue
|
|
4047
3770
|
});
|
|
4048
|
-
}, [dispatch]);
|
|
4049
|
-
|
|
3771
|
+
}, [dispatch]);
|
|
3772
|
+
// Getter functions.
|
|
4050
3773
|
const getLabelProps = react.useCallback(labelProps => ({
|
|
4051
3774
|
id: elementIds.labelId,
|
|
4052
3775
|
htmlFor: elementIds.toggleButtonId,
|
|
@@ -4064,13 +3787,11 @@
|
|
|
4064
3787
|
let {
|
|
4065
3788
|
suppressRefError = false
|
|
4066
3789
|
} = _temp2 === void 0 ? {} : _temp2;
|
|
4067
|
-
|
|
4068
3790
|
const menuHandleMouseLeave = () => {
|
|
4069
3791
|
dispatch({
|
|
4070
3792
|
type: MenuMouseLeave$1
|
|
4071
3793
|
});
|
|
4072
3794
|
};
|
|
4073
|
-
|
|
4074
3795
|
setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
|
|
4075
3796
|
return {
|
|
4076
3797
|
[refKey]: handleRefs(ref, menuNode => {
|
|
@@ -4097,13 +3818,11 @@
|
|
|
4097
3818
|
suppressRefError = false
|
|
4098
3819
|
} = _temp4 === void 0 ? {} : _temp4;
|
|
4099
3820
|
const latestState = latest.current.state;
|
|
4100
|
-
|
|
4101
3821
|
const toggleButtonHandleClick = () => {
|
|
4102
3822
|
dispatch({
|
|
4103
3823
|
type: ToggleButtonClick$1
|
|
4104
3824
|
});
|
|
4105
3825
|
};
|
|
4106
|
-
|
|
4107
3826
|
const toggleButtonHandleBlur = () => {
|
|
4108
3827
|
if (latestState.isOpen && !mouseAndTouchTrackersRef.current.isMouseDown) {
|
|
4109
3828
|
dispatch({
|
|
@@ -4111,10 +3830,8 @@
|
|
|
4111
3830
|
});
|
|
4112
3831
|
}
|
|
4113
3832
|
};
|
|
4114
|
-
|
|
4115
3833
|
const toggleButtonHandleKeyDown = event => {
|
|
4116
3834
|
const key = normalizeArrowKey(event);
|
|
4117
|
-
|
|
4118
3835
|
if (key && toggleButtonKeyDownHandlers[key]) {
|
|
4119
3836
|
toggleButtonKeyDownHandlers[key](event);
|
|
4120
3837
|
} else if (isAcceptedCharacterKey(key)) {
|
|
@@ -4125,7 +3842,6 @@
|
|
|
4125
3842
|
});
|
|
4126
3843
|
}
|
|
4127
3844
|
};
|
|
4128
|
-
|
|
4129
3845
|
const toggleProps = {
|
|
4130
3846
|
[refKey]: handleRefs(ref, toggleButtonNode => {
|
|
4131
3847
|
toggleButtonRef.current = toggleButtonNode;
|
|
@@ -4141,12 +3857,10 @@
|
|
|
4141
3857
|
onBlur: callAllEventHandlers(onBlur, toggleButtonHandleBlur),
|
|
4142
3858
|
...rest
|
|
4143
3859
|
};
|
|
4144
|
-
|
|
4145
3860
|
if (!rest.disabled) {
|
|
4146
3861
|
toggleProps.onClick = callAllEventHandlers(onClick, toggleButtonHandleClick);
|
|
4147
3862
|
toggleProps.onKeyDown = callAllEventHandlers(onKeyDown, toggleButtonHandleKeyDown);
|
|
4148
3863
|
}
|
|
4149
|
-
|
|
4150
3864
|
setGetterPropCallInfo('getToggleButtonProps', suppressRefError, refKey, toggleButtonRef);
|
|
4151
3865
|
return toggleProps;
|
|
4152
3866
|
}, [latest, elementIds, setGetterPropCallInfo, dispatch, mouseAndTouchTrackersRef, toggleButtonKeyDownHandlers, getItemNodeFromIndex]);
|
|
@@ -4167,12 +3881,10 @@
|
|
|
4167
3881
|
} = latest.current;
|
|
4168
3882
|
const item = itemProp ?? items[indexProp];
|
|
4169
3883
|
const index = getItemIndex(indexProp, item, latestProps.items);
|
|
4170
|
-
|
|
4171
3884
|
const itemHandleMouseMove = () => {
|
|
4172
3885
|
if (index === latestState.highlightedIndex) {
|
|
4173
3886
|
return;
|
|
4174
3887
|
}
|
|
4175
|
-
|
|
4176
3888
|
shouldScrollRef.current = false;
|
|
4177
3889
|
dispatch({
|
|
4178
3890
|
type: ItemMouseMove$1,
|
|
@@ -4180,20 +3892,16 @@
|
|
|
4180
3892
|
disabled
|
|
4181
3893
|
});
|
|
4182
3894
|
};
|
|
4183
|
-
|
|
4184
3895
|
const itemHandleClick = () => {
|
|
4185
3896
|
dispatch({
|
|
4186
3897
|
type: ItemClick$1,
|
|
4187
3898
|
index
|
|
4188
3899
|
});
|
|
4189
3900
|
};
|
|
4190
|
-
|
|
4191
3901
|
const itemIndex = getItemIndex(index, item, latestProps.items);
|
|
4192
|
-
|
|
4193
3902
|
if (itemIndex < 0) {
|
|
4194
3903
|
throw new Error('Pass either item or item index in getItemProps!');
|
|
4195
3904
|
}
|
|
4196
|
-
|
|
4197
3905
|
const itemProps = {
|
|
4198
3906
|
disabled,
|
|
4199
3907
|
role: 'option',
|
|
@@ -4206,11 +3914,9 @@
|
|
|
4206
3914
|
}),
|
|
4207
3915
|
...rest
|
|
4208
3916
|
};
|
|
4209
|
-
|
|
4210
3917
|
if (!disabled) {
|
|
4211
3918
|
itemProps.onClick = callAllEventHandlers(onClick, itemHandleClick);
|
|
4212
3919
|
}
|
|
4213
|
-
|
|
4214
3920
|
itemProps.onMouseMove = callAllEventHandlers(onMouseMove, itemHandleMouseMove);
|
|
4215
3921
|
return itemProps;
|
|
4216
3922
|
}, [latest, items, selectedItem, elementIds, shouldScrollRef, dispatch]);
|
|
@@ -4295,16 +4001,14 @@
|
|
|
4295
4001
|
let {
|
|
4296
4002
|
inputValue
|
|
4297
4003
|
} = initialState;
|
|
4298
|
-
|
|
4299
4004
|
if (inputValue === '' && selectedItem && props.defaultInputValue === undefined && props.initialInputValue === undefined && props.inputValue === undefined) {
|
|
4300
4005
|
inputValue = props.itemToString(selectedItem);
|
|
4301
4006
|
}
|
|
4302
|
-
|
|
4303
|
-
|
|
4007
|
+
return {
|
|
4008
|
+
...initialState,
|
|
4304
4009
|
inputValue
|
|
4305
4010
|
};
|
|
4306
4011
|
}
|
|
4307
|
-
|
|
4308
4012
|
const propTypes$1 = {
|
|
4309
4013
|
items: PropTypes.array.isRequired,
|
|
4310
4014
|
itemToString: PropTypes.func,
|
|
@@ -4344,6 +4048,7 @@
|
|
|
4344
4048
|
})
|
|
4345
4049
|
})
|
|
4346
4050
|
};
|
|
4051
|
+
|
|
4347
4052
|
/**
|
|
4348
4053
|
* The useCombobox version of useControlledReducer, which also
|
|
4349
4054
|
* checks if the controlled prop selectedItem changed between
|
|
@@ -4356,11 +4061,11 @@
|
|
|
4356
4061
|
* @param {Object} props The hook props.
|
|
4357
4062
|
* @returns {Array} An array with the state and an action dispatcher.
|
|
4358
4063
|
*/
|
|
4359
|
-
|
|
4360
4064
|
function useControlledReducer(reducer, initialState, props) {
|
|
4361
4065
|
const previousSelectedItemRef = react.useRef();
|
|
4362
|
-
const [state, dispatch] = useEnhancedReducer(reducer, initialState, props);
|
|
4066
|
+
const [state, dispatch] = useEnhancedReducer(reducer, initialState, props);
|
|
4363
4067
|
|
|
4068
|
+
// ToDo: if needed, make same approach as selectedItemChanged from Downshift.
|
|
4364
4069
|
react.useEffect(() => {
|
|
4365
4070
|
if (isControlledProp(props, 'selectedItem')) {
|
|
4366
4071
|
if (previousSelectedItemRef.current !== props.selectedItem) {
|
|
@@ -4369,29 +4074,26 @@
|
|
|
4369
4074
|
inputValue: props.itemToString(props.selectedItem)
|
|
4370
4075
|
});
|
|
4371
4076
|
}
|
|
4372
|
-
|
|
4373
4077
|
previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
|
|
4374
4078
|
}
|
|
4375
4079
|
});
|
|
4376
4080
|
return [getState(state, props), dispatch];
|
|
4377
|
-
}
|
|
4378
|
-
|
|
4081
|
+
}
|
|
4379
4082
|
|
|
4083
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
4380
4084
|
let validatePropTypes$1 = noop;
|
|
4381
4085
|
/* istanbul ignore next */
|
|
4382
|
-
|
|
4383
4086
|
{
|
|
4384
4087
|
validatePropTypes$1 = (options, caller) => {
|
|
4385
4088
|
PropTypes.checkPropTypes(propTypes$1, options, 'prop', caller.name);
|
|
4386
4089
|
};
|
|
4387
4090
|
}
|
|
4388
|
-
|
|
4389
|
-
|
|
4091
|
+
const defaultProps$1 = {
|
|
4092
|
+
...defaultProps$3,
|
|
4390
4093
|
getA11yStatusMessage: getA11yStatusMessage$1
|
|
4391
4094
|
};
|
|
4392
4095
|
|
|
4393
4096
|
/* eslint-disable complexity */
|
|
4394
|
-
|
|
4395
4097
|
function downshiftUseComboboxReducer(state, action) {
|
|
4396
4098
|
const {
|
|
4397
4099
|
type,
|
|
@@ -4399,7 +4101,6 @@
|
|
|
4399
4101
|
altKey
|
|
4400
4102
|
} = action;
|
|
4401
4103
|
let changes;
|
|
4402
|
-
|
|
4403
4104
|
switch (type) {
|
|
4404
4105
|
case ItemClick:
|
|
4405
4106
|
changes = {
|
|
@@ -4409,7 +4110,6 @@
|
|
|
4409
4110
|
inputValue: props.itemToString(props.items[action.index])
|
|
4410
4111
|
};
|
|
4411
4112
|
break;
|
|
4412
|
-
|
|
4413
4113
|
case InputKeyDownArrowDown:
|
|
4414
4114
|
if (state.isOpen) {
|
|
4415
4115
|
changes = {
|
|
@@ -4421,9 +4121,7 @@
|
|
|
4421
4121
|
isOpen: props.items.length >= 0
|
|
4422
4122
|
};
|
|
4423
4123
|
}
|
|
4424
|
-
|
|
4425
4124
|
break;
|
|
4426
|
-
|
|
4427
4125
|
case InputKeyDownArrowUp:
|
|
4428
4126
|
if (state.isOpen) {
|
|
4429
4127
|
if (altKey) {
|
|
@@ -4446,9 +4144,7 @@
|
|
|
4446
4144
|
isOpen: props.items.length >= 0
|
|
4447
4145
|
};
|
|
4448
4146
|
}
|
|
4449
|
-
|
|
4450
4147
|
break;
|
|
4451
|
-
|
|
4452
4148
|
case InputKeyDownEnter:
|
|
4453
4149
|
changes = {
|
|
4454
4150
|
isOpen: getDefaultValue$1(props, 'isOpen'),
|
|
@@ -4459,7 +4155,6 @@
|
|
|
4459
4155
|
})
|
|
4460
4156
|
};
|
|
4461
4157
|
break;
|
|
4462
|
-
|
|
4463
4158
|
case InputKeyDownEscape:
|
|
4464
4159
|
changes = {
|
|
4465
4160
|
isOpen: false,
|
|
@@ -4470,31 +4165,26 @@
|
|
|
4470
4165
|
})
|
|
4471
4166
|
};
|
|
4472
4167
|
break;
|
|
4473
|
-
|
|
4474
4168
|
case InputKeyDownPageUp:
|
|
4475
4169
|
changes = {
|
|
4476
4170
|
highlightedIndex: getNextWrappingIndex(-10, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false)
|
|
4477
4171
|
};
|
|
4478
4172
|
break;
|
|
4479
|
-
|
|
4480
4173
|
case InputKeyDownPageDown:
|
|
4481
4174
|
changes = {
|
|
4482
4175
|
highlightedIndex: getNextWrappingIndex(10, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, false)
|
|
4483
4176
|
};
|
|
4484
4177
|
break;
|
|
4485
|
-
|
|
4486
4178
|
case InputKeyDownHome:
|
|
4487
4179
|
changes = {
|
|
4488
4180
|
highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false)
|
|
4489
4181
|
};
|
|
4490
4182
|
break;
|
|
4491
|
-
|
|
4492
4183
|
case InputKeyDownEnd:
|
|
4493
4184
|
changes = {
|
|
4494
4185
|
highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false)
|
|
4495
4186
|
};
|
|
4496
4187
|
break;
|
|
4497
|
-
|
|
4498
4188
|
case InputBlur:
|
|
4499
4189
|
changes = {
|
|
4500
4190
|
isOpen: false,
|
|
@@ -4505,7 +4195,6 @@
|
|
|
4505
4195
|
})
|
|
4506
4196
|
};
|
|
4507
4197
|
break;
|
|
4508
|
-
|
|
4509
4198
|
case InputChange:
|
|
4510
4199
|
changes = {
|
|
4511
4200
|
isOpen: true,
|
|
@@ -4513,32 +4202,28 @@
|
|
|
4513
4202
|
inputValue: action.inputValue
|
|
4514
4203
|
};
|
|
4515
4204
|
break;
|
|
4516
|
-
|
|
4517
4205
|
case InputFocus:
|
|
4518
4206
|
changes = {
|
|
4519
4207
|
isOpen: true,
|
|
4520
4208
|
highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
|
|
4521
4209
|
};
|
|
4522
4210
|
break;
|
|
4523
|
-
|
|
4524
4211
|
case FunctionSelectItem:
|
|
4525
4212
|
changes = {
|
|
4526
4213
|
selectedItem: action.selectedItem,
|
|
4527
4214
|
inputValue: props.itemToString(action.selectedItem)
|
|
4528
4215
|
};
|
|
4529
4216
|
break;
|
|
4530
|
-
|
|
4531
4217
|
case ControlledPropUpdatedSelectedItem:
|
|
4532
4218
|
changes = {
|
|
4533
4219
|
inputValue: action.inputValue
|
|
4534
4220
|
};
|
|
4535
4221
|
break;
|
|
4536
|
-
|
|
4537
4222
|
default:
|
|
4538
4223
|
return downshiftCommonReducer(state, action, stateChangeTypes$1);
|
|
4539
4224
|
}
|
|
4540
|
-
|
|
4541
|
-
|
|
4225
|
+
return {
|
|
4226
|
+
...state,
|
|
4542
4227
|
...changes
|
|
4543
4228
|
};
|
|
4544
4229
|
}
|
|
@@ -4546,15 +4231,14 @@
|
|
|
4546
4231
|
|
|
4547
4232
|
/* eslint-disable max-statements */
|
|
4548
4233
|
useCombobox.stateChangeTypes = stateChangeTypes$1;
|
|
4549
|
-
|
|
4550
4234
|
function useCombobox(userProps) {
|
|
4551
4235
|
if (userProps === void 0) {
|
|
4552
4236
|
userProps = {};
|
|
4553
4237
|
}
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4238
|
+
validatePropTypes$1(userProps, useCombobox);
|
|
4239
|
+
// Props defaults and destructuring.
|
|
4240
|
+
const props = {
|
|
4241
|
+
...defaultProps$1,
|
|
4558
4242
|
...userProps
|
|
4559
4243
|
};
|
|
4560
4244
|
const {
|
|
@@ -4566,8 +4250,8 @@
|
|
|
4566
4250
|
getA11yStatusMessage,
|
|
4567
4251
|
getA11ySelectionMessage,
|
|
4568
4252
|
itemToString
|
|
4569
|
-
} = props;
|
|
4570
|
-
|
|
4253
|
+
} = props;
|
|
4254
|
+
// Initial state depending on controlled props.
|
|
4571
4255
|
const initialState = getInitialState$1(props);
|
|
4572
4256
|
const [state, dispatch] = useControlledReducer(downshiftUseComboboxReducer, initialState, props);
|
|
4573
4257
|
const {
|
|
@@ -4575,25 +4259,27 @@
|
|
|
4575
4259
|
highlightedIndex,
|
|
4576
4260
|
selectedItem,
|
|
4577
4261
|
inputValue
|
|
4578
|
-
} = state;
|
|
4262
|
+
} = state;
|
|
4579
4263
|
|
|
4264
|
+
// Element refs.
|
|
4580
4265
|
const menuRef = react.useRef(null);
|
|
4581
4266
|
const itemRefs = react.useRef({});
|
|
4582
4267
|
const inputRef = react.useRef(null);
|
|
4583
4268
|
const toggleButtonRef = react.useRef(null);
|
|
4584
|
-
const isInitialMountRef = react.useRef(true);
|
|
4585
|
-
|
|
4586
|
-
const elementIds = useElementIds(props);
|
|
4587
|
-
|
|
4588
|
-
const previousResultCountRef = react.useRef();
|
|
4589
|
-
|
|
4269
|
+
const isInitialMountRef = react.useRef(true);
|
|
4270
|
+
// prevent id re-generation between renders.
|
|
4271
|
+
const elementIds = useElementIds(props);
|
|
4272
|
+
// used to keep track of how many items we had on previous cycle.
|
|
4273
|
+
const previousResultCountRef = react.useRef();
|
|
4274
|
+
// utility callback to get item element.
|
|
4590
4275
|
const latest = useLatestRef({
|
|
4591
4276
|
state,
|
|
4592
4277
|
props
|
|
4593
4278
|
});
|
|
4594
|
-
const getItemNodeFromIndex = react.useCallback(index => itemRefs.current[elementIds.getItemId(index)], [elementIds]);
|
|
4595
|
-
// Sets a11y status message on changes in state.
|
|
4279
|
+
const getItemNodeFromIndex = react.useCallback(index => itemRefs.current[elementIds.getItemId(index)], [elementIds]);
|
|
4596
4280
|
|
|
4281
|
+
// Effects.
|
|
4282
|
+
// Sets a11y status message on changes in state.
|
|
4597
4283
|
useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], {
|
|
4598
4284
|
isInitialMount: isInitialMountRef.current,
|
|
4599
4285
|
previousResultCount: previousResultCountRef.current,
|
|
@@ -4601,8 +4287,8 @@
|
|
|
4601
4287
|
environment,
|
|
4602
4288
|
itemToString,
|
|
4603
4289
|
...state
|
|
4604
|
-
});
|
|
4605
|
-
|
|
4290
|
+
});
|
|
4291
|
+
// Sets a11y status message on changes in selectedItem.
|
|
4606
4292
|
useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], {
|
|
4607
4293
|
isInitialMount: isInitialMountRef.current,
|
|
4608
4294
|
previousResultCount: previousResultCountRef.current,
|
|
@@ -4610,8 +4296,8 @@
|
|
|
4610
4296
|
environment,
|
|
4611
4297
|
itemToString,
|
|
4612
4298
|
...state
|
|
4613
|
-
});
|
|
4614
|
-
|
|
4299
|
+
});
|
|
4300
|
+
// Scroll on highlighted item if change comes from keyboard.
|
|
4615
4301
|
const shouldScrollRef = useScrollIntoView({
|
|
4616
4302
|
menuElement: menuRef.current,
|
|
4617
4303
|
highlightedIndex,
|
|
@@ -4624,47 +4310,44 @@
|
|
|
4624
4310
|
isInitialMount: isInitialMountRef.current,
|
|
4625
4311
|
props,
|
|
4626
4312
|
state
|
|
4627
|
-
});
|
|
4628
|
-
|
|
4313
|
+
});
|
|
4314
|
+
// Focus the input on first render if required.
|
|
4629
4315
|
react.useEffect(() => {
|
|
4630
4316
|
const focusOnOpen = initialIsOpen || defaultIsOpen || isOpen;
|
|
4631
|
-
|
|
4632
4317
|
if (focusOnOpen && inputRef.current) {
|
|
4633
4318
|
inputRef.current.focus();
|
|
4634
|
-
}
|
|
4635
|
-
|
|
4319
|
+
}
|
|
4320
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
4636
4321
|
}, []);
|
|
4637
4322
|
react.useEffect(() => {
|
|
4638
4323
|
if (isInitialMountRef.current) {
|
|
4639
4324
|
return;
|
|
4640
4325
|
}
|
|
4641
|
-
|
|
4642
4326
|
previousResultCountRef.current = items.length;
|
|
4643
|
-
});
|
|
4644
|
-
|
|
4327
|
+
});
|
|
4328
|
+
// Add mouse/touch events to document.
|
|
4645
4329
|
const mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [inputRef, menuRef, toggleButtonRef], environment, () => {
|
|
4646
4330
|
dispatch({
|
|
4647
4331
|
type: InputBlur,
|
|
4648
4332
|
selectItem: false
|
|
4649
4333
|
});
|
|
4650
4334
|
});
|
|
4651
|
-
const setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
|
|
4652
|
-
|
|
4335
|
+
const setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
|
|
4336
|
+
// Make initial ref false.
|
|
4653
4337
|
react.useEffect(() => {
|
|
4654
4338
|
isInitialMountRef.current = false;
|
|
4655
|
-
}, []);
|
|
4656
|
-
|
|
4339
|
+
}, []);
|
|
4340
|
+
// Reset itemRefs on close.
|
|
4657
4341
|
react.useEffect(() => {
|
|
4658
4342
|
if (!isOpen) {
|
|
4659
4343
|
itemRefs.current = {};
|
|
4660
4344
|
} else if (document.activeElement !== inputRef.current) {
|
|
4661
4345
|
var _inputRef$current;
|
|
4662
|
-
|
|
4663
4346
|
inputRef == null ? void 0 : (_inputRef$current = inputRef.current) == null ? void 0 : _inputRef$current.focus();
|
|
4664
4347
|
}
|
|
4665
4348
|
}, [isOpen]);
|
|
4666
|
-
/* Event handler functions */
|
|
4667
4349
|
|
|
4350
|
+
/* Event handler functions */
|
|
4668
4351
|
const inputKeyDownHandlers = react.useMemo(() => ({
|
|
4669
4352
|
ArrowDown(event) {
|
|
4670
4353
|
event.preventDefault();
|
|
@@ -4674,7 +4357,6 @@
|
|
|
4674
4357
|
getItemNodeFromIndex
|
|
4675
4358
|
});
|
|
4676
4359
|
},
|
|
4677
|
-
|
|
4678
4360
|
ArrowUp(event) {
|
|
4679
4361
|
event.preventDefault();
|
|
4680
4362
|
dispatch({
|
|
@@ -4683,34 +4365,28 @@
|
|
|
4683
4365
|
getItemNodeFromIndex
|
|
4684
4366
|
});
|
|
4685
4367
|
},
|
|
4686
|
-
|
|
4687
4368
|
Home(event) {
|
|
4688
4369
|
if (!latest.current.state.isOpen) {
|
|
4689
4370
|
return;
|
|
4690
4371
|
}
|
|
4691
|
-
|
|
4692
4372
|
event.preventDefault();
|
|
4693
4373
|
dispatch({
|
|
4694
4374
|
type: InputKeyDownHome,
|
|
4695
4375
|
getItemNodeFromIndex
|
|
4696
4376
|
});
|
|
4697
4377
|
},
|
|
4698
|
-
|
|
4699
4378
|
End(event) {
|
|
4700
4379
|
if (!latest.current.state.isOpen) {
|
|
4701
4380
|
return;
|
|
4702
4381
|
}
|
|
4703
|
-
|
|
4704
4382
|
event.preventDefault();
|
|
4705
4383
|
dispatch({
|
|
4706
4384
|
type: InputKeyDownEnd,
|
|
4707
4385
|
getItemNodeFromIndex
|
|
4708
4386
|
});
|
|
4709
4387
|
},
|
|
4710
|
-
|
|
4711
4388
|
Escape(event) {
|
|
4712
4389
|
const latestState = latest.current.state;
|
|
4713
|
-
|
|
4714
4390
|
if (latestState.isOpen || latestState.inputValue || latestState.selectedItem || latestState.highlightedIndex > -1) {
|
|
4715
4391
|
event.preventDefault();
|
|
4716
4392
|
dispatch({
|
|
@@ -4718,22 +4394,19 @@
|
|
|
4718
4394
|
});
|
|
4719
4395
|
}
|
|
4720
4396
|
},
|
|
4721
|
-
|
|
4722
4397
|
Enter(event) {
|
|
4723
|
-
const latestState = latest.current.state;
|
|
4724
|
-
|
|
4398
|
+
const latestState = latest.current.state;
|
|
4399
|
+
// if closed or no highlighted index, do nothing.
|
|
4725
4400
|
if (!latestState.isOpen || event.which === 229 // if IME composing, wait for next Enter keydown event.
|
|
4726
4401
|
) {
|
|
4727
4402
|
return;
|
|
4728
4403
|
}
|
|
4729
|
-
|
|
4730
4404
|
event.preventDefault();
|
|
4731
4405
|
dispatch({
|
|
4732
4406
|
type: InputKeyDownEnter,
|
|
4733
4407
|
getItemNodeFromIndex
|
|
4734
4408
|
});
|
|
4735
4409
|
},
|
|
4736
|
-
|
|
4737
4410
|
PageUp(event) {
|
|
4738
4411
|
if (latest.current.state.isOpen) {
|
|
4739
4412
|
event.preventDefault();
|
|
@@ -4743,7 +4416,6 @@
|
|
|
4743
4416
|
});
|
|
4744
4417
|
}
|
|
4745
4418
|
},
|
|
4746
|
-
|
|
4747
4419
|
PageDown(event) {
|
|
4748
4420
|
if (latest.current.state.isOpen) {
|
|
4749
4421
|
event.preventDefault();
|
|
@@ -4753,9 +4425,9 @@
|
|
|
4753
4425
|
});
|
|
4754
4426
|
}
|
|
4755
4427
|
}
|
|
4428
|
+
}), [dispatch, latest, getItemNodeFromIndex]);
|
|
4756
4429
|
|
|
4757
|
-
|
|
4758
|
-
|
|
4430
|
+
// Getter props.
|
|
4759
4431
|
const getLabelProps = react.useCallback(labelProps => ({
|
|
4760
4432
|
id: elementIds.labelId,
|
|
4761
4433
|
htmlFor: elementIds.inputId,
|
|
@@ -4805,19 +4477,15 @@
|
|
|
4805
4477
|
state: latestState
|
|
4806
4478
|
} = latest.current;
|
|
4807
4479
|
const itemIndex = getItemIndex(index, item, latestProps.items);
|
|
4808
|
-
|
|
4809
4480
|
if (itemIndex < 0) {
|
|
4810
4481
|
throw new Error('Pass either item or item index in getItemProps!');
|
|
4811
4482
|
}
|
|
4812
|
-
|
|
4813
4483
|
const onSelectKey = 'onClick';
|
|
4814
4484
|
const customClickHandler = onClick;
|
|
4815
|
-
|
|
4816
4485
|
const itemHandleMouseMove = () => {
|
|
4817
4486
|
if (index === latestState.highlightedIndex) {
|
|
4818
4487
|
return;
|
|
4819
4488
|
}
|
|
4820
|
-
|
|
4821
4489
|
shouldScrollRef.current = false;
|
|
4822
4490
|
dispatch({
|
|
4823
4491
|
type: ItemMouseMove,
|
|
@@ -4825,16 +4493,13 @@
|
|
|
4825
4493
|
disabled
|
|
4826
4494
|
});
|
|
4827
4495
|
};
|
|
4828
|
-
|
|
4829
4496
|
const itemHandleClick = () => {
|
|
4830
4497
|
dispatch({
|
|
4831
4498
|
type: ItemClick,
|
|
4832
4499
|
index
|
|
4833
4500
|
});
|
|
4834
4501
|
};
|
|
4835
|
-
|
|
4836
4502
|
const itemHandleMouseDown = e => e.preventDefault();
|
|
4837
|
-
|
|
4838
4503
|
return {
|
|
4839
4504
|
[refKey]: handleRefs(ref, itemNode => {
|
|
4840
4505
|
if (itemNode) {
|
|
@@ -4862,13 +4527,11 @@
|
|
|
4862
4527
|
...rest
|
|
4863
4528
|
} = _temp4 === void 0 ? {} : _temp4;
|
|
4864
4529
|
const latestState = latest.current.state;
|
|
4865
|
-
|
|
4866
4530
|
const toggleButtonHandleClick = () => {
|
|
4867
4531
|
dispatch({
|
|
4868
4532
|
type: ToggleButtonClick
|
|
4869
4533
|
});
|
|
4870
4534
|
};
|
|
4871
|
-
|
|
4872
4535
|
return {
|
|
4873
4536
|
[refKey]: handleRefs(ref, toggleButtonNode => {
|
|
4874
4537
|
toggleButtonRef.current = toggleButtonNode;
|
|
@@ -4877,7 +4540,8 @@
|
|
|
4877
4540
|
'aria-expanded': latestState.isOpen,
|
|
4878
4541
|
id: elementIds.toggleButtonId,
|
|
4879
4542
|
tabIndex: -1,
|
|
4880
|
-
...(!rest.disabled && {
|
|
4543
|
+
...(!rest.disabled && {
|
|
4544
|
+
...({
|
|
4881
4545
|
onClick: callAllEventHandlers(onClick, toggleButtonHandleClick)
|
|
4882
4546
|
})
|
|
4883
4547
|
}),
|
|
@@ -4901,22 +4565,18 @@
|
|
|
4901
4565
|
} = _temp6 === void 0 ? {} : _temp6;
|
|
4902
4566
|
setGetterPropCallInfo('getInputProps', suppressRefError, refKey, inputRef);
|
|
4903
4567
|
const latestState = latest.current.state;
|
|
4904
|
-
|
|
4905
4568
|
const inputHandleKeyDown = event => {
|
|
4906
4569
|
const key = normalizeArrowKey(event);
|
|
4907
|
-
|
|
4908
4570
|
if (key && inputKeyDownHandlers[key]) {
|
|
4909
4571
|
inputKeyDownHandlers[key](event);
|
|
4910
4572
|
}
|
|
4911
4573
|
};
|
|
4912
|
-
|
|
4913
4574
|
const inputHandleChange = event => {
|
|
4914
4575
|
dispatch({
|
|
4915
4576
|
type: InputChange,
|
|
4916
4577
|
inputValue: event.target.value
|
|
4917
4578
|
});
|
|
4918
4579
|
};
|
|
4919
|
-
|
|
4920
4580
|
const inputHandleBlur = () => {
|
|
4921
4581
|
/* istanbul ignore else */
|
|
4922
4582
|
if (latestState.isOpen && !mouseAndTouchTrackersRef.current.isMouseDown) {
|
|
@@ -4926,7 +4586,6 @@
|
|
|
4926
4586
|
});
|
|
4927
4587
|
}
|
|
4928
4588
|
};
|
|
4929
|
-
|
|
4930
4589
|
const inputHandleFocus = () => {
|
|
4931
4590
|
if (!latestState.isOpen) {
|
|
4932
4591
|
dispatch({
|
|
@@ -4934,12 +4593,10 @@
|
|
|
4934
4593
|
});
|
|
4935
4594
|
}
|
|
4936
4595
|
};
|
|
4937
|
-
/* istanbul ignore next (preact) */
|
|
4938
|
-
|
|
4939
4596
|
|
|
4597
|
+
/* istanbul ignore next (preact) */
|
|
4940
4598
|
const onChangeKey = 'onChange';
|
|
4941
4599
|
let eventHandlers = {};
|
|
4942
|
-
|
|
4943
4600
|
if (!rest.disabled) {
|
|
4944
4601
|
eventHandlers = {
|
|
4945
4602
|
[onChangeKey]: callAllEventHandlers(onChange, onInput, inputHandleChange),
|
|
@@ -4948,7 +4605,6 @@
|
|
|
4948
4605
|
onFocus: callAllEventHandlers(onFocus, inputHandleFocus)
|
|
4949
4606
|
};
|
|
4950
4607
|
}
|
|
4951
|
-
|
|
4952
4608
|
return {
|
|
4953
4609
|
[refKey]: handleRefs(ref, inputNode => {
|
|
4954
4610
|
inputRef.current = inputNode;
|
|
@@ -4967,8 +4623,9 @@
|
|
|
4967
4623
|
...eventHandlers,
|
|
4968
4624
|
...rest
|
|
4969
4625
|
};
|
|
4970
|
-
}, [dispatch, inputKeyDownHandlers, latest, mouseAndTouchTrackersRef, setGetterPropCallInfo, elementIds]);
|
|
4626
|
+
}, [dispatch, inputKeyDownHandlers, latest, mouseAndTouchTrackersRef, setGetterPropCallInfo, elementIds]);
|
|
4971
4627
|
|
|
4628
|
+
// returns
|
|
4972
4629
|
const toggleMenu = react.useCallback(() => {
|
|
4973
4630
|
dispatch({
|
|
4974
4631
|
type: FunctionToggleMenu
|
|
@@ -5034,6 +4691,7 @@
|
|
|
5034
4691
|
activeIndex: -1,
|
|
5035
4692
|
selectedItems: []
|
|
5036
4693
|
};
|
|
4694
|
+
|
|
5037
4695
|
/**
|
|
5038
4696
|
* Returns the initial value for a state key in the following order:
|
|
5039
4697
|
* 1. controlled prop, 2. initial prop, 3. default prop, 4. default
|
|
@@ -5043,10 +4701,10 @@
|
|
|
5043
4701
|
* @param {string} propKey Props key to generate the value for.
|
|
5044
4702
|
* @returns {any} The initial value for that prop.
|
|
5045
4703
|
*/
|
|
5046
|
-
|
|
5047
4704
|
function getInitialValue(props, propKey) {
|
|
5048
4705
|
return getInitialValue$1(props, propKey, defaultStateValues);
|
|
5049
4706
|
}
|
|
4707
|
+
|
|
5050
4708
|
/**
|
|
5051
4709
|
* Returns the default value for a state key in the following order:
|
|
5052
4710
|
* 1. controlled prop, 2. default prop, 3. default value from Downshift.
|
|
@@ -5055,11 +4713,10 @@
|
|
|
5055
4713
|
* @param {string} propKey Props key to generate the value for.
|
|
5056
4714
|
* @returns {any} The initial value for that prop.
|
|
5057
4715
|
*/
|
|
5058
|
-
|
|
5059
|
-
|
|
5060
4716
|
function getDefaultValue(props, propKey) {
|
|
5061
4717
|
return getDefaultValue$1(props, propKey, defaultStateValues);
|
|
5062
4718
|
}
|
|
4719
|
+
|
|
5063
4720
|
/**
|
|
5064
4721
|
* Gets the initial state based on the provided props. It uses initial, default
|
|
5065
4722
|
* and controlled props related to state in order to compute the initial value.
|
|
@@ -5067,8 +4724,6 @@
|
|
|
5067
4724
|
* @param {Object} props Props passed to the hook.
|
|
5068
4725
|
* @returns {Object} The initial state.
|
|
5069
4726
|
*/
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
4727
|
function getInitialState(props) {
|
|
5073
4728
|
const activeIndex = getInitialValue(props, 'activeIndex');
|
|
5074
4729
|
const selectedItems = getInitialValue(props, 'selectedItems');
|
|
@@ -5077,6 +4732,7 @@
|
|
|
5077
4732
|
selectedItems
|
|
5078
4733
|
};
|
|
5079
4734
|
}
|
|
4735
|
+
|
|
5080
4736
|
/**
|
|
5081
4737
|
* Returns true if dropdown keydown operation is permitted. Should not be
|
|
5082
4738
|
* allowed on keydown with modifier keys (ctrl, alt, shift, meta), on
|
|
@@ -5086,32 +4742,28 @@
|
|
|
5086
4742
|
* @param {KeyboardEvent} event The event from keydown.
|
|
5087
4743
|
* @returns {boolean} Whether the operation is allowed.
|
|
5088
4744
|
*/
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
4745
|
function isKeyDownOperationPermitted(event) {
|
|
5092
4746
|
if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey) {
|
|
5093
4747
|
return false;
|
|
5094
4748
|
}
|
|
5095
|
-
|
|
5096
4749
|
const element = event.target;
|
|
5097
|
-
|
|
5098
|
-
|
|
5099
|
-
element.value !== '' && (
|
|
4750
|
+
if (element instanceof HTMLInputElement &&
|
|
4751
|
+
// if element is a text input
|
|
4752
|
+
element.value !== '' && (
|
|
4753
|
+
// and we have text in it
|
|
5100
4754
|
// and cursor is either not at the start or is currently highlighting text.
|
|
5101
4755
|
element.selectionStart !== 0 || element.selectionEnd !== 0)) {
|
|
5102
4756
|
return false;
|
|
5103
4757
|
}
|
|
5104
|
-
|
|
5105
4758
|
return true;
|
|
5106
4759
|
}
|
|
4760
|
+
|
|
5107
4761
|
/**
|
|
5108
4762
|
* Returns a message to be added to aria-live region when item is removed.
|
|
5109
4763
|
*
|
|
5110
4764
|
* @param {Object} selectionParameters Parameters required to build the message.
|
|
5111
4765
|
* @returns {string} The a11y message.
|
|
5112
4766
|
*/
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
4767
|
function getA11yRemovalMessage(selectionParameters) {
|
|
5116
4768
|
const {
|
|
5117
4769
|
removedSelectedItem,
|
|
@@ -5119,7 +4771,6 @@
|
|
|
5119
4771
|
} = selectionParameters;
|
|
5120
4772
|
return `${itemToStringLocal(removedSelectedItem)} has been removed.`;
|
|
5121
4773
|
}
|
|
5122
|
-
|
|
5123
4774
|
const propTypes = {
|
|
5124
4775
|
selectedItems: PropTypes.array,
|
|
5125
4776
|
initialSelectedItems: PropTypes.array,
|
|
@@ -5151,11 +4802,11 @@
|
|
|
5151
4802
|
getA11yRemovalMessage,
|
|
5152
4803
|
keyNavigationNext: 'ArrowRight',
|
|
5153
4804
|
keyNavigationPrevious: 'ArrowLeft'
|
|
5154
|
-
};
|
|
4805
|
+
};
|
|
5155
4806
|
|
|
4807
|
+
// eslint-disable-next-line import/no-mutable-exports
|
|
5156
4808
|
let validatePropTypes = noop;
|
|
5157
4809
|
/* istanbul ignore next */
|
|
5158
|
-
|
|
5159
4810
|
{
|
|
5160
4811
|
validatePropTypes = (options, caller) => {
|
|
5161
4812
|
PropTypes.checkPropTypes(propTypes, options, 'prop', caller.name);
|
|
@@ -5194,7 +4845,6 @@
|
|
|
5194
4845
|
});
|
|
5195
4846
|
|
|
5196
4847
|
/* eslint-disable complexity */
|
|
5197
|
-
|
|
5198
4848
|
function downshiftMultipleSelectionReducer(state, action) {
|
|
5199
4849
|
const {
|
|
5200
4850
|
type,
|
|
@@ -5207,37 +4857,31 @@
|
|
|
5207
4857
|
selectedItems
|
|
5208
4858
|
} = state;
|
|
5209
4859
|
let changes;
|
|
5210
|
-
|
|
5211
4860
|
switch (type) {
|
|
5212
4861
|
case SelectedItemClick:
|
|
5213
4862
|
changes = {
|
|
5214
4863
|
activeIndex: index
|
|
5215
4864
|
};
|
|
5216
4865
|
break;
|
|
5217
|
-
|
|
5218
4866
|
case SelectedItemKeyDownNavigationPrevious:
|
|
5219
4867
|
changes = {
|
|
5220
4868
|
activeIndex: activeIndex - 1 < 0 ? 0 : activeIndex - 1
|
|
5221
4869
|
};
|
|
5222
4870
|
break;
|
|
5223
|
-
|
|
5224
4871
|
case SelectedItemKeyDownNavigationNext:
|
|
5225
4872
|
changes = {
|
|
5226
4873
|
activeIndex: activeIndex + 1 >= selectedItems.length ? -1 : activeIndex + 1
|
|
5227
4874
|
};
|
|
5228
4875
|
break;
|
|
5229
|
-
|
|
5230
4876
|
case SelectedItemKeyDownBackspace:
|
|
5231
4877
|
case SelectedItemKeyDownDelete:
|
|
5232
4878
|
{
|
|
5233
4879
|
let newActiveIndex = activeIndex;
|
|
5234
|
-
|
|
5235
4880
|
if (selectedItems.length === 1) {
|
|
5236
4881
|
newActiveIndex = -1;
|
|
5237
4882
|
} else if (activeIndex === selectedItems.length - 1) {
|
|
5238
4883
|
newActiveIndex = selectedItems.length - 2;
|
|
5239
4884
|
}
|
|
5240
|
-
|
|
5241
4885
|
changes = {
|
|
5242
4886
|
selectedItems: [...selectedItems.slice(0, activeIndex), ...selectedItems.slice(activeIndex + 1)],
|
|
5243
4887
|
...{
|
|
@@ -5246,52 +4890,43 @@
|
|
|
5246
4890
|
};
|
|
5247
4891
|
break;
|
|
5248
4892
|
}
|
|
5249
|
-
|
|
5250
4893
|
case DropdownKeyDownNavigationPrevious:
|
|
5251
4894
|
changes = {
|
|
5252
4895
|
activeIndex: selectedItems.length - 1
|
|
5253
4896
|
};
|
|
5254
4897
|
break;
|
|
5255
|
-
|
|
5256
4898
|
case DropdownKeyDownBackspace:
|
|
5257
4899
|
changes = {
|
|
5258
4900
|
selectedItems: selectedItems.slice(0, selectedItems.length - 1)
|
|
5259
4901
|
};
|
|
5260
4902
|
break;
|
|
5261
|
-
|
|
5262
4903
|
case FunctionAddSelectedItem:
|
|
5263
4904
|
changes = {
|
|
5264
4905
|
selectedItems: [...selectedItems, selectedItem]
|
|
5265
4906
|
};
|
|
5266
4907
|
break;
|
|
5267
|
-
|
|
5268
4908
|
case DropdownClick:
|
|
5269
4909
|
changes = {
|
|
5270
4910
|
activeIndex: -1
|
|
5271
4911
|
};
|
|
5272
4912
|
break;
|
|
5273
|
-
|
|
5274
4913
|
case FunctionRemoveSelectedItem:
|
|
5275
4914
|
{
|
|
5276
4915
|
let newActiveIndex = activeIndex;
|
|
5277
4916
|
const selectedItemIndex = selectedItems.indexOf(selectedItem);
|
|
5278
|
-
|
|
5279
4917
|
if (selectedItemIndex >= 0) {
|
|
5280
4918
|
if (selectedItems.length === 1) {
|
|
5281
4919
|
newActiveIndex = -1;
|
|
5282
4920
|
} else if (selectedItemIndex === selectedItems.length - 1) {
|
|
5283
4921
|
newActiveIndex = selectedItems.length - 2;
|
|
5284
4922
|
}
|
|
5285
|
-
|
|
5286
4923
|
changes = {
|
|
5287
4924
|
selectedItems: [...selectedItems.slice(0, selectedItemIndex), ...selectedItems.slice(selectedItemIndex + 1)],
|
|
5288
4925
|
activeIndex: newActiveIndex
|
|
5289
4926
|
};
|
|
5290
4927
|
}
|
|
5291
|
-
|
|
5292
4928
|
break;
|
|
5293
4929
|
}
|
|
5294
|
-
|
|
5295
4930
|
case FunctionSetSelectedItems:
|
|
5296
4931
|
{
|
|
5297
4932
|
const {
|
|
@@ -5302,7 +4937,6 @@
|
|
|
5302
4937
|
};
|
|
5303
4938
|
break;
|
|
5304
4939
|
}
|
|
5305
|
-
|
|
5306
4940
|
case FunctionSetActiveIndex:
|
|
5307
4941
|
{
|
|
5308
4942
|
const {
|
|
@@ -5313,33 +4947,30 @@
|
|
|
5313
4947
|
};
|
|
5314
4948
|
break;
|
|
5315
4949
|
}
|
|
5316
|
-
|
|
5317
4950
|
case FunctionReset:
|
|
5318
4951
|
changes = {
|
|
5319
4952
|
activeIndex: getDefaultValue(props, 'activeIndex'),
|
|
5320
4953
|
selectedItems: getDefaultValue(props, 'selectedItems')
|
|
5321
4954
|
};
|
|
5322
4955
|
break;
|
|
5323
|
-
|
|
5324
4956
|
default:
|
|
5325
4957
|
throw new Error('Reducer called without proper action type.');
|
|
5326
4958
|
}
|
|
5327
|
-
|
|
5328
|
-
|
|
4959
|
+
return {
|
|
4960
|
+
...state,
|
|
5329
4961
|
...changes
|
|
5330
4962
|
};
|
|
5331
4963
|
}
|
|
5332
4964
|
|
|
5333
4965
|
useMultipleSelection.stateChangeTypes = stateChangeTypes;
|
|
5334
|
-
|
|
5335
4966
|
function useMultipleSelection(userProps) {
|
|
5336
4967
|
if (userProps === void 0) {
|
|
5337
4968
|
userProps = {};
|
|
5338
4969
|
}
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
|
|
5342
|
-
|
|
4970
|
+
validatePropTypes(userProps, useMultipleSelection);
|
|
4971
|
+
// Props defaults and destructuring.
|
|
4972
|
+
const props = {
|
|
4973
|
+
...defaultProps,
|
|
5343
4974
|
...userProps
|
|
5344
4975
|
};
|
|
5345
4976
|
const {
|
|
@@ -5348,14 +4979,16 @@
|
|
|
5348
4979
|
environment,
|
|
5349
4980
|
keyNavigationNext,
|
|
5350
4981
|
keyNavigationPrevious
|
|
5351
|
-
} = props;
|
|
4982
|
+
} = props;
|
|
5352
4983
|
|
|
4984
|
+
// Reducer init.
|
|
5353
4985
|
const [state, dispatch] = useControlledReducer$1(downshiftMultipleSelectionReducer, getInitialState(props), props);
|
|
5354
4986
|
const {
|
|
5355
4987
|
activeIndex,
|
|
5356
4988
|
selectedItems
|
|
5357
|
-
} = state;
|
|
4989
|
+
} = state;
|
|
5358
4990
|
|
|
4991
|
+
// Refs.
|
|
5359
4992
|
const isInitialMountRef = react.useRef(true);
|
|
5360
4993
|
const dropdownRef = react.useRef(null);
|
|
5361
4994
|
const previousSelectedItemsRef = react.useRef(selectedItems);
|
|
@@ -5364,15 +4997,14 @@
|
|
|
5364
4997
|
const latest = useLatestRef({
|
|
5365
4998
|
state,
|
|
5366
4999
|
props
|
|
5367
|
-
});
|
|
5000
|
+
});
|
|
5368
5001
|
|
|
5002
|
+
// Effects.
|
|
5369
5003
|
/* Sets a11y status message on changes in selectedItem. */
|
|
5370
|
-
|
|
5371
5004
|
react.useEffect(() => {
|
|
5372
5005
|
if (isInitialMountRef.current) {
|
|
5373
5006
|
return;
|
|
5374
5007
|
}
|
|
5375
|
-
|
|
5376
5008
|
if (selectedItems.length < previousSelectedItemsRef.current.length) {
|
|
5377
5009
|
const removedSelectedItem = previousSelectedItemsRef.current.find(item => selectedItems.indexOf(item) < 0);
|
|
5378
5010
|
setStatus(getA11yRemovalMessage({
|
|
@@ -5383,15 +5015,15 @@
|
|
|
5383
5015
|
activeSelectedItem: selectedItems[activeIndex]
|
|
5384
5016
|
}), environment.document);
|
|
5385
5017
|
}
|
|
5018
|
+
previousSelectedItemsRef.current = selectedItems;
|
|
5386
5019
|
|
|
5387
|
-
|
|
5388
|
-
}, [selectedItems.length]);
|
|
5389
|
-
|
|
5020
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5021
|
+
}, [selectedItems.length]);
|
|
5022
|
+
// Sets focus on active item.
|
|
5390
5023
|
react.useEffect(() => {
|
|
5391
5024
|
if (isInitialMountRef.current) {
|
|
5392
5025
|
return;
|
|
5393
5026
|
}
|
|
5394
|
-
|
|
5395
5027
|
if (activeIndex === -1 && dropdownRef.current) {
|
|
5396
5028
|
dropdownRef.current.focus();
|
|
5397
5029
|
} else if (selectedItemRefs.current[activeIndex]) {
|
|
@@ -5403,37 +5035,34 @@
|
|
|
5403
5035
|
props,
|
|
5404
5036
|
state
|
|
5405
5037
|
});
|
|
5406
|
-
const setGetterPropCallInfo = useGetterPropsCalledChecker('getDropdownProps');
|
|
5407
|
-
|
|
5038
|
+
const setGetterPropCallInfo = useGetterPropsCalledChecker('getDropdownProps');
|
|
5039
|
+
// Make initial ref false.
|
|
5408
5040
|
react.useEffect(() => {
|
|
5409
5041
|
isInitialMountRef.current = false;
|
|
5410
|
-
}, []);
|
|
5042
|
+
}, []);
|
|
5411
5043
|
|
|
5044
|
+
// Event handler functions.
|
|
5412
5045
|
const selectedItemKeyDownHandlers = react.useMemo(() => ({
|
|
5413
5046
|
[keyNavigationPrevious]() {
|
|
5414
5047
|
dispatch({
|
|
5415
5048
|
type: SelectedItemKeyDownNavigationPrevious
|
|
5416
5049
|
});
|
|
5417
5050
|
},
|
|
5418
|
-
|
|
5419
5051
|
[keyNavigationNext]() {
|
|
5420
5052
|
dispatch({
|
|
5421
5053
|
type: SelectedItemKeyDownNavigationNext
|
|
5422
5054
|
});
|
|
5423
5055
|
},
|
|
5424
|
-
|
|
5425
5056
|
Delete() {
|
|
5426
5057
|
dispatch({
|
|
5427
5058
|
type: SelectedItemKeyDownDelete
|
|
5428
5059
|
});
|
|
5429
5060
|
},
|
|
5430
|
-
|
|
5431
5061
|
Backspace() {
|
|
5432
5062
|
dispatch({
|
|
5433
5063
|
type: SelectedItemKeyDownBackspace
|
|
5434
5064
|
});
|
|
5435
5065
|
}
|
|
5436
|
-
|
|
5437
5066
|
}), [dispatch, keyNavigationNext, keyNavigationPrevious]);
|
|
5438
5067
|
const dropdownKeyDownHandlers = react.useMemo(() => ({
|
|
5439
5068
|
[keyNavigationPrevious](event) {
|
|
@@ -5443,7 +5072,6 @@
|
|
|
5443
5072
|
});
|
|
5444
5073
|
}
|
|
5445
5074
|
},
|
|
5446
|
-
|
|
5447
5075
|
Backspace(event) {
|
|
5448
5076
|
if (isKeyDownOperationPermitted(event)) {
|
|
5449
5077
|
dispatch({
|
|
@@ -5451,9 +5079,9 @@
|
|
|
5451
5079
|
});
|
|
5452
5080
|
}
|
|
5453
5081
|
}
|
|
5082
|
+
}), [dispatch, keyNavigationPrevious]);
|
|
5454
5083
|
|
|
5455
|
-
|
|
5456
|
-
|
|
5084
|
+
// Getter props.
|
|
5457
5085
|
const getSelectedItemProps = react.useCallback(function (_temp) {
|
|
5458
5086
|
let {
|
|
5459
5087
|
refKey = 'ref',
|
|
@@ -5468,26 +5096,21 @@
|
|
|
5468
5096
|
state: latestState
|
|
5469
5097
|
} = latest.current;
|
|
5470
5098
|
const itemIndex = getItemIndex(index, selectedItem, latestState.selectedItems);
|
|
5471
|
-
|
|
5472
5099
|
if (itemIndex < 0) {
|
|
5473
5100
|
throw new Error('Pass either selectedItem or index in getSelectedItemProps!');
|
|
5474
5101
|
}
|
|
5475
|
-
|
|
5476
5102
|
const selectedItemHandleClick = () => {
|
|
5477
5103
|
dispatch({
|
|
5478
5104
|
type: SelectedItemClick,
|
|
5479
5105
|
index
|
|
5480
5106
|
});
|
|
5481
5107
|
};
|
|
5482
|
-
|
|
5483
5108
|
const selectedItemHandleKeyDown = event => {
|
|
5484
5109
|
const key = normalizeArrowKey(event);
|
|
5485
|
-
|
|
5486
5110
|
if (key && selectedItemKeyDownHandlers[key]) {
|
|
5487
5111
|
selectedItemKeyDownHandlers[key](event);
|
|
5488
5112
|
}
|
|
5489
5113
|
};
|
|
5490
|
-
|
|
5491
5114
|
return {
|
|
5492
5115
|
[refKey]: handleRefs(ref, selectedItemNode => {
|
|
5493
5116
|
if (selectedItemNode) {
|
|
@@ -5513,21 +5136,17 @@
|
|
|
5513
5136
|
suppressRefError = false
|
|
5514
5137
|
} = _temp3 === void 0 ? {} : _temp3;
|
|
5515
5138
|
setGetterPropCallInfo('getDropdownProps', suppressRefError, refKey, dropdownRef);
|
|
5516
|
-
|
|
5517
5139
|
const dropdownHandleKeyDown = event => {
|
|
5518
5140
|
const key = normalizeArrowKey(event);
|
|
5519
|
-
|
|
5520
5141
|
if (key && dropdownKeyDownHandlers[key]) {
|
|
5521
5142
|
dropdownKeyDownHandlers[key](event);
|
|
5522
5143
|
}
|
|
5523
5144
|
};
|
|
5524
|
-
|
|
5525
5145
|
const dropdownHandleClick = () => {
|
|
5526
5146
|
dispatch({
|
|
5527
5147
|
type: DropdownClick
|
|
5528
5148
|
});
|
|
5529
5149
|
};
|
|
5530
|
-
|
|
5531
5150
|
return {
|
|
5532
5151
|
[refKey]: handleRefs(ref, dropdownNode => {
|
|
5533
5152
|
if (dropdownNode) {
|
|
@@ -5540,8 +5159,9 @@
|
|
|
5540
5159
|
}),
|
|
5541
5160
|
...rest
|
|
5542
5161
|
};
|
|
5543
|
-
}, [dispatch, dropdownKeyDownHandlers, setGetterPropCallInfo]);
|
|
5162
|
+
}, [dispatch, dropdownKeyDownHandlers, setGetterPropCallInfo]);
|
|
5544
5163
|
|
|
5164
|
+
// returns
|
|
5545
5165
|
const addSelectedItem = react.useCallback(selectedItem => {
|
|
5546
5166
|
dispatch({
|
|
5547
5167
|
type: FunctionAddSelectedItem,
|