downshift 3.4.4 → 3.4.8

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.
@@ -409,1066 +409,1072 @@ var stateChangeTypes = /*#__PURE__*/Object.freeze({
409
409
 
410
410
  var Downshift =
411
411
  /*#__PURE__*/
412
- function (_Component) {
413
- _inheritsLoose(Downshift, _Component);
412
+ function () {
413
+ var Downshift =
414
+ /*#__PURE__*/
415
+ function (_Component) {
416
+ _inheritsLoose(Downshift, _Component);
417
+
418
+ function Downshift(_props) {
419
+ var _this = _Component.call(this, _props) || this;
420
+
421
+ _this.id = _this.props.id || "downshift-" + generateId();
422
+ _this.menuId = _this.props.menuId || _this.id + "-menu";
423
+ _this.labelId = _this.props.labelId || _this.id + "-label";
424
+ _this.inputId = _this.props.inputId || _this.id + "-input";
425
+
426
+ _this.getItemId = _this.props.getItemId || function (index) {
427
+ return _this.id + "-item-" + index;
428
+ };
414
429
 
415
- function Downshift(_props) {
416
- var _this = _Component.call(this, _props) || this;
430
+ _this.input = null;
431
+ _this.items = [];
432
+ _this.itemCount = null;
433
+ _this.previousResultCount = 0;
434
+ _this.timeoutIds = [];
417
435
 
418
- _this.id = _this.props.id || "downshift-" + generateId();
419
- _this.menuId = _this.props.menuId || _this.id + "-menu";
420
- _this.labelId = _this.props.labelId || _this.id + "-label";
421
- _this.inputId = _this.props.inputId || _this.id + "-input";
436
+ _this.internalSetTimeout = function (fn, time) {
437
+ var id = setTimeout(function () {
438
+ _this.timeoutIds = _this.timeoutIds.filter(function (i) {
439
+ return i !== id;
440
+ });
441
+ fn();
442
+ }, time);
422
443
 
423
- _this.getItemId = _this.props.getItemId || function (index) {
424
- return _this.id + "-item-" + index;
425
- };
444
+ _this.timeoutIds.push(id);
445
+ };
426
446
 
427
- _this.input = null;
428
- _this.items = [];
429
- _this.itemCount = null;
430
- _this.previousResultCount = 0;
431
- _this.timeoutIds = [];
447
+ _this.setItemCount = function (count) {
448
+ _this.itemCount = count;
449
+ };
432
450
 
433
- _this.internalSetTimeout = function (fn, time) {
434
- var id = setTimeout(function () {
435
- _this.timeoutIds = _this.timeoutIds.filter(function (i) {
436
- return i !== id;
437
- });
438
- fn();
439
- }, time);
451
+ _this.unsetItemCount = function () {
452
+ _this.itemCount = null;
453
+ };
440
454
 
441
- _this.timeoutIds.push(id);
442
- };
455
+ _this.setHighlightedIndex = function (highlightedIndex, otherStateToSet) {
456
+ if (highlightedIndex === void 0) {
457
+ highlightedIndex = _this.props.defaultHighlightedIndex;
458
+ }
443
459
 
444
- _this.setItemCount = function (count) {
445
- _this.itemCount = count;
446
- };
460
+ if (otherStateToSet === void 0) {
461
+ otherStateToSet = {};
462
+ }
447
463
 
448
- _this.unsetItemCount = function () {
449
- _this.itemCount = null;
450
- };
464
+ otherStateToSet = pickState(otherStateToSet);
451
465
 
452
- _this.setHighlightedIndex = function (highlightedIndex, otherStateToSet) {
453
- if (highlightedIndex === void 0) {
454
- highlightedIndex = _this.props.defaultHighlightedIndex;
455
- }
466
+ _this.internalSetState(_extends({
467
+ highlightedIndex: highlightedIndex
468
+ }, otherStateToSet));
469
+ };
456
470
 
457
- if (otherStateToSet === void 0) {
458
- otherStateToSet = {};
459
- }
471
+ _this.clearSelection = function (cb) {
472
+ _this.internalSetState({
473
+ selectedItem: null,
474
+ inputValue: '',
475
+ highlightedIndex: _this.props.defaultHighlightedIndex,
476
+ isOpen: _this.props.defaultIsOpen
477
+ }, cb);
478
+ };
460
479
 
461
- otherStateToSet = pickState(otherStateToSet);
480
+ _this.selectItem = function (item, otherStateToSet, cb) {
481
+ otherStateToSet = pickState(otherStateToSet);
462
482
 
463
- _this.internalSetState(_extends({
464
- highlightedIndex: highlightedIndex
465
- }, otherStateToSet));
466
- };
483
+ _this.internalSetState(_extends({
484
+ isOpen: _this.props.defaultIsOpen,
485
+ highlightedIndex: _this.props.defaultHighlightedIndex,
486
+ selectedItem: item,
487
+ inputValue: _this.props.itemToString(item)
488
+ }, otherStateToSet), cb);
489
+ };
467
490
 
468
- _this.clearSelection = function (cb) {
469
- _this.internalSetState({
470
- selectedItem: null,
471
- inputValue: '',
472
- highlightedIndex: _this.props.defaultHighlightedIndex,
473
- isOpen: _this.props.defaultIsOpen
474
- }, cb);
475
- };
491
+ _this.selectItemAtIndex = function (itemIndex, otherStateToSet, cb) {
492
+ var item = _this.items[itemIndex];
476
493
 
477
- _this.selectItem = function (item, otherStateToSet, cb) {
478
- otherStateToSet = pickState(otherStateToSet);
494
+ if (item == null) {
495
+ return;
496
+ }
479
497
 
480
- _this.internalSetState(_extends({
481
- isOpen: _this.props.defaultIsOpen,
482
- highlightedIndex: _this.props.defaultHighlightedIndex,
483
- selectedItem: item,
484
- inputValue: _this.props.itemToString(item)
485
- }, otherStateToSet), cb);
486
- };
498
+ _this.selectItem(item, otherStateToSet, cb);
499
+ };
487
500
 
488
- _this.selectItemAtIndex = function (itemIndex, otherStateToSet, cb) {
489
- var item = _this.items[itemIndex];
501
+ _this.selectHighlightedItem = function (otherStateToSet, cb) {
502
+ return _this.selectItemAtIndex(_this.getState().highlightedIndex, otherStateToSet, cb);
503
+ };
490
504
 
491
- if (item == null) {
492
- return;
493
- }
505
+ _this.internalSetState = function (stateToSet, cb) {
506
+ var isItemSelected, onChangeArg;
507
+ var onStateChangeArg = {};
508
+ var isStateToSetFunction = typeof stateToSet === 'function'; // we want to call `onInputValueChange` before the `setState` call
509
+ // so someone controlling the `inputValue` state gets notified of
510
+ // the input change as soon as possible. This avoids issues with
511
+ // preserving the cursor position.
512
+ // See https://github.com/downshift-js/downshift/issues/217 for more info.
513
+
514
+ if (!isStateToSetFunction && stateToSet.hasOwnProperty('inputValue')) {
515
+ _this.props.onInputValueChange(stateToSet.inputValue, _extends({}, _this.getStateAndHelpers(), {}, stateToSet));
516
+ }
494
517
 
495
- _this.selectItem(item, otherStateToSet, cb);
496
- };
518
+ return _this.setState(function (state) {
519
+ state = _this.getState(state);
520
+ var newStateToSet = isStateToSetFunction ? stateToSet(state) : stateToSet; // Your own function that could modify the state that will be set.
497
521
 
498
- _this.selectHighlightedItem = function (otherStateToSet, cb) {
499
- return _this.selectItemAtIndex(_this.getState().highlightedIndex, otherStateToSet, cb);
500
- };
522
+ newStateToSet = _this.props.stateReducer(state, newStateToSet); // checks if an item is selected, regardless of if it's different from
523
+ // what was selected before
524
+ // used to determine if onSelect and onChange callbacks should be called
501
525
 
502
- _this.internalSetState = function (stateToSet, cb) {
503
- var isItemSelected, onChangeArg;
504
- var onStateChangeArg = {};
505
- var isStateToSetFunction = typeof stateToSet === 'function'; // we want to call `onInputValueChange` before the `setState` call
506
- // so someone controlling the `inputValue` state gets notified of
507
- // the input change as soon as possible. This avoids issues with
508
- // preserving the cursor position.
509
- // See https://github.com/downshift-js/downshift/issues/217 for more info.
510
-
511
- if (!isStateToSetFunction && stateToSet.hasOwnProperty('inputValue')) {
512
- _this.props.onInputValueChange(stateToSet.inputValue, _extends({}, _this.getStateAndHelpers(), {}, stateToSet));
513
- }
526
+ isItemSelected = newStateToSet.hasOwnProperty('selectedItem'); // this keeps track of the object we want to call with setState
514
527
 
515
- return _this.setState(function (state) {
516
- state = _this.getState(state);
517
- var newStateToSet = isStateToSetFunction ? stateToSet(state) : stateToSet; // Your own function that could modify the state that will be set.
528
+ var nextState = {}; // this is just used to tell whether the state changed
518
529
 
519
- newStateToSet = _this.props.stateReducer(state, newStateToSet); // checks if an item is selected, regardless of if it's different from
520
- // what was selected before
521
- // used to determine if onSelect and onChange callbacks should be called
530
+ var nextFullState = {}; // we need to call on change if the outside world is controlling any of our state
531
+ // and we're trying to update that state. OR if the selection has changed and we're
532
+ // trying to update the selection
522
533
 
523
- isItemSelected = newStateToSet.hasOwnProperty('selectedItem'); // this keeps track of the object we want to call with setState
534
+ if (isItemSelected && newStateToSet.selectedItem !== state.selectedItem) {
535
+ onChangeArg = newStateToSet.selectedItem;
536
+ }
524
537
 
525
- var nextState = {}; // this is just used to tell whether the state changed
538
+ newStateToSet.type = newStateToSet.type || unknown;
539
+ Object.keys(newStateToSet).forEach(function (key) {
540
+ // onStateChangeArg should only have the state that is
541
+ // actually changing
542
+ if (state[key] !== newStateToSet[key]) {
543
+ onStateChangeArg[key] = newStateToSet[key];
544
+ } // the type is useful for the onStateChangeArg
545
+ // but we don't actually want to set it in internal state.
546
+ // this is an undocumented feature for now... Not all internalSetState
547
+ // calls support it and I'm not certain we want them to yet.
548
+ // But it enables users controlling the isOpen state to know when
549
+ // the isOpen state changes due to mouseup events which is quite handy.
550
+
551
+
552
+ if (key === 'type') {
553
+ return;
554
+ }
526
555
 
527
- var nextFullState = {}; // we need to call on change if the outside world is controlling any of our state
528
- // and we're trying to update that state. OR if the selection has changed and we're
529
- // trying to update the selection
556
+ nextFullState[key] = newStateToSet[key]; // if it's coming from props, then we don't care to set it internally
530
557
 
531
- if (isItemSelected && newStateToSet.selectedItem !== state.selectedItem) {
532
- onChangeArg = newStateToSet.selectedItem;
533
- }
558
+ if (!_this.isControlledProp(key)) {
559
+ nextState[key] = newStateToSet[key];
560
+ }
561
+ }); // if stateToSet is a function, then we weren't able to call onInputValueChange
562
+ // earlier, so we'll call it now that we know what the inputValue state will be.
534
563
 
535
- newStateToSet.type = newStateToSet.type || unknown;
536
- Object.keys(newStateToSet).forEach(function (key) {
537
- // onStateChangeArg should only have the state that is
538
- // actually changing
539
- if (state[key] !== newStateToSet[key]) {
540
- onStateChangeArg[key] = newStateToSet[key];
541
- } // the type is useful for the onStateChangeArg
542
- // but we don't actually want to set it in internal state.
543
- // this is an undocumented feature for now... Not all internalSetState
544
- // calls support it and I'm not certain we want them to yet.
545
- // But it enables users controlling the isOpen state to know when
546
- // the isOpen state changes due to mouseup events which is quite handy.
547
-
548
-
549
- if (key === 'type') {
550
- return;
564
+ if (isStateToSetFunction && newStateToSet.hasOwnProperty('inputValue')) {
565
+ _this.props.onInputValueChange(newStateToSet.inputValue, _extends({}, _this.getStateAndHelpers(), {}, newStateToSet));
551
566
  }
552
567
 
553
- nextFullState[key] = newStateToSet[key]; // if it's coming from props, then we don't care to set it internally
568
+ return nextState;
569
+ }, function () {
570
+ // call the provided callback if it's a function
571
+ cbToCb(cb)(); // only call the onStateChange and onChange callbacks if
572
+ // we have relevant information to pass them.
554
573
 
555
- if (!_this.isControlledProp(key)) {
556
- nextState[key] = newStateToSet[key];
557
- }
558
- }); // if stateToSet is a function, then we weren't able to call onInputValueChange
559
- // earlier, so we'll call it now that we know what the inputValue state will be.
574
+ var hasMoreStateThanType = Object.keys(onStateChangeArg).length > 1;
560
575
 
561
- if (isStateToSetFunction && newStateToSet.hasOwnProperty('inputValue')) {
562
- _this.props.onInputValueChange(newStateToSet.inputValue, _extends({}, _this.getStateAndHelpers(), {}, newStateToSet));
563
- }
576
+ if (hasMoreStateThanType) {
577
+ _this.props.onStateChange(onStateChangeArg, _this.getStateAndHelpers());
578
+ }
564
579
 
565
- return nextState;
566
- }, function () {
567
- // call the provided callback if it's a function
568
- cbToCb(cb)(); // only call the onStateChange and onChange callbacks if
569
- // we have relevant information to pass them.
580
+ if (isItemSelected) {
581
+ _this.props.onSelect(stateToSet.selectedItem, _this.getStateAndHelpers());
582
+ }
570
583
 
571
- var hasMoreStateThanType = Object.keys(onStateChangeArg).length > 1;
584
+ if (onChangeArg !== undefined) {
585
+ _this.props.onChange(onChangeArg, _this.getStateAndHelpers());
586
+ } // this is currently undocumented and therefore subject to change
587
+ // We'll try to not break it, but just be warned.
572
588
 
573
- if (hasMoreStateThanType) {
574
- _this.props.onStateChange(onStateChangeArg, _this.getStateAndHelpers());
575
- }
576
589
 
577
- if (isItemSelected) {
578
- _this.props.onSelect(stateToSet.selectedItem, _this.getStateAndHelpers());
579
- }
590
+ _this.props.onUserAction(onStateChangeArg, _this.getStateAndHelpers());
591
+ });
592
+ };
580
593
 
581
- if (onChangeArg !== undefined) {
582
- _this.props.onChange(onChangeArg, _this.getStateAndHelpers());
583
- } // this is currently undocumented and therefore subject to change
584
- // We'll try to not break it, but just be warned.
594
+ _this.rootRef = function (node) {
595
+ return _this._rootNode = node;
596
+ };
585
597
 
598
+ _this.getRootProps = function (_temp, _temp2) {
599
+ var _extends2;
586
600
 
587
- _this.props.onUserAction(onStateChangeArg, _this.getStateAndHelpers());
588
- });
589
- };
601
+ var _ref = _temp === void 0 ? {} : _temp,
602
+ _ref$refKey = _ref.refKey,
603
+ refKey = _ref$refKey === void 0 ? 'ref' : _ref$refKey,
604
+ ref = _ref.ref,
605
+ rest = _objectWithoutPropertiesLoose(_ref, ["refKey", "ref"]);
590
606
 
591
- _this.rootRef = function (node) {
592
- return _this._rootNode = node;
593
- };
607
+ var _ref2 = _temp2 === void 0 ? {} : _temp2,
608
+ _ref2$suppressRefErro = _ref2.suppressRefError,
609
+ suppressRefError = _ref2$suppressRefErro === void 0 ? false : _ref2$suppressRefErro;
594
610
 
595
- _this.getRootProps = function (_temp, _temp2) {
596
- var _extends2;
611
+ // this is used in the render to know whether the user has called getRootProps.
612
+ // It uses that to know whether to apply the props automatically
613
+ _this.getRootProps.called = true;
614
+ _this.getRootProps.refKey = refKey;
615
+ _this.getRootProps.suppressRefError = suppressRefError;
597
616
 
598
- var _ref = _temp === void 0 ? {} : _temp,
599
- _ref$refKey = _ref.refKey,
600
- refKey = _ref$refKey === void 0 ? 'ref' : _ref$refKey,
601
- ref = _ref.ref,
602
- rest = _objectWithoutPropertiesLoose(_ref, ["refKey", "ref"]);
617
+ var _this$getState = _this.getState(),
618
+ isOpen = _this$getState.isOpen;
603
619
 
604
- var _ref2 = _temp2 === void 0 ? {} : _temp2,
605
- _ref2$suppressRefErro = _ref2.suppressRefError,
606
- suppressRefError = _ref2$suppressRefErro === void 0 ? false : _ref2$suppressRefErro;
620
+ return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, _this.rootRef), _extends2.role = 'combobox', _extends2['aria-expanded'] = isOpen, _extends2['aria-haspopup'] = 'listbox', _extends2['aria-owns'] = isOpen ? _this.menuId : null, _extends2['aria-labelledby'] = _this.labelId, _extends2), rest);
621
+ };
607
622
 
608
- // this is used in the render to know whether the user has called getRootProps.
609
- // It uses that to know whether to apply the props automatically
610
- _this.getRootProps.called = true;
611
- _this.getRootProps.refKey = refKey;
612
- _this.getRootProps.suppressRefError = suppressRefError;
623
+ _this.keyDownHandlers = {
624
+ ArrowDown: function ArrowDown(event) {
625
+ var _this2 = this;
613
626
 
614
- var _this$getState = _this.getState(),
615
- isOpen = _this$getState.isOpen;
627
+ event.preventDefault();
616
628
 
617
- return _extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, _this.rootRef), _extends2.role = 'combobox', _extends2['aria-expanded'] = isOpen, _extends2['aria-haspopup'] = 'listbox', _extends2['aria-owns'] = isOpen ? _this.menuId : null, _extends2['aria-labelledby'] = _this.labelId, _extends2), rest);
618
- };
629
+ if (this.getState().isOpen) {
630
+ var amount = event.shiftKey ? 5 : 1;
631
+ this.moveHighlightedIndex(amount, {
632
+ type: keyDownArrowDown
633
+ });
634
+ } else {
635
+ this.internalSetState({
636
+ isOpen: true,
637
+ type: keyDownArrowDown
638
+ }, function () {
639
+ var itemCount = _this2.getItemCount();
640
+
641
+ if (itemCount > 0) {
642
+ _this2.setHighlightedIndex(getNextWrappingIndex(1, _this2.getState().highlightedIndex, itemCount), {
643
+ type: keyDownArrowDown
644
+ });
645
+ }
646
+ });
647
+ }
648
+ },
649
+ ArrowUp: function ArrowUp(event) {
650
+ var _this3 = this;
619
651
 
620
- _this.keyDownHandlers = {
621
- ArrowDown: function ArrowDown(event) {
622
- var _this2 = this;
652
+ event.preventDefault();
623
653
 
624
- event.preventDefault();
654
+ if (this.getState().isOpen) {
655
+ var amount = event.shiftKey ? -5 : -1;
656
+ this.moveHighlightedIndex(amount, {
657
+ type: keyDownArrowUp
658
+ });
659
+ } else {
660
+ this.internalSetState({
661
+ isOpen: true,
662
+ type: keyDownArrowUp
663
+ }, function () {
664
+ var itemCount = _this3.getItemCount();
665
+
666
+ if (itemCount > 0) {
667
+ _this3.setHighlightedIndex(getNextWrappingIndex(-1, _this3.getState().highlightedIndex, itemCount), {
668
+ type: keyDownArrowDown
669
+ });
670
+ }
671
+ });
672
+ }
673
+ },
674
+ Enter: function Enter(event) {
675
+ var _this$getState2 = this.getState(),
676
+ isOpen = _this$getState2.isOpen,
677
+ highlightedIndex = _this$getState2.highlightedIndex;
678
+
679
+ if (isOpen && highlightedIndex != null) {
680
+ event.preventDefault();
681
+ var item = this.items[highlightedIndex];
682
+ var itemNode = this.getItemNodeFromIndex(highlightedIndex);
683
+
684
+ if (item == null || itemNode && itemNode.hasAttribute('disabled')) {
685
+ return;
686
+ }
625
687
 
626
- if (this.getState().isOpen) {
627
- var amount = event.shiftKey ? 5 : 1;
628
- this.moveHighlightedIndex(amount, {
629
- type: keyDownArrowDown
688
+ this.selectHighlightedItem({
689
+ type: keyDownEnter
690
+ });
691
+ }
692
+ },
693
+ Escape: function Escape(event) {
694
+ event.preventDefault();
695
+ this.reset({
696
+ type: keyDownEscape,
697
+ selectedItem: null,
698
+ inputValue: ''
630
699
  });
631
- } else {
632
- this.internalSetState({
633
- isOpen: true,
634
- type: keyDownArrowDown
635
- }, function () {
636
- var itemCount = _this2.getItemCount();
637
-
638
- if (itemCount > 0) {
639
- _this2.setHighlightedIndex(getNextWrappingIndex(1, _this2.getState().highlightedIndex, itemCount), {
640
- type: keyDownArrowDown
641
- });
642
- }
700
+ }
701
+ };
702
+ _this.buttonKeyDownHandlers = _extends({}, _this.keyDownHandlers, {
703
+ ' ': function _(event) {
704
+ event.preventDefault();
705
+ this.toggleMenu({
706
+ type: keyDownSpaceButton
643
707
  });
644
708
  }
645
- },
646
- ArrowUp: function ArrowUp(event) {
647
- var _this3 = this;
648
-
649
- event.preventDefault();
650
-
651
- if (this.getState().isOpen) {
652
- var amount = event.shiftKey ? -5 : -1;
653
- this.moveHighlightedIndex(amount, {
654
- type: keyDownArrowUp
709
+ });
710
+ _this.inputKeyDownHandlers = _extends({}, _this.keyDownHandlers, {
711
+ Home: function Home(event) {
712
+ this.highlightFirstOrLastIndex(event, true, {
713
+ type: keyDownHome
655
714
  });
656
- } else {
657
- this.internalSetState({
658
- isOpen: true,
659
- type: keyDownArrowUp
660
- }, function () {
661
- var itemCount = _this3.getItemCount();
662
-
663
- if (itemCount > 0) {
664
- _this3.setHighlightedIndex(getNextWrappingIndex(-1, _this3.getState().highlightedIndex, itemCount), {
665
- type: keyDownArrowDown
666
- });
667
- }
715
+ },
716
+ End: function End(event) {
717
+ this.highlightFirstOrLastIndex(event, false, {
718
+ type: keyDownEnd
668
719
  });
669
720
  }
670
- },
671
- Enter: function Enter(event) {
672
- var _this$getState2 = this.getState(),
673
- isOpen = _this$getState2.isOpen,
674
- highlightedIndex = _this$getState2.highlightedIndex;
675
-
676
- if (isOpen && highlightedIndex != null) {
677
- event.preventDefault();
678
- var item = this.items[highlightedIndex];
679
- var itemNode = this.getItemNodeFromIndex(highlightedIndex);
721
+ });
680
722
 
681
- if (item == null || itemNode && itemNode.hasAttribute('disabled')) {
682
- return;
683
- }
723
+ _this.getToggleButtonProps = function (_temp3) {
724
+ var _ref3 = _temp3 === void 0 ? {} : _temp3,
725
+ onClick = _ref3.onClick,
726
+ onPress = _ref3.onPress,
727
+ onKeyDown = _ref3.onKeyDown,
728
+ onKeyUp = _ref3.onKeyUp,
729
+ onBlur = _ref3.onBlur,
730
+ rest = _objectWithoutPropertiesLoose(_ref3, ["onClick", "onPress", "onKeyDown", "onKeyUp", "onBlur"]);
731
+
732
+ var _this$getState3 = _this.getState(),
733
+ isOpen = _this$getState3.isOpen;
734
+
735
+ var enabledEventHandlers = {
736
+ onClick: callAllEventHandlers(onClick, _this.buttonHandleClick),
737
+ onKeyDown: callAllEventHandlers(onKeyDown, _this.buttonHandleKeyDown),
738
+ onKeyUp: callAllEventHandlers(onKeyUp, _this.buttonHandleKeyUp),
739
+ onBlur: callAllEventHandlers(onBlur, _this.buttonHandleBlur)
740
+ };
741
+ var eventHandlers = rest.disabled ? {} : enabledEventHandlers;
742
+ return _extends({
743
+ type: 'button',
744
+ role: 'button',
745
+ 'aria-label': isOpen ? 'close menu' : 'open menu',
746
+ 'aria-haspopup': true,
747
+ 'data-toggle': true
748
+ }, eventHandlers, {}, rest);
749
+ };
684
750
 
685
- this.selectHighlightedItem({
686
- type: keyDownEnter
687
- });
688
- }
689
- },
690
- Escape: function Escape(event) {
691
- event.preventDefault();
692
- this.reset({
693
- type: keyDownEscape,
694
- selectedItem: null,
695
- inputValue: ''
696
- });
697
- }
698
- };
699
- _this.buttonKeyDownHandlers = _extends({}, _this.keyDownHandlers, {
700
- ' ': function _(event) {
751
+ _this.buttonHandleKeyUp = function (event) {
752
+ // Prevent click event from emitting in Firefox
701
753
  event.preventDefault();
702
- this.toggleMenu({
703
- type: keyDownSpaceButton
704
- });
705
- }
706
- });
707
- _this.inputKeyDownHandlers = _extends({}, _this.keyDownHandlers, {
708
- Home: function Home(event) {
709
- this.highlightFirstOrLastIndex(event, true, {
710
- type: keyDownHome
711
- });
712
- },
713
- End: function End(event) {
714
- this.highlightFirstOrLastIndex(event, false, {
715
- type: keyDownEnd
716
- });
717
- }
718
- });
719
-
720
- _this.getToggleButtonProps = function (_temp3) {
721
- var _ref3 = _temp3 === void 0 ? {} : _temp3,
722
- onClick = _ref3.onClick,
723
- onPress = _ref3.onPress,
724
- onKeyDown = _ref3.onKeyDown,
725
- onKeyUp = _ref3.onKeyUp,
726
- onBlur = _ref3.onBlur,
727
- rest = _objectWithoutPropertiesLoose(_ref3, ["onClick", "onPress", "onKeyDown", "onKeyUp", "onBlur"]);
728
-
729
- var _this$getState3 = _this.getState(),
730
- isOpen = _this$getState3.isOpen;
731
-
732
- var enabledEventHandlers = {
733
- onClick: callAllEventHandlers(onClick, _this.buttonHandleClick),
734
- onKeyDown: callAllEventHandlers(onKeyDown, _this.buttonHandleKeyDown),
735
- onKeyUp: callAllEventHandlers(onKeyUp, _this.buttonHandleKeyUp),
736
- onBlur: callAllEventHandlers(onBlur, _this.buttonHandleBlur)
737
754
  };
738
- var eventHandlers = rest.disabled ? {} : enabledEventHandlers;
739
- return _extends({
740
- type: 'button',
741
- role: 'button',
742
- 'aria-label': isOpen ? 'close menu' : 'open menu',
743
- 'aria-haspopup': true,
744
- 'data-toggle': true
745
- }, eventHandlers, {}, rest);
746
- };
747
-
748
- _this.buttonHandleKeyUp = function (event) {
749
- // Prevent click event from emitting in Firefox
750
- event.preventDefault();
751
- };
752
755
 
753
- _this.buttonHandleKeyDown = function (event) {
754
- var key = normalizeArrowKey(event);
756
+ _this.buttonHandleKeyDown = function (event) {
757
+ var key = normalizeArrowKey(event);
755
758
 
756
- if (_this.buttonKeyDownHandlers[key]) {
757
- _this.buttonKeyDownHandlers[key].call(_assertThisInitialized(_this), event);
758
- }
759
- };
759
+ if (_this.buttonKeyDownHandlers[key]) {
760
+ _this.buttonKeyDownHandlers[key].call(_assertThisInitialized(_this), event);
761
+ }
762
+ };
760
763
 
761
- _this.buttonHandleClick = function (event) {
762
- event.preventDefault(); // handle odd case for Safari and Firefox which
763
- // don't give the button the focus properly.
764
+ _this.buttonHandleClick = function (event) {
765
+ event.preventDefault(); // handle odd case for Safari and Firefox which
766
+ // don't give the button the focus properly.
764
767
 
765
- /* istanbul ignore if (can't reasonably test this) */
768
+ /* istanbul ignore if (can't reasonably test this) */
766
769
 
767
- if ( _this.props.environment.document.activeElement === _this.props.environment.document.body) {
768
- event.target.focus();
769
- } // to simplify testing components that use downshift, we'll not wrap this in a setTimeout
770
- // if the NODE_ENV is test. With the proper build system, this should be dead code eliminated
771
- // when building for production and should therefore have no impact on production code.
770
+ if ( _this.props.environment.document.activeElement === _this.props.environment.document.body) {
771
+ event.target.focus();
772
+ } // to simplify testing components that use downshift, we'll not wrap this in a setTimeout
773
+ // if the NODE_ENV is test. With the proper build system, this should be dead code eliminated
774
+ // when building for production and should therefore have no impact on production code.
772
775
 
773
776
 
774
- if (process.env.NODE_ENV === 'test') {
775
- _this.toggleMenu({
776
- type: clickButton
777
- });
778
- } else {
779
- // Ensure that toggle of menu occurs after the potential blur event in iOS
780
- _this.internalSetTimeout(function () {
781
- return _this.toggleMenu({
777
+ if (process.env.NODE_ENV === 'test') {
778
+ _this.toggleMenu({
782
779
  type: clickButton
783
780
  });
781
+ } else {
782
+ // Ensure that toggle of menu occurs after the potential blur event in iOS
783
+ _this.internalSetTimeout(function () {
784
+ return _this.toggleMenu({
785
+ type: clickButton
786
+ });
787
+ });
788
+ }
789
+ };
790
+
791
+ _this.buttonHandleBlur = function (event) {
792
+ var blurTarget = event.target; // Save blur target for comparison with activeElement later
793
+ // Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not body element
794
+
795
+ _this.internalSetTimeout(function () {
796
+ 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)
797
+ ) {
798
+ _this.reset({
799
+ type: blurButton
800
+ });
801
+ }
784
802
  });
785
- }
786
- };
803
+ };
787
804
 
788
- _this.buttonHandleBlur = function (event) {
789
- var blurTarget = event.target; // Save blur target for comparison with activeElement later
790
- // Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not body element
805
+ _this.getLabelProps = function (props) {
806
+ return _extends({
807
+ htmlFor: _this.inputId,
808
+ id: _this.labelId
809
+ }, props);
810
+ };
791
811
 
792
- _this.internalSetTimeout(function () {
793
- 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)
794
- ) {
795
- _this.reset({
796
- type: blurButton
797
- });
798
- }
799
- });
800
- };
812
+ _this.getInputProps = function (_temp4) {
813
+ var _ref4 = _temp4 === void 0 ? {} : _temp4,
814
+ onKeyDown = _ref4.onKeyDown,
815
+ onBlur = _ref4.onBlur,
816
+ onChange = _ref4.onChange,
817
+ onInput = _ref4.onInput,
818
+ onChangeText = _ref4.onChangeText,
819
+ rest = _objectWithoutPropertiesLoose(_ref4, ["onKeyDown", "onBlur", "onChange", "onInput", "onChangeText"]);
801
820
 
802
- _this.getLabelProps = function (props) {
803
- return _extends({
804
- htmlFor: _this.inputId,
805
- id: _this.labelId
806
- }, props);
807
- };
821
+ var onChangeKey;
822
+ var eventHandlers = {};
823
+ /* istanbul ignore next (preact) */
808
824
 
809
- _this.getInputProps = function (_temp4) {
810
- var _ref4 = _temp4 === void 0 ? {} : _temp4,
811
- onKeyDown = _ref4.onKeyDown,
812
- onBlur = _ref4.onBlur,
813
- onChange = _ref4.onChange,
814
- onInput = _ref4.onInput,
815
- onChangeText = _ref4.onChangeText,
816
- rest = _objectWithoutPropertiesLoose(_ref4, ["onKeyDown", "onBlur", "onChange", "onInput", "onChangeText"]);
825
+ onChangeKey = 'onChange';
817
826
 
818
- var onChangeKey;
819
- var eventHandlers = {};
820
- /* istanbul ignore next (preact) */
827
+ var _this$getState4 = _this.getState(),
828
+ inputValue = _this$getState4.inputValue,
829
+ isOpen = _this$getState4.isOpen,
830
+ highlightedIndex = _this$getState4.highlightedIndex;
821
831
 
822
- onChangeKey = 'onChange';
832
+ if (!rest.disabled) {
833
+ var _eventHandlers;
823
834
 
824
- var _this$getState4 = _this.getState(),
825
- inputValue = _this$getState4.inputValue,
826
- isOpen = _this$getState4.isOpen,
827
- highlightedIndex = _this$getState4.highlightedIndex;
835
+ eventHandlers = (_eventHandlers = {}, _eventHandlers[onChangeKey] = callAllEventHandlers(onChange, onInput, _this.inputHandleChange), _eventHandlers.onKeyDown = callAllEventHandlers(onKeyDown, _this.inputHandleKeyDown), _eventHandlers.onBlur = callAllEventHandlers(onBlur, _this.inputHandleBlur), _eventHandlers);
836
+ }
837
+ /* istanbul ignore if (react-native) */
828
838
 
829
- if (!rest.disabled) {
830
- var _eventHandlers;
831
839
 
832
- eventHandlers = (_eventHandlers = {}, _eventHandlers[onChangeKey] = callAllEventHandlers(onChange, onInput, _this.inputHandleChange), _eventHandlers.onKeyDown = callAllEventHandlers(onKeyDown, _this.inputHandleKeyDown), _eventHandlers.onBlur = callAllEventHandlers(onBlur, _this.inputHandleBlur), _eventHandlers);
833
- }
834
- /* istanbul ignore if (react-native) */
840
+ return _extends({
841
+ 'aria-autocomplete': 'list',
842
+ 'aria-activedescendant': isOpen && typeof highlightedIndex === 'number' && highlightedIndex >= 0 ? _this.getItemId(highlightedIndex) : null,
843
+ 'aria-controls': isOpen ? _this.menuId : null,
844
+ 'aria-labelledby': _this.labelId,
845
+ // https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
846
+ // revert back since autocomplete="nope" is ignored on latest Chrome and Opera
847
+ autoComplete: 'off',
848
+ value: inputValue,
849
+ id: _this.inputId
850
+ }, eventHandlers, {}, rest);
851
+ };
835
852
 
853
+ _this.inputHandleKeyDown = function (event) {
854
+ var key = normalizeArrowKey(event);
836
855
 
837
- return _extends({
838
- 'aria-autocomplete': 'list',
839
- 'aria-activedescendant': isOpen && typeof highlightedIndex === 'number' && highlightedIndex >= 0 ? _this.getItemId(highlightedIndex) : null,
840
- 'aria-controls': isOpen ? _this.menuId : null,
841
- 'aria-labelledby': _this.labelId,
842
- // https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
843
- // revert back since autocomplete="nope" is ignored on latest Chrome and Opera
844
- autoComplete: 'off',
845
- value: inputValue,
846
- id: _this.inputId
847
- }, eventHandlers, {}, rest);
848
- };
856
+ if (key && _this.inputKeyDownHandlers[key]) {
857
+ _this.inputKeyDownHandlers[key].call(_assertThisInitialized(_this), event);
858
+ }
859
+ };
849
860
 
850
- _this.inputHandleKeyDown = function (event) {
851
- var key = normalizeArrowKey(event);
861
+ _this.inputHandleChange = function (event) {
862
+ _this.internalSetState({
863
+ type: changeInput,
864
+ isOpen: true,
865
+ inputValue: event.target.value,
866
+ highlightedIndex: _this.props.defaultHighlightedIndex
867
+ });
868
+ };
852
869
 
853
- if (key && _this.inputKeyDownHandlers[key]) {
854
- _this.inputKeyDownHandlers[key].call(_assertThisInitialized(_this), event);
855
- }
856
- };
870
+ _this.inputHandleBlur = function () {
871
+ // Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not the body element
872
+ _this.internalSetTimeout(function () {
873
+ var 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);
857
874
 
858
- _this.inputHandleChange = function (event) {
859
- _this.internalSetState({
860
- type: changeInput,
861
- isOpen: true,
862
- inputValue: event.target.value,
863
- highlightedIndex: _this.props.defaultHighlightedIndex
864
- });
865
- };
875
+ if (!_this.isMouseDown && !downshiftButtonIsActive) {
876
+ _this.reset({
877
+ type: blurInput
878
+ });
879
+ }
880
+ });
881
+ };
866
882
 
867
- _this.inputHandleBlur = function () {
868
- // Need setTimeout, so that when the user presses Tab, the activeElement is the next focused element, not the body element
869
- _this.internalSetTimeout(function () {
870
- var 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);
883
+ _this.menuRef = function (node) {
884
+ _this._menuNode = node;
885
+ };
871
886
 
872
- if (!_this.isMouseDown && !downshiftButtonIsActive) {
873
- _this.reset({
874
- type: blurInput
875
- });
876
- }
877
- });
878
- };
887
+ _this.getMenuProps = function (_temp5, _temp6) {
888
+ var _extends3;
879
889
 
880
- _this.menuRef = function (node) {
881
- _this._menuNode = node;
882
- };
890
+ var _ref5 = _temp5 === void 0 ? {} : _temp5,
891
+ _ref5$refKey = _ref5.refKey,
892
+ refKey = _ref5$refKey === void 0 ? 'ref' : _ref5$refKey,
893
+ ref = _ref5.ref,
894
+ props = _objectWithoutPropertiesLoose(_ref5, ["refKey", "ref"]);
883
895
 
884
- _this.getMenuProps = function (_temp5, _temp6) {
885
- var _extends3;
896
+ var _ref6 = _temp6 === void 0 ? {} : _temp6,
897
+ _ref6$suppressRefErro = _ref6.suppressRefError,
898
+ suppressRefError = _ref6$suppressRefErro === void 0 ? false : _ref6$suppressRefErro;
886
899
 
887
- var _ref5 = _temp5 === void 0 ? {} : _temp5,
888
- _ref5$refKey = _ref5.refKey,
889
- refKey = _ref5$refKey === void 0 ? 'ref' : _ref5$refKey,
890
- ref = _ref5.ref,
891
- props = _objectWithoutPropertiesLoose(_ref5, ["refKey", "ref"]);
900
+ _this.getMenuProps.called = true;
901
+ _this.getMenuProps.refKey = refKey;
902
+ _this.getMenuProps.suppressRefError = suppressRefError;
903
+ return _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, _this.menuRef), _extends3.role = 'listbox', _extends3['aria-labelledby'] = props && props['aria-label'] ? null : _this.labelId, _extends3.id = _this.menuId, _extends3), props);
904
+ };
892
905
 
893
- var _ref6 = _temp6 === void 0 ? {} : _temp6,
894
- _ref6$suppressRefErro = _ref6.suppressRefError,
895
- suppressRefError = _ref6$suppressRefErro === void 0 ? false : _ref6$suppressRefErro;
906
+ _this.getItemProps = function (_temp7) {
907
+ var _enabledEventHandlers;
908
+
909
+ var _ref7 = _temp7 === void 0 ? {} : _temp7,
910
+ onMouseMove = _ref7.onMouseMove,
911
+ onMouseDown = _ref7.onMouseDown,
912
+ onClick = _ref7.onClick,
913
+ onPress = _ref7.onPress,
914
+ index = _ref7.index,
915
+ _ref7$item = _ref7.item,
916
+ item = _ref7$item === void 0 ? process.env.NODE_ENV === 'production' ?
917
+ /* istanbul ignore next */
918
+ undefined : requiredProp('getItemProps', 'item') : _ref7$item,
919
+ rest = _objectWithoutPropertiesLoose(_ref7, ["onMouseMove", "onMouseDown", "onClick", "onPress", "index", "item"]);
920
+
921
+ if (index === undefined) {
922
+ _this.items.push(item);
923
+
924
+ index = _this.items.indexOf(item);
925
+ } else {
926
+ _this.items[index] = item;
927
+ }
896
928
 
897
- _this.getMenuProps.called = true;
898
- _this.getMenuProps.refKey = refKey;
899
- _this.getMenuProps.suppressRefError = suppressRefError;
900
- return _extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, _this.menuRef), _extends3.role = 'listbox', _extends3['aria-labelledby'] = props && props['aria-label'] ? null : _this.labelId, _extends3.id = _this.menuId, _extends3), props);
901
- };
929
+ var onSelectKey = 'onClick';
930
+ var customClickHandler = onClick;
931
+ var enabledEventHandlers = (_enabledEventHandlers = {
932
+ // onMouseMove is used over onMouseEnter here. onMouseMove
933
+ // is only triggered on actual mouse movement while onMouseEnter
934
+ // can fire on DOM changes, interrupting keyboard navigation
935
+ onMouseMove: callAllEventHandlers(onMouseMove, function () {
936
+ if (index === _this.getState().highlightedIndex) {
937
+ return;
938
+ }
902
939
 
903
- _this.getItemProps = function (_temp7) {
904
- var _enabledEventHandlers;
905
-
906
- var _ref7 = _temp7 === void 0 ? {} : _temp7,
907
- onMouseMove = _ref7.onMouseMove,
908
- onMouseDown = _ref7.onMouseDown,
909
- onClick = _ref7.onClick,
910
- onPress = _ref7.onPress,
911
- index = _ref7.index,
912
- _ref7$item = _ref7.item,
913
- item = _ref7$item === void 0 ? process.env.NODE_ENV === 'production' ?
914
- /* istanbul ignore next */
915
- undefined : requiredProp('getItemProps', 'item') : _ref7$item,
916
- rest = _objectWithoutPropertiesLoose(_ref7, ["onMouseMove", "onMouseDown", "onClick", "onPress", "index", "item"]);
940
+ _this.setHighlightedIndex(index, {
941
+ type: itemMouseEnter
942
+ }); // We never want to manually scroll when changing state based
943
+ // on `onMouseMove` because we will be moving the element out
944
+ // from under the user which is currently scrolling/moving the
945
+ // cursor
946
+
947
+
948
+ _this.avoidScrolling = true;
949
+
950
+ _this.internalSetTimeout(function () {
951
+ return _this.avoidScrolling = false;
952
+ }, 250);
953
+ }),
954
+ onMouseDown: callAllEventHandlers(onMouseDown, function (event) {
955
+ // This prevents the activeElement from being changed
956
+ // to the item so it can remain with the current activeElement
957
+ // which is a more common use case.
958
+ event.preventDefault();
959
+ })
960
+ }, _enabledEventHandlers[onSelectKey] = callAllEventHandlers(customClickHandler, function () {
961
+ _this.selectItemAtIndex(index, {
962
+ type: clickItem
963
+ });
964
+ }), _enabledEventHandlers); // Passing down the onMouseDown handler to prevent redirect
965
+ // of the activeElement if clicking on disabled items
966
+
967
+ var eventHandlers = rest.disabled ? {
968
+ onMouseDown: enabledEventHandlers.onMouseDown
969
+ } : enabledEventHandlers;
970
+ return _extends({
971
+ id: _this.getItemId(index),
972
+ role: 'option',
973
+ 'aria-selected': _this.getState().highlightedIndex === index
974
+ }, eventHandlers, {}, rest);
975
+ };
917
976
 
918
- if (index === undefined) {
919
- _this.items.push(item);
977
+ _this.clearItems = function () {
978
+ _this.items = [];
979
+ };
920
980
 
921
- index = _this.items.indexOf(item);
922
- } else {
923
- _this.items[index] = item;
924
- }
981
+ _this.reset = function (otherStateToSet, cb) {
982
+ if (otherStateToSet === void 0) {
983
+ otherStateToSet = {};
984
+ }
925
985
 
926
- var onSelectKey = 'onClick';
927
- var customClickHandler = onClick;
928
- var enabledEventHandlers = (_enabledEventHandlers = {
929
- // onMouseMove is used over onMouseEnter here. onMouseMove
930
- // is only triggered on actual mouse movement while onMouseEnter
931
- // can fire on DOM changes, interrupting keyboard navigation
932
- onMouseMove: callAllEventHandlers(onMouseMove, function () {
933
- if (index === _this.getState().highlightedIndex) {
934
- return;
935
- }
986
+ otherStateToSet = pickState(otherStateToSet);
936
987
 
937
- _this.setHighlightedIndex(index, {
938
- type: itemMouseEnter
939
- }); // We never want to manually scroll when changing state based
940
- // on `onMouseMove` because we will be moving the element out
941
- // from under the user which is currently scrolling/moving the
942
- // cursor
988
+ _this.internalSetState(function (_ref8) {
989
+ var selectedItem = _ref8.selectedItem;
990
+ return _extends({
991
+ isOpen: _this.props.defaultIsOpen,
992
+ highlightedIndex: _this.props.defaultHighlightedIndex,
993
+ inputValue: _this.props.itemToString(selectedItem)
994
+ }, otherStateToSet);
995
+ }, cb);
996
+ };
943
997
 
998
+ _this.toggleMenu = function (otherStateToSet, cb) {
999
+ if (otherStateToSet === void 0) {
1000
+ otherStateToSet = {};
1001
+ }
944
1002
 
945
- _this.avoidScrolling = true;
1003
+ otherStateToSet = pickState(otherStateToSet);
1004
+
1005
+ _this.internalSetState(function (_ref9) {
1006
+ var isOpen = _ref9.isOpen;
1007
+ return _extends({
1008
+ isOpen: !isOpen
1009
+ }, isOpen && {
1010
+ highlightedIndex: _this.props.defaultHighlightedIndex
1011
+ }, {}, otherStateToSet);
1012
+ }, function () {
1013
+ var _this$getState5 = _this.getState(),
1014
+ isOpen = _this$getState5.isOpen,
1015
+ highlightedIndex = _this$getState5.highlightedIndex;
1016
+
1017
+ if (isOpen) {
1018
+ if (_this.getItemCount() > 0 && typeof highlightedIndex === 'number') {
1019
+ _this.setHighlightedIndex(highlightedIndex, otherStateToSet);
1020
+ }
1021
+ }
946
1022
 
947
- _this.internalSetTimeout(function () {
948
- return _this.avoidScrolling = false;
949
- }, 250);
950
- }),
951
- onMouseDown: callAllEventHandlers(onMouseDown, function (event) {
952
- // This prevents the activeElement from being changed
953
- // to the item so it can remain with the current activeElement
954
- // which is a more common use case.
955
- event.preventDefault();
956
- })
957
- }, _enabledEventHandlers[onSelectKey] = callAllEventHandlers(customClickHandler, function () {
958
- _this.selectItemAtIndex(index, {
959
- type: clickItem
1023
+ cbToCb(cb)();
960
1024
  });
961
- }), _enabledEventHandlers); // Passing down the onMouseDown handler to prevent redirect
962
- // of the activeElement if clicking on disabled items
1025
+ };
963
1026
 
964
- var eventHandlers = rest.disabled ? {
965
- onMouseDown: enabledEventHandlers.onMouseDown
966
- } : enabledEventHandlers;
967
- return _extends({
968
- id: _this.getItemId(index),
969
- role: 'option',
970
- 'aria-selected': _this.getState().highlightedIndex === index
971
- }, eventHandlers, {}, rest);
972
- };
1027
+ _this.openMenu = function (cb) {
1028
+ _this.internalSetState({
1029
+ isOpen: true
1030
+ }, cb);
1031
+ };
973
1032
 
974
- _this.clearItems = function () {
975
- _this.items = [];
976
- };
1033
+ _this.closeMenu = function (cb) {
1034
+ _this.internalSetState({
1035
+ isOpen: false
1036
+ }, cb);
1037
+ };
977
1038
 
978
- _this.reset = function (otherStateToSet, cb) {
979
- if (otherStateToSet === void 0) {
980
- otherStateToSet = {};
1039
+ _this.updateStatus = debounce(function () {
1040
+ var state = _this.getState();
1041
+
1042
+ var item = _this.items[state.highlightedIndex];
1043
+
1044
+ var resultCount = _this.getItemCount();
1045
+
1046
+ var status = _this.props.getA11yStatusMessage(_extends({
1047
+ itemToString: _this.props.itemToString,
1048
+ previousResultCount: _this.previousResultCount,
1049
+ resultCount: resultCount,
1050
+ highlightedItem: item
1051
+ }, state));
1052
+
1053
+ _this.previousResultCount = resultCount;
1054
+ setStatus(status, _this.props.environment.document);
1055
+ }, 200);
1056
+
1057
+ // fancy destructuring + defaults + aliases
1058
+ // this basically says each value of state should either be set to
1059
+ // the initial value or the default value if the initial value is not provided
1060
+ var _this$props = _this.props,
1061
+ defaultHighlightedIndex = _this$props.defaultHighlightedIndex,
1062
+ _this$props$initialHi = _this$props.initialHighlightedIndex,
1063
+ _highlightedIndex = _this$props$initialHi === void 0 ? defaultHighlightedIndex : _this$props$initialHi,
1064
+ defaultIsOpen = _this$props.defaultIsOpen,
1065
+ _this$props$initialIs = _this$props.initialIsOpen,
1066
+ _isOpen = _this$props$initialIs === void 0 ? defaultIsOpen : _this$props$initialIs,
1067
+ _this$props$initialIn = _this$props.initialInputValue,
1068
+ _inputValue = _this$props$initialIn === void 0 ? '' : _this$props$initialIn,
1069
+ _this$props$initialSe = _this$props.initialSelectedItem,
1070
+ _selectedItem = _this$props$initialSe === void 0 ? null : _this$props$initialSe;
1071
+
1072
+ var _state = _this.getState({
1073
+ highlightedIndex: _highlightedIndex,
1074
+ isOpen: _isOpen,
1075
+ inputValue: _inputValue,
1076
+ selectedItem: _selectedItem
1077
+ });
1078
+
1079
+ if (_state.selectedItem != null && _this.props.initialInputValue === undefined) {
1080
+ _state.inputValue = _this.props.itemToString(_state.selectedItem);
981
1081
  }
982
1082
 
983
- otherStateToSet = pickState(otherStateToSet);
1083
+ _this.state = _state;
1084
+ return _this;
1085
+ }
984
1086
 
985
- _this.internalSetState(function (_ref8) {
986
- var selectedItem = _ref8.selectedItem;
987
- return _extends({
988
- isOpen: _this.props.defaultIsOpen,
989
- highlightedIndex: _this.props.defaultHighlightedIndex,
990
- inputValue: _this.props.itemToString(selectedItem)
991
- }, otherStateToSet);
992
- }, cb);
993
- };
1087
+ var _proto = Downshift.prototype;
994
1088
 
995
- _this.toggleMenu = function (otherStateToSet, cb) {
996
- if (otherStateToSet === void 0) {
997
- otherStateToSet = {};
1089
+ /**
1090
+ * Clear all running timeouts
1091
+ */
1092
+ _proto.internalClearTimeouts = function internalClearTimeouts() {
1093
+ this.timeoutIds.forEach(function (id) {
1094
+ clearTimeout(id);
1095
+ });
1096
+ this.timeoutIds = [];
1097
+ }
1098
+ /**
1099
+ * Gets the state based on internal state or props
1100
+ * If a state value is passed via props, then that
1101
+ * is the value given, otherwise it's retrieved from
1102
+ * stateToMerge
1103
+ *
1104
+ * This will perform a shallow merge of the given state object
1105
+ * with the state coming from props
1106
+ * (for the controlled component scenario)
1107
+ * This is used in state updater functions so they're referencing
1108
+ * the right state regardless of where it comes from.
1109
+ *
1110
+ * @param {Object} stateToMerge defaults to this.state
1111
+ * @return {Object} the state
1112
+ */
1113
+ ;
1114
+
1115
+ _proto.getState = function getState(stateToMerge) {
1116
+ var _this4 = this;
1117
+
1118
+ if (stateToMerge === void 0) {
1119
+ stateToMerge = this.state;
998
1120
  }
999
1121
 
1000
- otherStateToSet = pickState(otherStateToSet);
1122
+ return Object.keys(stateToMerge).reduce(function (state, key) {
1123
+ state[key] = _this4.isControlledProp(key) ? _this4.props[key] : stateToMerge[key];
1124
+ return state;
1125
+ }, {});
1126
+ }
1127
+ /**
1128
+ * This determines whether a prop is a "controlled prop" meaning it is
1129
+ * state which is controlled by the outside of this component rather
1130
+ * than within this component.
1131
+ * @param {String} key the key to check
1132
+ * @return {Boolean} whether it is a controlled controlled prop
1133
+ */
1134
+ ;
1135
+
1136
+ _proto.isControlledProp = function isControlledProp(key) {
1137
+ return this.props[key] !== undefined;
1138
+ };
1001
1139
 
1002
- _this.internalSetState(function (_ref9) {
1003
- var isOpen = _ref9.isOpen;
1004
- return _extends({
1005
- isOpen: !isOpen
1006
- }, isOpen && {
1007
- highlightedIndex: _this.props.defaultHighlightedIndex
1008
- }, {}, otherStateToSet);
1009
- }, function () {
1010
- var _this$getState5 = _this.getState(),
1011
- isOpen = _this$getState5.isOpen,
1012
- highlightedIndex = _this$getState5.highlightedIndex;
1013
-
1014
- if (isOpen) {
1015
- if (_this.getItemCount() > 0 && typeof highlightedIndex === 'number') {
1016
- _this.setHighlightedIndex(highlightedIndex, otherStateToSet);
1017
- }
1018
- }
1140
+ _proto.getItemCount = function getItemCount() {
1141
+ // things read better this way. They're in priority order:
1142
+ // 1. `this.itemCount`
1143
+ // 2. `this.props.itemCount`
1144
+ // 3. `this.items.length`
1145
+ var itemCount = this.items.length;
1146
+
1147
+ if (this.itemCount != null) {
1148
+ itemCount = this.itemCount;
1149
+ } else if (this.props.itemCount !== undefined) {
1150
+ itemCount = this.props.itemCount;
1151
+ }
1019
1152
 
1020
- cbToCb(cb)();
1021
- });
1153
+ return itemCount;
1022
1154
  };
1023
1155
 
1024
- _this.openMenu = function (cb) {
1025
- _this.internalSetState({
1026
- isOpen: true
1027
- }, cb);
1156
+ _proto.getItemNodeFromIndex = function getItemNodeFromIndex(index) {
1157
+ return this.props.environment.document.getElementById(this.getItemId(index));
1028
1158
  };
1029
1159
 
1030
- _this.closeMenu = function (cb) {
1031
- _this.internalSetState({
1032
- isOpen: false
1033
- }, cb);
1160
+ _proto.scrollHighlightedItemIntoView = function scrollHighlightedItemIntoView() {
1161
+ /* istanbul ignore else (react-native) */
1162
+ {
1163
+ var node = this.getItemNodeFromIndex(this.getState().highlightedIndex);
1164
+ this.props.scrollIntoView(node, this._menuNode);
1165
+ }
1034
1166
  };
1035
1167
 
1036
- _this.updateStatus = debounce(function () {
1037
- var state = _this.getState();
1038
-
1039
- var item = _this.items[state.highlightedIndex];
1040
-
1041
- var resultCount = _this.getItemCount();
1042
-
1043
- var status = _this.props.getA11yStatusMessage(_extends({
1044
- itemToString: _this.props.itemToString,
1045
- previousResultCount: _this.previousResultCount,
1046
- resultCount: resultCount,
1047
- highlightedItem: item
1048
- }, state));
1049
-
1050
- _this.previousResultCount = resultCount;
1051
- setStatus(status, _this.props.environment.document);
1052
- }, 200);
1053
-
1054
- // fancy destructuring + defaults + aliases
1055
- // this basically says each value of state should either be set to
1056
- // the initial value or the default value if the initial value is not provided
1057
- var _this$props = _this.props,
1058
- defaultHighlightedIndex = _this$props.defaultHighlightedIndex,
1059
- _this$props$initialHi = _this$props.initialHighlightedIndex,
1060
- _highlightedIndex = _this$props$initialHi === void 0 ? defaultHighlightedIndex : _this$props$initialHi,
1061
- defaultIsOpen = _this$props.defaultIsOpen,
1062
- _this$props$initialIs = _this$props.initialIsOpen,
1063
- _isOpen = _this$props$initialIs === void 0 ? defaultIsOpen : _this$props$initialIs,
1064
- _this$props$initialIn = _this$props.initialInputValue,
1065
- _inputValue = _this$props$initialIn === void 0 ? '' : _this$props$initialIn,
1066
- _this$props$initialSe = _this$props.initialSelectedItem,
1067
- _selectedItem = _this$props$initialSe === void 0 ? null : _this$props$initialSe;
1068
-
1069
- var _state = _this.getState({
1070
- highlightedIndex: _highlightedIndex,
1071
- isOpen: _isOpen,
1072
- inputValue: _inputValue,
1073
- selectedItem: _selectedItem
1074
- });
1168
+ _proto.moveHighlightedIndex = function moveHighlightedIndex(amount, otherStateToSet) {
1169
+ var itemCount = this.getItemCount();
1075
1170
 
1076
- if (_state.selectedItem != null && _this.props.initialInputValue === undefined) {
1077
- _state.inputValue = _this.props.itemToString(_state.selectedItem);
1078
- }
1171
+ if (itemCount > 0) {
1172
+ var nextHighlightedIndex = getNextWrappingIndex(amount, this.getState().highlightedIndex, itemCount);
1173
+ this.setHighlightedIndex(nextHighlightedIndex, otherStateToSet);
1174
+ }
1175
+ };
1079
1176
 
1080
- _this.state = _state;
1081
- return _this;
1082
- }
1177
+ _proto.highlightFirstOrLastIndex = function highlightFirstOrLastIndex(event, first, otherStateToSet) {
1178
+ var itemsLastIndex = this.getItemCount() - 1;
1083
1179
 
1084
- var _proto = Downshift.prototype;
1180
+ if (itemsLastIndex < 0 || !this.getState().isOpen) {
1181
+ return;
1182
+ }
1085
1183
 
1086
- /**
1087
- * Clear all running timeouts
1088
- */
1089
- _proto.internalClearTimeouts = function internalClearTimeouts() {
1090
- this.timeoutIds.forEach(function (id) {
1091
- clearTimeout(id);
1092
- });
1093
- this.timeoutIds = [];
1094
- }
1095
- /**
1096
- * Gets the state based on internal state or props
1097
- * If a state value is passed via props, then that
1098
- * is the value given, otherwise it's retrieved from
1099
- * stateToMerge
1100
- *
1101
- * This will perform a shallow merge of the given state object
1102
- * with the state coming from props
1103
- * (for the controlled component scenario)
1104
- * This is used in state updater functions so they're referencing
1105
- * the right state regardless of where it comes from.
1106
- *
1107
- * @param {Object} stateToMerge defaults to this.state
1108
- * @return {Object} the state
1109
- */
1110
- ;
1111
-
1112
- _proto.getState = function getState(stateToMerge) {
1113
- var _this4 = this;
1114
-
1115
- if (stateToMerge === void 0) {
1116
- stateToMerge = this.state;
1117
- }
1184
+ event.preventDefault();
1185
+ this.setHighlightedIndex(first ? 0 : itemsLastIndex, otherStateToSet);
1186
+ };
1118
1187
 
1119
- return Object.keys(stateToMerge).reduce(function (state, key) {
1120
- state[key] = _this4.isControlledProp(key) ? _this4.props[key] : stateToMerge[key];
1121
- return state;
1122
- }, {});
1123
- }
1124
- /**
1125
- * This determines whether a prop is a "controlled prop" meaning it is
1126
- * state which is controlled by the outside of this component rather
1127
- * than within this component.
1128
- * @param {String} key the key to check
1129
- * @return {Boolean} whether it is a controlled controlled prop
1130
- */
1131
- ;
1132
-
1133
- _proto.isControlledProp = function isControlledProp(key) {
1134
- return this.props[key] !== undefined;
1135
- };
1188
+ _proto.getStateAndHelpers = function getStateAndHelpers() {
1189
+ var _this$getState6 = this.getState(),
1190
+ highlightedIndex = _this$getState6.highlightedIndex,
1191
+ inputValue = _this$getState6.inputValue,
1192
+ selectedItem = _this$getState6.selectedItem,
1193
+ isOpen = _this$getState6.isOpen;
1194
+
1195
+ var itemToString = this.props.itemToString;
1196
+ var id = this.id;
1197
+ var getRootProps = this.getRootProps,
1198
+ getToggleButtonProps = this.getToggleButtonProps,
1199
+ getLabelProps = this.getLabelProps,
1200
+ getMenuProps = this.getMenuProps,
1201
+ getInputProps = this.getInputProps,
1202
+ getItemProps = this.getItemProps,
1203
+ openMenu = this.openMenu,
1204
+ closeMenu = this.closeMenu,
1205
+ toggleMenu = this.toggleMenu,
1206
+ selectItem = this.selectItem,
1207
+ selectItemAtIndex = this.selectItemAtIndex,
1208
+ selectHighlightedItem = this.selectHighlightedItem,
1209
+ setHighlightedIndex = this.setHighlightedIndex,
1210
+ clearSelection = this.clearSelection,
1211
+ clearItems = this.clearItems,
1212
+ reset = this.reset,
1213
+ setItemCount = this.setItemCount,
1214
+ unsetItemCount = this.unsetItemCount,
1215
+ setState = this.internalSetState;
1216
+ return {
1217
+ // prop getters
1218
+ getRootProps: getRootProps,
1219
+ getToggleButtonProps: getToggleButtonProps,
1220
+ getLabelProps: getLabelProps,
1221
+ getMenuProps: getMenuProps,
1222
+ getInputProps: getInputProps,
1223
+ getItemProps: getItemProps,
1224
+ // actions
1225
+ reset: reset,
1226
+ openMenu: openMenu,
1227
+ closeMenu: closeMenu,
1228
+ toggleMenu: toggleMenu,
1229
+ selectItem: selectItem,
1230
+ selectItemAtIndex: selectItemAtIndex,
1231
+ selectHighlightedItem: selectHighlightedItem,
1232
+ setHighlightedIndex: setHighlightedIndex,
1233
+ clearSelection: clearSelection,
1234
+ clearItems: clearItems,
1235
+ setItemCount: setItemCount,
1236
+ unsetItemCount: unsetItemCount,
1237
+ setState: setState,
1238
+ // props
1239
+ itemToString: itemToString,
1240
+ // derived
1241
+ id: id,
1242
+ // state
1243
+ highlightedIndex: highlightedIndex,
1244
+ inputValue: inputValue,
1245
+ isOpen: isOpen,
1246
+ selectedItem: selectedItem
1247
+ };
1248
+ } //////////////////////////// ROOT
1249
+ ;
1136
1250
 
1137
- _proto.getItemCount = function getItemCount() {
1138
- // things read better this way. They're in priority order:
1139
- // 1. `this.itemCount`
1140
- // 2. `this.props.itemCount`
1141
- // 3. `this.items.length`
1142
- var itemCount = this.items.length;
1143
-
1144
- if (this.itemCount != null) {
1145
- itemCount = this.itemCount;
1146
- } else if (this.props.itemCount !== undefined) {
1147
- itemCount = this.props.itemCount;
1148
- }
1251
+ _proto.componentDidMount = function componentDidMount() {
1252
+ var _this5 = this;
1149
1253
 
1150
- return itemCount;
1151
- };
1254
+ /* istanbul ignore if (react-native) */
1255
+ if (process.env.NODE_ENV !== 'production' && !false && this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
1256
+ validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
1257
+ }
1258
+ /* istanbul ignore if (react-native) */
1152
1259
 
1153
- _proto.getItemNodeFromIndex = function getItemNodeFromIndex(index) {
1154
- return this.props.environment.document.getElementById(this.getItemId(index));
1155
- };
1156
1260
 
1157
- _proto.scrollHighlightedItemIntoView = function scrollHighlightedItemIntoView() {
1158
- /* istanbul ignore else (react-native) */
1159
- {
1160
- var node = this.getItemNodeFromIndex(this.getState().highlightedIndex);
1161
- this.props.scrollIntoView(node, this._menuNode);
1162
- }
1163
- };
1261
+ {
1262
+ var targetWithinDownshift = function (target, checkActiveElement) {
1263
+ if (checkActiveElement === void 0) {
1264
+ checkActiveElement = true;
1265
+ }
1164
1266
 
1165
- _proto.moveHighlightedIndex = function moveHighlightedIndex(amount, otherStateToSet) {
1166
- var itemCount = this.getItemCount();
1267
+ var document = _this5.props.environment.document;
1268
+ return [_this5._rootNode, _this5._menuNode].some(function (contextNode) {
1269
+ return contextNode && (isOrContainsNode(contextNode, target) || checkActiveElement && isOrContainsNode(contextNode, document.activeElement));
1270
+ });
1271
+ }; // this.isMouseDown helps us track whether the mouse is currently held down.
1272
+ // This is useful when the user clicks on an item in the list, but holds the mouse
1273
+ // down long enough for the list to disappear (because the blur event fires on the input)
1274
+ // this.isMouseDown is used in the blur handler on the input to determine whether the blur event should
1275
+ // trigger hiding the menu.
1167
1276
 
1168
- if (itemCount > 0) {
1169
- var nextHighlightedIndex = getNextWrappingIndex(amount, this.getState().highlightedIndex, itemCount);
1170
- this.setHighlightedIndex(nextHighlightedIndex, otherStateToSet);
1171
- }
1172
- };
1173
1277
 
1174
- _proto.highlightFirstOrLastIndex = function highlightFirstOrLastIndex(event, first, otherStateToSet) {
1175
- var itemsLastIndex = this.getItemCount() - 1;
1278
+ var onMouseDown = function () {
1279
+ _this5.isMouseDown = true;
1280
+ };
1176
1281
 
1177
- if (itemsLastIndex < 0 || !this.getState().isOpen) {
1178
- return;
1179
- }
1282
+ var onMouseUp = function (event) {
1283
+ _this5.isMouseDown = false; // if the target element or the activeElement is within a downshift node
1284
+ // then we don't want to reset downshift
1180
1285
 
1181
- event.preventDefault();
1182
- this.setHighlightedIndex(first ? 0 : itemsLastIndex, otherStateToSet);
1183
- };
1286
+ var contextWithinDownshift = targetWithinDownshift(event.target);
1184
1287
 
1185
- _proto.getStateAndHelpers = function getStateAndHelpers() {
1186
- var _this$getState6 = this.getState(),
1187
- highlightedIndex = _this$getState6.highlightedIndex,
1188
- inputValue = _this$getState6.inputValue,
1189
- selectedItem = _this$getState6.selectedItem,
1190
- isOpen = _this$getState6.isOpen;
1191
-
1192
- var itemToString = this.props.itemToString;
1193
- var id = this.id;
1194
- var getRootProps = this.getRootProps,
1195
- getToggleButtonProps = this.getToggleButtonProps,
1196
- getLabelProps = this.getLabelProps,
1197
- getMenuProps = this.getMenuProps,
1198
- getInputProps = this.getInputProps,
1199
- getItemProps = this.getItemProps,
1200
- openMenu = this.openMenu,
1201
- closeMenu = this.closeMenu,
1202
- toggleMenu = this.toggleMenu,
1203
- selectItem = this.selectItem,
1204
- selectItemAtIndex = this.selectItemAtIndex,
1205
- selectHighlightedItem = this.selectHighlightedItem,
1206
- setHighlightedIndex = this.setHighlightedIndex,
1207
- clearSelection = this.clearSelection,
1208
- clearItems = this.clearItems,
1209
- reset = this.reset,
1210
- setItemCount = this.setItemCount,
1211
- unsetItemCount = this.unsetItemCount,
1212
- setState = this.internalSetState;
1213
- return {
1214
- // prop getters
1215
- getRootProps: getRootProps,
1216
- getToggleButtonProps: getToggleButtonProps,
1217
- getLabelProps: getLabelProps,
1218
- getMenuProps: getMenuProps,
1219
- getInputProps: getInputProps,
1220
- getItemProps: getItemProps,
1221
- // actions
1222
- reset: reset,
1223
- openMenu: openMenu,
1224
- closeMenu: closeMenu,
1225
- toggleMenu: toggleMenu,
1226
- selectItem: selectItem,
1227
- selectItemAtIndex: selectItemAtIndex,
1228
- selectHighlightedItem: selectHighlightedItem,
1229
- setHighlightedIndex: setHighlightedIndex,
1230
- clearSelection: clearSelection,
1231
- clearItems: clearItems,
1232
- setItemCount: setItemCount,
1233
- unsetItemCount: unsetItemCount,
1234
- setState: setState,
1235
- // props
1236
- itemToString: itemToString,
1237
- // derived
1238
- id: id,
1239
- // state
1240
- highlightedIndex: highlightedIndex,
1241
- inputValue: inputValue,
1242
- isOpen: isOpen,
1243
- selectedItem: selectedItem
1244
- };
1245
- } //////////////////////////// ROOT
1246
- ;
1288
+ if (!contextWithinDownshift && _this5.getState().isOpen) {
1289
+ _this5.reset({
1290
+ type: mouseUp
1291
+ }, function () {
1292
+ return _this5.props.onOuterClick(_this5.getStateAndHelpers());
1293
+ });
1294
+ }
1295
+ }; // Touching an element in iOS gives focus and hover states, but touching out of
1296
+ // the element will remove hover, and persist the focus state, resulting in the
1297
+ // blur event not being triggered.
1298
+ // this.isTouchMove helps us track whether the user is tapping or swiping on a touch screen.
1299
+ // If the user taps outside of Downshift, the component should be reset,
1300
+ // but not if the user is swiping
1247
1301
 
1248
- _proto.componentDidMount = function componentDidMount() {
1249
- var _this5 = this;
1250
-
1251
- /* istanbul ignore if (react-native) */
1252
- if (process.env.NODE_ENV !== 'production' && !false && this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
1253
- validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
1254
- }
1255
- /* istanbul ignore if (react-native) */
1256
1302
 
1303
+ var onTouchStart = function () {
1304
+ _this5.isTouchMove = false;
1305
+ };
1257
1306
 
1258
- {
1259
- var targetWithinDownshift = function (target, checkActiveElement) {
1260
- if (checkActiveElement === void 0) {
1261
- checkActiveElement = true;
1262
- }
1307
+ var onTouchMove = function () {
1308
+ _this5.isTouchMove = true;
1309
+ };
1263
1310
 
1264
- var document = _this5.props.environment.document;
1265
- return [_this5._rootNode, _this5._menuNode].some(function (contextNode) {
1266
- return contextNode && (isOrContainsNode(contextNode, target) || checkActiveElement && isOrContainsNode(contextNode, document.activeElement));
1267
- });
1268
- }; // this.isMouseDown helps us track whether the mouse is currently held down.
1269
- // This is useful when the user clicks on an item in the list, but holds the mouse
1270
- // down long enough for the list to disappear (because the blur event fires on the input)
1271
- // this.isMouseDown is used in the blur handler on the input to determine whether the blur event should
1272
- // trigger hiding the menu.
1311
+ var onTouchEnd = function (event) {
1312
+ var contextWithinDownshift = targetWithinDownshift(event.target, false);
1273
1313
 
1314
+ if (!_this5.isTouchMove && !contextWithinDownshift && _this5.getState().isOpen) {
1315
+ _this5.reset({
1316
+ type: touchEnd
1317
+ }, function () {
1318
+ return _this5.props.onOuterClick(_this5.getStateAndHelpers());
1319
+ });
1320
+ }
1321
+ };
1274
1322
 
1275
- var onMouseDown = function () {
1276
- _this5.isMouseDown = true;
1277
- };
1323
+ var environment = this.props.environment;
1324
+ environment.addEventListener('mousedown', onMouseDown);
1325
+ environment.addEventListener('mouseup', onMouseUp);
1326
+ environment.addEventListener('touchstart', onTouchStart);
1327
+ environment.addEventListener('touchmove', onTouchMove);
1328
+ environment.addEventListener('touchend', onTouchEnd);
1278
1329
 
1279
- var onMouseUp = function (event) {
1280
- _this5.isMouseDown = false; // if the target element or the activeElement is within a downshift node
1281
- // then we don't want to reset downshift
1330
+ this.cleanup = function () {
1331
+ _this5.internalClearTimeouts();
1282
1332
 
1283
- var contextWithinDownshift = targetWithinDownshift(event.target);
1333
+ _this5.updateStatus.cancel();
1284
1334
 
1285
- if (!contextWithinDownshift && _this5.getState().isOpen) {
1286
- _this5.reset({
1287
- type: mouseUp
1288
- }, function () {
1289
- return _this5.props.onOuterClick(_this5.getStateAndHelpers());
1290
- });
1291
- }
1292
- }; // Touching an element in iOS gives focus and hover states, but touching out of
1293
- // the element will remove hover, and persist the focus state, resulting in the
1294
- // blur event not being triggered.
1295
- // this.isTouchMove helps us track whether the user is tapping or swiping on a touch screen.
1296
- // If the user taps outside of Downshift, the component should be reset,
1297
- // but not if the user is swiping
1335
+ environment.removeEventListener('mousedown', onMouseDown);
1336
+ environment.removeEventListener('mouseup', onMouseUp);
1337
+ environment.removeEventListener('touchstart', onTouchStart);
1338
+ environment.removeEventListener('touchmove', onTouchMove);
1339
+ environment.removeEventListener('touchend', onTouchEnd);
1340
+ };
1341
+ }
1342
+ };
1298
1343
 
1344
+ _proto.shouldScroll = function shouldScroll(prevState, prevProps) {
1345
+ var _ref10 = this.props.highlightedIndex === undefined ? this.getState() : this.props,
1346
+ currentHighlightedIndex = _ref10.highlightedIndex;
1299
1347
 
1300
- var onTouchStart = function () {
1301
- _this5.isTouchMove = false;
1302
- };
1348
+ var _ref11 = prevProps.highlightedIndex === undefined ? prevState : prevProps,
1349
+ prevHighlightedIndex = _ref11.highlightedIndex;
1303
1350
 
1304
- var onTouchMove = function () {
1305
- _this5.isTouchMove = true;
1306
- };
1351
+ var scrollWhenOpen = currentHighlightedIndex && this.getState().isOpen && !prevState.isOpen;
1352
+ return scrollWhenOpen || currentHighlightedIndex !== prevHighlightedIndex;
1353
+ };
1307
1354
 
1308
- var onTouchEnd = function (event) {
1309
- var contextWithinDownshift = targetWithinDownshift(event.target, false);
1355
+ _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
1356
+ if (process.env.NODE_ENV !== 'production') {
1357
+ validateControlledUnchanged(prevProps, this.props);
1358
+ /* istanbul ignore if (react-native) */
1310
1359
 
1311
- if (!_this5.isTouchMove && !contextWithinDownshift && _this5.getState().isOpen) {
1312
- _this5.reset({
1313
- type: touchEnd
1314
- }, function () {
1315
- return _this5.props.onOuterClick(_this5.getStateAndHelpers());
1316
- });
1360
+ if ( this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
1361
+ validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
1317
1362
  }
1318
- };
1319
-
1320
- var environment = this.props.environment;
1321
- environment.addEventListener('mousedown', onMouseDown);
1322
- environment.addEventListener('mouseup', onMouseUp);
1323
- environment.addEventListener('touchstart', onTouchStart);
1324
- environment.addEventListener('touchmove', onTouchMove);
1325
- environment.addEventListener('touchend', onTouchEnd);
1326
-
1327
- this.cleanup = function () {
1328
- _this5.internalClearTimeouts();
1363
+ }
1329
1364
 
1330
- _this5.updateStatus.cancel();
1365
+ if (this.isControlledProp('selectedItem') && this.props.selectedItemChanged(prevProps.selectedItem, this.props.selectedItem)) {
1366
+ this.internalSetState({
1367
+ type: controlledPropUpdatedSelectedItem,
1368
+ inputValue: this.props.itemToString(this.props.selectedItem)
1369
+ });
1370
+ }
1331
1371
 
1332
- environment.removeEventListener('mousedown', onMouseDown);
1333
- environment.removeEventListener('mouseup', onMouseUp);
1334
- environment.removeEventListener('touchstart', onTouchStart);
1335
- environment.removeEventListener('touchmove', onTouchMove);
1336
- environment.removeEventListener('touchend', onTouchEnd);
1337
- };
1338
- }
1339
- };
1372
+ if (!this.avoidScrolling && this.shouldScroll(prevState, prevProps)) {
1373
+ this.scrollHighlightedItemIntoView();
1374
+ }
1375
+ /* istanbul ignore else (react-native) */
1340
1376
 
1341
- _proto.shouldScroll = function shouldScroll(prevState, prevProps) {
1342
- var _ref10 = this.props.highlightedIndex === undefined ? this.getState() : this.props,
1343
- currentHighlightedIndex = _ref10.highlightedIndex;
1344
1377
 
1345
- var _ref11 = prevProps.highlightedIndex === undefined ? prevState : prevProps,
1346
- prevHighlightedIndex = _ref11.highlightedIndex;
1378
+ this.updateStatus();
1379
+ };
1347
1380
 
1348
- var scrollWhenOpen = currentHighlightedIndex && this.getState().isOpen && !prevState.isOpen;
1349
- return scrollWhenOpen || currentHighlightedIndex !== prevHighlightedIndex;
1350
- };
1381
+ _proto.componentWillUnmount = function componentWillUnmount() {
1382
+ this.cleanup(); // avoids memory leak
1383
+ };
1351
1384
 
1352
- _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
1353
- if (process.env.NODE_ENV !== 'production') {
1354
- validateControlledUnchanged(prevProps, this.props);
1355
- /* istanbul ignore if (react-native) */
1385
+ _proto.render = function render() {
1386
+ var children = unwrapArray(this.props.children, noop); // because the items are rerendered every time we call the children
1387
+ // we clear this out each render and it will be populated again as
1388
+ // getItemProps is called.
1356
1389
 
1357
- if ( this.getMenuProps.called && !this.getMenuProps.suppressRefError) {
1358
- validateGetMenuPropsCalledCorrectly(this._menuNode, this.getMenuProps);
1359
- }
1360
- }
1390
+ this.clearItems(); // we reset this so we know whether the user calls getRootProps during
1391
+ // this render. If they do then we don't need to do anything,
1392
+ // if they don't then we need to clone the element they return and
1393
+ // apply the props for them.
1361
1394
 
1362
- if (this.isControlledProp('selectedItem') && this.props.selectedItemChanged(prevProps.selectedItem, this.props.selectedItem)) {
1363
- this.internalSetState({
1364
- type: controlledPropUpdatedSelectedItem,
1365
- inputValue: this.props.itemToString(this.props.selectedItem)
1366
- });
1367
- }
1395
+ this.getRootProps.called = false;
1396
+ this.getRootProps.refKey = undefined;
1397
+ this.getRootProps.suppressRefError = undefined; // we do something similar for getMenuProps
1368
1398
 
1369
- if (!this.avoidScrolling && this.shouldScroll(prevState, prevProps)) {
1370
- this.scrollHighlightedItemIntoView();
1371
- }
1372
- /* istanbul ignore else (react-native) */
1399
+ this.getMenuProps.called = false;
1400
+ this.getMenuProps.refKey = undefined;
1401
+ this.getMenuProps.suppressRefError = undefined; // we do something similar for getLabelProps
1373
1402
 
1403
+ this.getLabelProps.called = false; // and something similar for getInputProps
1374
1404
 
1375
- this.updateStatus();
1376
- };
1405
+ this.getInputProps.called = false;
1406
+ var element = unwrapArray(children(this.getStateAndHelpers()));
1377
1407
 
1378
- _proto.componentWillUnmount = function componentWillUnmount() {
1379
- this.cleanup(); // avoids memory leak
1380
- };
1408
+ if (!element) {
1409
+ return null;
1410
+ }
1381
1411
 
1382
- _proto.render = function render() {
1383
- var children = unwrapArray(this.props.children, noop); // because the items are rerendered every time we call the children
1384
- // we clear this out each render and it will be populated again as
1385
- // getItemProps is called.
1412
+ if (this.getRootProps.called || this.props.suppressRefError) {
1413
+ if (process.env.NODE_ENV !== 'production' && !this.getRootProps.suppressRefError && !this.props.suppressRefError) {
1414
+ validateGetRootPropsCalledCorrectly(element, this.getRootProps);
1415
+ }
1386
1416
 
1387
- this.clearItems(); // we reset this so we know whether the user calls getRootProps during
1388
- // this render. If they do then we don't need to do anything,
1389
- // if they don't then we need to clone the element they return and
1390
- // apply the props for them.
1417
+ return element;
1418
+ } else if (isDOMElement(element)) {
1419
+ // they didn't apply the root props, but we can clone
1420
+ // this and apply the props ourselves
1421
+ return react.cloneElement(element, this.getRootProps(getElementProps(element)));
1422
+ }
1423
+ /* istanbul ignore else */
1391
1424
 
1392
- this.getRootProps.called = false;
1393
- this.getRootProps.refKey = undefined;
1394
- this.getRootProps.suppressRefError = undefined; // we do something similar for getMenuProps
1395
1425
 
1396
- this.getMenuProps.called = false;
1397
- this.getMenuProps.refKey = undefined;
1398
- this.getMenuProps.suppressRefError = undefined; // we do something similar for getLabelProps
1426
+ if (process.env.NODE_ENV !== 'production') {
1427
+ // they didn't apply the root props, but they need to
1428
+ // otherwise we can't query around the autocomplete
1429
+ throw new Error('downshift: If you return a non-DOM element, you must apply the getRootProps function');
1430
+ }
1431
+ /* istanbul ignore next */
1399
1432
 
1400
- this.getLabelProps.called = false; // and something similar for getInputProps
1401
1433
 
1402
- this.getInputProps.called = false;
1403
- var element = unwrapArray(children(this.getStateAndHelpers()));
1434
+ return undefined;
1435
+ };
1404
1436
 
1405
- if (!element) {
1406
- return null;
1407
- }
1437
+ return Downshift;
1438
+ }(react.Component);
1408
1439
 
1409
- if (this.getRootProps.called || this.props.suppressRefError) {
1410
- if (process.env.NODE_ENV !== 'production' && !this.getRootProps.suppressRefError && !this.props.suppressRefError) {
1411
- validateGetRootPropsCalledCorrectly(element, this.getRootProps);
1440
+ Downshift.defaultProps = {
1441
+ defaultHighlightedIndex: null,
1442
+ defaultIsOpen: false,
1443
+ getA11yStatusMessage: getA11yStatusMessage,
1444
+ itemToString: function itemToString(i) {
1445
+ if (i == null) {
1446
+ return '';
1412
1447
  }
1413
1448
 
1414
- return element;
1415
- } else if (isDOMElement(element)) {
1416
- // they didn't apply the root props, but we can clone
1417
- // this and apply the props ourselves
1418
- return react.cloneElement(element, this.getRootProps(getElementProps(element)));
1419
- }
1420
- /* istanbul ignore else */
1421
-
1422
-
1423
- if (process.env.NODE_ENV !== 'production') {
1424
- // they didn't apply the root props, but they need to
1425
- // otherwise we can't query around the autocomplete
1426
- throw new Error('downshift: If you return a non-DOM element, you must apply the getRootProps function');
1427
- }
1428
- /* istanbul ignore next */
1429
-
1449
+ if (process.env.NODE_ENV !== 'production' && isPlainObject(i) && !i.hasOwnProperty('toString')) {
1450
+ // eslint-disable-next-line no-console
1451
+ 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);
1452
+ }
1430
1453
 
1431
- return undefined;
1454
+ return String(i);
1455
+ },
1456
+ onStateChange: noop,
1457
+ onInputValueChange: noop,
1458
+ onUserAction: noop,
1459
+ onChange: noop,
1460
+ onSelect: noop,
1461
+ onOuterClick: noop,
1462
+ selectedItemChanged: function selectedItemChanged(prevItem, item) {
1463
+ return prevItem !== item;
1464
+ },
1465
+ environment: typeof window === 'undefined'
1466
+ /* istanbul ignore next (ssr) */
1467
+ ? {} : window,
1468
+ stateReducer: function stateReducer(state, stateToSet) {
1469
+ return stateToSet;
1470
+ },
1471
+ suppressRefError: false,
1472
+ scrollIntoView: scrollIntoView
1432
1473
  };
1433
-
1474
+ Downshift.stateChangeTypes = stateChangeTypes;
1434
1475
  return Downshift;
1435
- }(react.Component);
1436
-
1437
- Downshift.defaultProps = {
1438
- defaultHighlightedIndex: null,
1439
- defaultIsOpen: false,
1440
- getA11yStatusMessage: getA11yStatusMessage,
1441
- itemToString: function itemToString(i) {
1442
- if (i == null) {
1443
- return '';
1444
- }
1476
+ }();
1445
1477
 
1446
- if (process.env.NODE_ENV !== 'production' && isPlainObject(i) && !i.hasOwnProperty('toString')) {
1447
- // eslint-disable-next-line no-console
1448
- 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);
1449
- }
1450
-
1451
- return String(i);
1452
- },
1453
- onStateChange: noop,
1454
- onInputValueChange: noop,
1455
- onUserAction: noop,
1456
- onChange: noop,
1457
- onSelect: noop,
1458
- onOuterClick: noop,
1459
- selectedItemChanged: function selectedItemChanged(prevItem, item) {
1460
- return prevItem !== item;
1461
- },
1462
- environment: typeof window === 'undefined'
1463
- /* istanbul ignore next (ssr) */
1464
- ? {} : window,
1465
- stateReducer: function stateReducer(state, stateToSet) {
1466
- return stateToSet;
1467
- },
1468
- suppressRefError: false,
1469
- scrollIntoView: scrollIntoView
1470
- };
1471
- Downshift.stateChangeTypes = stateChangeTypes;
1472
1478
  process.env.NODE_ENV !== "production" ? Downshift.propTypes = {
1473
1479
  children: PropTypes.func,
1474
1480
  defaultHighlightedIndex: PropTypes.number,
@@ -2092,7 +2098,9 @@ function downshiftSelectReducer(state, action) {
2092
2098
  }
2093
2099
  /* eslint-enable complexity */
2094
2100
 
2095
- var validatePropTypes = getPropTypesValidator(useSelect, propTypes);
2101
+ var validatePropTypes = process.env.NODE_ENV === 'production' ?
2102
+ /* istanbul ignore next */
2103
+ null : getPropTypesValidator(useSelect, propTypes);
2096
2104
  var defaultProps = {
2097
2105
  itemToString: itemToString,
2098
2106
  stateReducer: function stateReducer(s, a) {
@@ -2112,7 +2120,11 @@ function useSelect(userProps) {
2112
2120
  userProps = {};
2113
2121
  }
2114
2122
 
2115
- validatePropTypes(userProps); // Props defaults and destructuring.
2123
+ /* istanbul ignore else */
2124
+ if (process.env.NODE_ENV !== 'production') {
2125
+ validatePropTypes(userProps);
2126
+ } // Props defaults and destructuring.
2127
+
2116
2128
 
2117
2129
  var props = _extends({}, defaultProps, {}, userProps);
2118
2130