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