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.
@@ -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
- } // eslint-disable-next-line import/no-mutable-exports
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'; // we want to call `onInputValueChange` before the `setState` call
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, { ...this.getStateAndHelpers(),
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; // Your own function that could modify the state that will be set.
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
- newStateToSet = this.props.stateReducer(state, newStateToSet); // checks if an item is selected, regardless of if it's different from
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
- isItemSelected = newStateToSet.hasOwnProperty('selectedItem'); // this keeps track of the object we want to call with setState
1913
-
1914
- const nextState = {}; // this is just used to tell whether the state changed
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
- } // the type is useful for the onStateChangeArg
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
- newStateToSet[key]; // if it's coming from props, then we don't care to set it internally
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
- }); // if stateToSet is a function, then we weren't able to call onInputValueChange
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, { ...this.getStateAndHelpers(),
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)(); // only call the onStateChange and onChange callbacks if
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
- } // this is currently undocumented and therefore subject to change
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 = { ...this.keyDownHandlers,
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 = { ...this.keyDownHandlers,
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
- } // get next non-disabled starting downwards from 0 if that's disabled.
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
- } // get next non-disabled starting upwards from last index if that's disabled.
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(); // handle odd case for Safari and Firefox which
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
- } // to simplify testing components that use downshift, we'll not wrap this in a setTimeout
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
- }); // We never want to manually scroll when changing state based
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
- }; // Passing down the onMouseDown handler to prevent redirect
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
- } //////////////////////////// ROOT
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; // if the target element or the activeElement is within a downshift node
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
- }; // Touching an element in iOS gives focus and hover states, but touching out of
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); // because the items are rerendered every time we call the children
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
- this.clearItems(); // we reset this so we know whether the user calls getRootProps during
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; // we do something similar for getMenuProps
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; // we do something similar for getLabelProps
2807
-
2808
- this.getLabelProps.called = false; // and something similar for getInputProps
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); // istanbul ignore next
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); // technically this is not "concurrent mode safe" because we're manipulating
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, { ...action,
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
- } // initialHighlightedIndex will give value to highlightedIndex on initial state only.
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
- }; // eslint-disable-next-line react-hooks/exhaustive-deps
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); // eslint-disable-next-line react-hooks/exhaustive-deps
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); // Scroll on highlighted item if change comes from keyboard.
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
- } // eslint-disable-next-line react-hooks/exhaustive-deps
3403
-
3155
+ }
3156
+ // eslint-disable-next-line react-hooks/exhaustive-deps
3404
3157
  }, [highlightedIndex]);
3405
3158
  return shouldScrollRef;
3406
- } // eslint-disable-next-line import/no-mutable-exports
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
- return { ...state,
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
- return { ...state,
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
- validatePropTypes$2(userProps, useSelect); // Props defaults and destructuring.
3809
-
3810
- const props = { ...defaultProps$2,
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; // Initial state depending on controlled 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; // Element efs.
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({}); // used to keep the inputValue clearTimeout object between renders.
3834
-
3835
- const clearTimeoutRef = react.useRef(null); // prevent id re-generation between renders.
3836
-
3837
- const elementIds = useElementIds(props); // used to keep track of how many items we had on previous cycle.
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); // utility callback to get item element.
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
- }); // Some utils.
3572
+ });
3846
3573
 
3847
- const getItemNodeFromIndex = react.useCallback(index => itemRefs.current[elementIds.getItemId(index)], [elementIds]); // Effects.
3848
- // Sets a11y status message on changes in state.
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
- }); // Sets a11y status message on changes in selectedItem.
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
- }); // Scroll on highlighted item if change comes from keyboard.
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
- }); // Sets cleanup for the keysSoFar callback, debounded after 500ms.
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); // Cancel any pending debounced calls on mount
3614
+ }, 500);
3885
3615
 
3616
+ // Cancel any pending debounced calls on mount
3886
3617
  return () => {
3887
3618
  clearTimeoutRef.current.cancel();
3888
3619
  };
3889
- }, []); // Invokes the keysSoFar callback set up above.
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
- }); // Add mouse/touch events to document.
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'); // Make initial ref false.
3917
-
3646
+ const setGetterPropCallInfo = useGetterPropsCalledChecker('getMenuProps', 'getToggleButtonProps');
3647
+ // Make initial ref false.
3918
3648
  react.useEffect(() => {
3919
3649
  isInitialMountRef.current = false;
3920
- }, []); // Reset itemRefs on close.
3921
-
3650
+ }, []);
3651
+ // Reset itemRefs on close.
3922
3652
  react.useEffect(() => {
3923
3653
  if (!isOpen) {
3924
3654
  itemRefs.current = {};
3925
3655
  }
3926
- }, [isOpen]); // Event handler functions.
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
- }), [dispatch, getItemNodeFromIndex, latest]); // Action functions.
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]); // Getter functions.
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
- return { ...initialState,
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); // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
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
- } // eslint-disable-next-line import/no-mutable-exports
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
- const defaultProps$1 = { ...defaultProps$3,
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
- return { ...state,
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
- validatePropTypes$1(userProps, useCombobox); // Props defaults and destructuring.
4556
-
4557
- const props = { ...defaultProps$1,
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; // Initial state depending on controlled 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; // Element refs.
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); // prevent id re-generation between renders.
4585
-
4586
- const elementIds = useElementIds(props); // used to keep track of how many items we had on previous cycle.
4587
-
4588
- const previousResultCountRef = react.useRef(); // utility callback to get item element.
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]); // Effects.
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
- }); // Sets a11y status message on changes in selectedItem.
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
- }); // Scroll on highlighted item if change comes from keyboard.
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
- }); // Focus the input on first render if required.
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
- } // eslint-disable-next-line react-hooks/exhaustive-deps
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
- }); // Add mouse/touch events to document.
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'); // Make initial ref false.
4652
-
4335
+ const setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getMenuProps');
4336
+ // Make initial ref false.
4653
4337
  react.useEffect(() => {
4654
4338
  isInitialMountRef.current = false;
4655
- }, []); // Reset itemRefs on close.
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; // if closed or no highlighted index, do nothing.
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
- }), [dispatch, latest, getItemNodeFromIndex]); // Getter props.
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]); // returns
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
- if (element instanceof HTMLInputElement && // if element is a text input
5099
- element.value !== '' && ( // and we have text in it
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
- }; // eslint-disable-next-line import/no-mutable-exports
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
- return { ...state,
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
- validatePropTypes(userProps, useMultipleSelection); // Props defaults and destructuring.
5341
-
5342
- const props = { ...defaultProps,
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; // Reducer init.
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; // Refs.
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
- }); // Effects.
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
- previousSelectedItemsRef.current = selectedItems; // eslint-disable-next-line react-hooks/exhaustive-deps
5388
- }, [selectedItems.length]); // Sets focus on active item.
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'); // Make initial ref false.
5407
-
5038
+ const setGetterPropCallInfo = useGetterPropsCalledChecker('getDropdownProps');
5039
+ // Make initial ref false.
5408
5040
  react.useEffect(() => {
5409
5041
  isInitialMountRef.current = false;
5410
- }, []); // Event handler functions.
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
- }), [dispatch, keyNavigationPrevious]); // Getter props.
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]); // returns
5162
+ }, [dispatch, dropdownKeyDownHandlers, setGetterPropCallInfo]);
5544
5163
 
5164
+ // returns
5545
5165
  const addSelectedItem = react.useCallback(selectedItem => {
5546
5166
  dispatch({
5547
5167
  type: FunctionAddSelectedItem,