return initialHighlightedIndex;
if (defaultHighlightedIndex !== undefined) {
return defaultHighlightedIndex;
return items.indexOf(selectedItem);
return getNextWrappingIndex(offset, items.indexOf(selectedItem), items.length, getItemNodeFromIndex, false);
return offset < 0 ? items.length - 1 : 0;
* Reuse the movement tracking of mouse and touch events.
* @param {boolean} isOpen Whether the dropdown is open or not.
* @param {Array<Object>} downshiftElementRefs Downshift element refs to track movement (toggleButton, menu etc.)
* @param {Object} environment Environment where component/hook exists.
* @param {Function} handleBlur Handler on blur from mouse or touch.
* @returns {Object} Ref containing whether mouseDown or touchMove event is happening
function useMouseAndTouchTracker(isOpen, downshiftElementRefs, environment, handleBlur) {
var mouseAndTouchTrackersRef = Object(external_React_["useRef"])({
Object(external_React_["useEffect"])(function () {
// The same strategy for checking if a click occurred inside or outside downsift
var onMouseDown = function onMouseDown() {
mouseAndTouchTrackersRef.current.isMouseDown = true;
var onMouseUp = function onMouseUp(event) {
mouseAndTouchTrackersRef.current.isMouseDown = false;
if (isOpen && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
var onTouchStart = function onTouchStart() {
mouseAndTouchTrackersRef.current.isTouchMove = false;
var onTouchMove = function onTouchMove() {
mouseAndTouchTrackersRef.current.isTouchMove = true;
var onTouchEnd = function onTouchEnd(event) {
if (isOpen && !mouseAndTouchTrackersRef.current.isTouchMove && !targetWithinDownshift(event.target, downshiftElementRefs.map(function (ref) {
}), environment, false)) {
environment.addEventListener('mousedown', onMouseDown);
environment.addEventListener('mouseup', onMouseUp);
environment.addEventListener('touchstart', onTouchStart);
environment.addEventListener('touchmove', onTouchMove);
environment.addEventListener('touchend', onTouchEnd);
return function cleanup() {
environment.removeEventListener('mousedown', onMouseDown);
environment.removeEventListener('mouseup', onMouseUp);
environment.removeEventListener('touchstart', onTouchStart);
environment.removeEventListener('touchmove', onTouchMove);
environment.removeEventListener('touchend', onTouchEnd);
}; // eslint-disable-next-line react-hooks/exhaustive-deps
}, [isOpen, environment]);
return mouseAndTouchTrackersRef;
/* istanbul ignore next */
// eslint-disable-next-line import/no-mutable-exports
var useGetterPropsCalledChecker = function useGetterPropsCalledChecker() {
return downshift_esm_noop;
* Custom hook that checks if getter props are called correctly.
* @param {...any} propKeys Getter prop names to be handled.
* @returns {Function} Setter function called inside getter props to set call information.
/* istanbul ignore next */
function useA11yMessageSetter(getA11yMessage, dependencyArray, _ref2) {
var isInitialMount = _ref2.isInitialMount,
highlightedIndex = _ref2.highlightedIndex,
environment = _ref2.environment,
rest = objectWithoutPropertiesLoose_objectWithoutPropertiesLoose(_ref2, _excluded$3);
// Sets a11y status message on changes in state.
Object(external_React_["useEffect"])(function () {
if (isInitialMount || false) {
updateA11yStatus(function () {
return getA11yMessage(extends_extends({
highlightedIndex: highlightedIndex,
highlightedItem: items[highlightedIndex],
resultCount: items.length
}, environment.document); // eslint-disable-next-line react-hooks/exhaustive-deps
function useScrollIntoView(_ref3) {
var highlightedIndex = _ref3.highlightedIndex,
itemRefs = _ref3.itemRefs,
getItemNodeFromIndex = _ref3.getItemNodeFromIndex,
menuElement = _ref3.menuElement,
scrollIntoViewProp = _ref3.scrollIntoView;
// used not to scroll on highlight by mouse.
var shouldScrollRef = Object(external_React_["useRef"])(true); // Scroll on highlighted item if change comes from keyboard.
useIsomorphicLayoutEffect(function () {
if (highlightedIndex < 0 || !isOpen || !Object.keys(itemRefs.current).length) {
if (shouldScrollRef.current === false) {
shouldScrollRef.current = true;
scrollIntoViewProp(getItemNodeFromIndex(highlightedIndex), menuElement);
} // eslint-disable-next-line react-hooks/exhaustive-deps
} // eslint-disable-next-line import/no-mutable-exports
var useControlPropsValidator = downshift_esm_noop;
/* istanbul ignore next */
/* eslint-disable complexity */
function downshiftCommonReducer(state, action, stateChangeTypes) {
case stateChangeTypes.ItemMouseMove:
highlightedIndex: action.index
case stateChangeTypes.MenuMouseLeave:
case stateChangeTypes.ToggleButtonClick:
case stateChangeTypes.FunctionToggleMenu:
highlightedIndex: state.isOpen ? -1 : getHighlightedIndexOnOpen(props, state, 0)
case stateChangeTypes.FunctionOpenMenu:
highlightedIndex: getHighlightedIndexOnOpen(props, state, 0)
case stateChangeTypes.FunctionCloseMenu:
case stateChangeTypes.FunctionSetHighlightedIndex:
highlightedIndex: action.highlightedIndex
case stateChangeTypes.FunctionSetInputValue:
inputValue: action.inputValue
case stateChangeTypes.FunctionReset:
highlightedIndex: getDefaultValue$1(props, 'highlightedIndex'),
isOpen: getDefaultValue$1(props, 'isOpen'),
selectedItem: getDefaultValue$1(props, 'selectedItem'),
inputValue: getDefaultValue$1(props, 'inputValue')
throw new Error('Reducer called without proper action type.');
return extends_extends({}, state, changes);
/* eslint-enable complexity */
function getItemIndexByCharacterKey(_a) {
var keysSoFar = _a.keysSoFar, highlightedIndex = _a.highlightedIndex, items = _a.items, itemToString = _a.itemToString, getItemNodeFromIndex = _a.getItemNodeFromIndex;
var lowerCasedKeysSoFar = keysSoFar.toLowerCase();
for (var index = 0; index < items.length; index++) {
var offsetIndex = (index + highlightedIndex + 1) % items.length;
var item = items[offsetIndex];
if (item !== undefined &&
.startsWith(lowerCasedKeysSoFar)) {
var element = getItemNodeFromIndex(offsetIndex);
if (!(element === null || element === void 0 ? void 0 : element.hasAttribute('disabled'))) {
items: prop_types_default.a.array.isRequired,
itemToString: prop_types_default.a.func,
getA11yStatusMessage: prop_types_default.a.func,
getA11ySelectionMessage: prop_types_default.a.func,
circularNavigation: prop_types_default.a.bool,
highlightedIndex: prop_types_default.a.number,
defaultHighlightedIndex: prop_types_default.a.number,
initialHighlightedIndex: prop_types_default.a.number,
isOpen: prop_types_default.a.bool,
defaultIsOpen: prop_types_default.a.bool,
initialIsOpen: prop_types_default.a.bool,
selectedItem: prop_types_default.a.any,
initialSelectedItem: prop_types_default.a.any,
defaultSelectedItem: prop_types_default.a.any,
id: prop_types_default.a.string,
labelId: prop_types_default.a.string,
menuId: prop_types_default.a.string,
getItemId: prop_types_default.a.func,
toggleButtonId: prop_types_default.a.string,
stateReducer: prop_types_default.a.func,
onSelectedItemChange: prop_types_default.a.func,
onHighlightedIndexChange: prop_types_default.a.func,
onStateChange: prop_types_default.a.func,
onIsOpenChange: prop_types_default.a.func,
environment: prop_types_default.a.shape({
addEventListener: prop_types_default.a.func,
removeEventListener: prop_types_default.a.func,
document: prop_types_default.a.shape({
getElementById: prop_types_default.a.func,
activeElement: prop_types_default.a.any,
body: prop_types_default.a.any
* Default implementation for status message. Only added when menu is open.
* Will specift if there are results in the list, and if so, how many,
* and what keys are relevant.
* @param {Object} param the downshift state and other relevant properties
* @return {String} the a11y status message
function downshift_esm_getA11yStatusMessage(_a) {
var isOpen = _a.isOpen, resultCount = _a.resultCount, previousResultCount = _a.previousResultCount;
return 'No results are available.';
if (resultCount !== previousResultCount) {
return resultCount + " result" + (resultCount === 1 ? ' is' : 's are') + " available, use up and down arrow keys to navigate. Press Enter or Space Bar keys to select.";
var defaultProps$2 = __assign(__assign({}, defaultProps$3), { getA11yStatusMessage: downshift_esm_getA11yStatusMessage });
// eslint-disable-next-line import/no-mutable-exports
var validatePropTypes$2 = downshift_esm_noop;
/* istanbul ignore next */
var MenuKeyDownArrowDown = false ? undefined : 0;
var MenuKeyDownArrowUp = false ? undefined : 1;
var MenuKeyDownEscape = false ? undefined : 2;
var MenuKeyDownHome = false ? undefined : 3;
var MenuKeyDownEnd = false ? undefined : 4;
var MenuKeyDownEnter = false ? undefined : 5;
var MenuKeyDownSpaceButton = false ? undefined : 6;
var MenuKeyDownCharacter = false ? undefined : 7;
var MenuBlur = false ? undefined : 8;
var MenuMouseLeave$1 = false ? undefined : 9;
var ItemMouseMove$1 = false ? undefined : 10;
var ItemClick$1 = false ? undefined : 11;
var ToggleButtonClick$1 = false ? undefined : 12;
var ToggleButtonKeyDownArrowDown = false ? undefined : 13;
var ToggleButtonKeyDownArrowUp = false ? undefined : 14;
var ToggleButtonKeyDownCharacter = false ? undefined : 15;
var FunctionToggleMenu$1 = false ? undefined : 16;
var FunctionOpenMenu$1 = false ? undefined : 17;
var FunctionCloseMenu$1 = false ? undefined : 18;
var FunctionSetHighlightedIndex$1 = false ? undefined : 19;
var FunctionSelectItem$1 = false ? undefined : 20;
var FunctionSetInputValue$1 = false ? undefined : 21;
var FunctionReset$2 = false ? undefined : 22;
var stateChangeTypes$2 = /*#__PURE__*/Object.freeze({
MenuKeyDownArrowDown: MenuKeyDownArrowDown,
MenuKeyDownArrowUp: MenuKeyDownArrowUp,
MenuKeyDownEscape: MenuKeyDownEscape,
MenuKeyDownHome: MenuKeyDownHome,
MenuKeyDownEnd: MenuKeyDownEnd,
MenuKeyDownEnter: MenuKeyDownEnter,
MenuKeyDownSpaceButton: MenuKeyDownSpaceButton,
MenuKeyDownCharacter: MenuKeyDownCharacter,
MenuMouseLeave: MenuMouseLeave$1,
ItemMouseMove: ItemMouseMove$1,
ToggleButtonClick: ToggleButtonClick$1,
ToggleButtonKeyDownArrowDown: ToggleButtonKeyDownArrowDown,
ToggleButtonKeyDownArrowUp: ToggleButtonKeyDownArrowUp,
ToggleButtonKeyDownCharacter: ToggleButtonKeyDownCharacter,
FunctionToggleMenu: FunctionToggleMenu$1,
FunctionOpenMenu: FunctionOpenMenu$1,
FunctionCloseMenu: FunctionCloseMenu$1,
FunctionSetHighlightedIndex: FunctionSetHighlightedIndex$1,
FunctionSelectItem: FunctionSelectItem$1,
FunctionSetInputValue: FunctionSetInputValue$1,
FunctionReset: FunctionReset$2
/* eslint-disable complexity */
function downshiftSelectReducer(state, action) {
shiftKey = action.shiftKey;
isOpen: getDefaultValue$1(props, 'isOpen'),
highlightedIndex: getDefaultValue$1(props, 'highlightedIndex'),
selectedItem: props.items[action.index]
case ToggleButtonKeyDownCharacter:
var lowercasedKey = action.key;
var inputValue = "" + state.inputValue + lowercasedKey;
var itemIndex = getItemIndexByCharacterKey({
highlightedIndex: state.selectedItem ? props.items.indexOf(state.selectedItem) : -1,
itemToString: props.itemToString,
getItemNodeFromIndex: action.getItemNodeFromIndex
changes = extends_extends({
selectedItem: props.items[itemIndex]
case ToggleButtonKeyDownArrowDown:
highlightedIndex: getHighlightedIndexOnOpen(props, state, 1, action.getItemNodeFromIndex),
case ToggleButtonKeyDownArrowUp:
highlightedIndex: getHighlightedIndexOnOpen(props, state, -1, action.getItemNodeFromIndex),
case MenuKeyDownSpaceButton:
changes = extends_extends({
isOpen: getDefaultValue$1(props, 'isOpen'),
highlightedIndex: getDefaultValue$1(props, 'highlightedIndex')
}, state.highlightedIndex >= 0 && {
selectedItem: props.items[state.highlightedIndex]
highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false)
highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false)
case MenuKeyDownCharacter:
var _lowercasedKey = action.key;
var _inputValue = "" + state.inputValue + _lowercasedKey;
var highlightedIndex = getItemIndexByCharacterKey({
highlightedIndex: state.highlightedIndex,
itemToString: props.itemToString,
getItemNodeFromIndex: action.getItemNodeFromIndex
changes = extends_extends({
}, highlightedIndex >= 0 && {
highlightedIndex: highlightedIndex
case MenuKeyDownArrowDown:
highlightedIndex: getNextWrappingIndex(shiftKey ? 5 : 1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, props.circularNavigation)
highlightedIndex: getNextWrappingIndex(shiftKey ? -5 : -1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, props.circularNavigation)
case FunctionSelectItem$1:
selectedItem: action.selectedItem
return downshiftCommonReducer(state, action, stateChangeTypes$2);
return extends_extends({}, state, changes);
/* eslint-enable complexity */
var _excluded$2 = ["onMouseLeave", "refKey", "onKeyDown", "onBlur", "ref"],
_excluded2$2 = ["onClick", "onKeyDown", "refKey", "ref"],
_excluded3$1 = ["item", "index", "onMouseMove", "onClick", "refKey", "ref"];
useSelect.stateChangeTypes = stateChangeTypes$2;
function useSelect(userProps) {
if (userProps === void 0) {