MenuMouseLeave: MenuMouseLeave,
ItemMouseMove: ItemMouseMove,
ToggleButtonClick: ToggleButtonClick,
FunctionToggleMenu: FunctionToggleMenu,
FunctionOpenMenu: FunctionOpenMenu,
FunctionCloseMenu: FunctionCloseMenu,
FunctionSetHighlightedIndex: FunctionSetHighlightedIndex,
FunctionSelectItem: FunctionSelectItem,
FunctionSetInputValue: FunctionSetInputValue,
FunctionReset: FunctionReset$1,
ControlledPropUpdatedSelectedItem: ControlledPropUpdatedSelectedItem
function getInitialState$1(props) {
var initialState = getInitialState$2(props);
var selectedItem = initialState.selectedItem;
var inputValue = initialState.inputValue;
if (inputValue === '' && selectedItem && props.defaultInputValue === undefined && props.initialInputValue === undefined && props.inputValue === undefined) {
inputValue = props.itemToString(selectedItem);
return extends_extends({}, initialState, {
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,
inputValue: prop_types_default.a.string,
defaultInputValue: prop_types_default.a.string,
initialInputValue: prop_types_default.a.string,
id: prop_types_default.a.string,
labelId: prop_types_default.a.string,
menuId: prop_types_default.a.string,
getItemId: prop_types_default.a.func,
inputId: prop_types_default.a.string,
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,
onInputValueChange: 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
* The useCombobox version of useControlledReducer, which also
* checks if the controlled prop selectedItem changed between
* renders. If so, it will also update inputValue with its
* string equivalent. It uses the common useEnhancedReducer to
* compute the rest of the state.
* @param {Function} reducer Reducer function from downshift.
* @param {Object} initialState Initial state of the hook.
* @param {Object} props The hook props.
* @returns {Array} An array with the state and an action dispatcher.
function useControlledReducer(reducer, initialState, props) {
var previousSelectedItemRef = Object(external_React_["useRef"])();
var _useEnhancedReducer = useEnhancedReducer(reducer, initialState, props),
state = _useEnhancedReducer[0],
dispatch = _useEnhancedReducer[1]; // ToDo: if needed, make same approach as selectedItemChanged from Downshift.
Object(external_React_["useEffect"])(function () {
if (isControlledProp(props, 'selectedItem')) {
if (previousSelectedItemRef.current !== props.selectedItem) {
type: ControlledPropUpdatedSelectedItem,
inputValue: props.itemToString(props.selectedItem)
previousSelectedItemRef.current = state.selectedItem === previousSelectedItemRef.current ? props.selectedItem : state.selectedItem;
return [getState(state, props), dispatch];
} // eslint-disable-next-line import/no-mutable-exports
var validatePropTypes$1 = downshift_esm_noop;
/* istanbul ignore next */
var defaultProps$1 = extends_extends({}, defaultProps$3, {
getA11yStatusMessage: getA11yStatusMessage$1,
/* eslint-disable complexity */
function downshiftUseComboboxReducer(state, action) {
shiftKey = action.shiftKey;
isOpen: getDefaultValue$1(props, 'isOpen'),
highlightedIndex: getDefaultValue$1(props, 'highlightedIndex'),
selectedItem: props.items[action.index],
inputValue: props.itemToString(props.items[action.index])
case InputKeyDownArrowDown:
highlightedIndex: getNextWrappingIndex(shiftKey ? 5 : 1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, props.circularNavigation)
highlightedIndex: getHighlightedIndexOnOpen(props, state, 1, action.getItemNodeFromIndex),
isOpen: props.items.length >= 0
case InputKeyDownArrowUp:
highlightedIndex: getNextWrappingIndex(shiftKey ? -5 : -1, state.highlightedIndex, props.items.length, action.getItemNodeFromIndex, props.circularNavigation)
highlightedIndex: getHighlightedIndexOnOpen(props, state, -1, action.getItemNodeFromIndex),
isOpen: props.items.length >= 0
changes = extends_extends({}, state.isOpen && state.highlightedIndex >= 0 && {
selectedItem: props.items[state.highlightedIndex],
isOpen: getDefaultValue$1(props, 'isOpen'),
highlightedIndex: getDefaultValue$1(props, 'highlightedIndex'),
inputValue: props.itemToString(props.items[state.highlightedIndex])
changes = extends_extends({
highlightedIndex: getNextNonDisabledIndex(1, 0, props.items.length, action.getItemNodeFromIndex, false)
highlightedIndex: getNextNonDisabledIndex(-1, props.items.length - 1, props.items.length, action.getItemNodeFromIndex, false)
changes = extends_extends({
}, state.highlightedIndex >= 0 && action.selectItem && {
selectedItem: props.items[state.highlightedIndex],
inputValue: props.itemToString(props.items[state.highlightedIndex])
highlightedIndex: getDefaultValue$1(props, 'highlightedIndex'),
inputValue: action.inputValue
selectedItem: action.selectedItem,
inputValue: props.itemToString(action.selectedItem)
case ControlledPropUpdatedSelectedItem:
inputValue: action.inputValue
return downshiftCommonReducer(state, action, stateChangeTypes$1);
return extends_extends({}, state, changes);
/* eslint-enable complexity */
var _excluded$1 = ["onMouseLeave", "refKey", "ref"],
_excluded2$1 = ["item", "index", "refKey", "ref", "onMouseMove", "onClick", "onPress"],
_excluded3 = ["onClick", "onPress", "refKey", "ref"],
_excluded4 = ["onKeyDown", "onChange", "onInput", "onBlur", "onChangeText", "refKey", "ref"],
_excluded5 = ["refKey", "ref"];
useCombobox.stateChangeTypes = stateChangeTypes$1;
function useCombobox(userProps) {
if (userProps === void 0) {
validatePropTypes$1(userProps, useCombobox); // Props defaults and destructuring.
var props = extends_extends({}, defaultProps$1, userProps);
var initialIsOpen = props.initialIsOpen,
defaultIsOpen = props.defaultIsOpen,
scrollIntoView = props.scrollIntoView,
environment = props.environment,
getA11yStatusMessage = props.getA11yStatusMessage,
getA11ySelectionMessage = props.getA11ySelectionMessage,
itemToString = props.itemToString; // Initial state depending on controlled props.
var initialState = getInitialState$1(props);
var _useControlledReducer = useControlledReducer(downshiftUseComboboxReducer, initialState, props),
state = _useControlledReducer[0],
dispatch = _useControlledReducer[1];
var isOpen = state.isOpen,
highlightedIndex = state.highlightedIndex,
selectedItem = state.selectedItem,
inputValue = state.inputValue; // Element refs.
var menuRef = Object(external_React_["useRef"])(null);
var itemRefs = Object(external_React_["useRef"])({});
var inputRef = Object(external_React_["useRef"])(null);
var toggleButtonRef = Object(external_React_["useRef"])(null);
var comboboxRef = Object(external_React_["useRef"])(null);
var isInitialMountRef = Object(external_React_["useRef"])(true); // prevent id re-generation between renders.
var elementIds = useElementIds(props); // used to keep track of how many items we had on previous cycle.
var previousResultCountRef = Object(external_React_["useRef"])(); // utility callback to get item element.
var latest = useLatestRef({
var getItemNodeFromIndex = Object(external_React_["useCallback"])(function (index) {
return itemRefs.current[elementIds.getItemId(index)];
}, [elementIds]); // Effects.
// Sets a11y status message on changes in state.
useA11yMessageSetter(getA11yStatusMessage, [isOpen, highlightedIndex, inputValue, items], extends_extends({
isInitialMount: isInitialMountRef.current,
previousResultCount: previousResultCountRef.current,
environment: environment,
itemToString: itemToString
}, state)); // Sets a11y status message on changes in selectedItem.
useA11yMessageSetter(getA11ySelectionMessage, [selectedItem], extends_extends({
isInitialMount: isInitialMountRef.current,
previousResultCount: previousResultCountRef.current,
environment: environment,
itemToString: itemToString
}, state)); // Scroll on highlighted item if change comes from keyboard.
var shouldScrollRef = useScrollIntoView({
menuElement: menuRef.current,
highlightedIndex: highlightedIndex,
scrollIntoView: scrollIntoView,
getItemNodeFromIndex: getItemNodeFromIndex
useControlPropsValidator({
isInitialMount: isInitialMountRef.current,
}); // Focus the input on first render if required.
Object(external_React_["useEffect"])(function () {
var focusOnOpen = initialIsOpen || defaultIsOpen || isOpen;
if (focusOnOpen && inputRef.current) {
inputRef.current.focus();
} // eslint-disable-next-line react-hooks/exhaustive-deps
Object(external_React_["useEffect"])(function () {
if (isInitialMountRef.current) {
previousResultCountRef.current = items.length;
}); // Add mouse/touch events to document.
var mouseAndTouchTrackersRef = useMouseAndTouchTracker(isOpen, [comboboxRef, menuRef, toggleButtonRef], environment, function () {
var setGetterPropCallInfo = useGetterPropsCalledChecker('getInputProps', 'getComboboxProps', 'getMenuProps'); // Make initial ref false.
Object(external_React_["useEffect"])(function () {
isInitialMountRef.current = false;
}, []); // Reset itemRefs on close.
Object(external_React_["useEffect"])(function () {
/* Event handler functions */
var inputKeyDownHandlers = Object(external_React_["useMemo"])(function () {
ArrowDown: function ArrowDown(event) {
type: InputKeyDownArrowDown,
shiftKey: event.shiftKey,
getItemNodeFromIndex: getItemNodeFromIndex
ArrowUp: function ArrowUp(event) {
type: InputKeyDownArrowUp,
shiftKey: event.shiftKey,
getItemNodeFromIndex: getItemNodeFromIndex
Home: function Home(event) {
if (!latest.current.state.isOpen) {
getItemNodeFromIndex: getItemNodeFromIndex
End: function End(event) {
if (!latest.current.state.isOpen) {
getItemNodeFromIndex: getItemNodeFromIndex
Escape: function Escape() {
var latestState = latest.current.state;
if (latestState.isOpen || latestState.inputValue || latestState.selectedItem || latestState.highlightedIndex > -1) {
Enter: function Enter(event) {
var latestState = latest.current.state; // if closed or no highlighted index, do nothing.
if (!latestState.isOpen || latestState.highlightedIndex < 0 || event.which === 229 // if IME composing, wait for next Enter keydown event.
getItemNodeFromIndex: getItemNodeFromIndex
}, [dispatch, latest, getItemNodeFromIndex]); // Getter props.
var getLabelProps = Object(external_React_["useCallback"])(function (labelProps) {
htmlFor: elementIds.inputId
var getMenuProps = Object(external_React_["useCallback"])(function (_temp, _temp2) {
var _ref = _temp === void 0 ? {} : _temp,
onMouseLeave = _ref.onMouseLeave,
_ref$refKey = _ref.refKey,
refKey = _ref$refKey === void 0 ? 'ref' : _ref$refKey,
rest = objectWithoutPropertiesLoose_objectWithoutPropertiesLoose(_ref, _excluded$1);
var _ref2 = _temp2 === void 0 ? {} : _temp2,
_ref2$suppressRefErro = _ref2.suppressRefError,
suppressRefError = _ref2$suppressRefErro === void 0 ? false : _ref2$suppressRefErro;
setGetterPropCallInfo('getMenuProps', suppressRefError, refKey, menuRef);
return extends_extends((_extends2 = {}, _extends2[refKey] = handleRefs(ref, function (menuNode) {
menuRef.current = menuNode;
}), _extends2.id = elementIds.menuId, _extends2.role = 'listbox', _extends2['aria-labelledby'] = elementIds.labelId, _extends2.onMouseLeave = callAllEventHandlers(onMouseLeave, function () {
}, [dispatch, setGetterPropCallInfo, elementIds]);
var getItemProps = Object(external_React_["useCallback"])(function (_temp3) {
var _ref3 = _temp3 === void 0 ? {} : _temp3,
_ref3$refKey = _ref3.refKey,
refKey = _ref3$refKey === void 0 ? 'ref' : _ref3$refKey,
onMouseMove = _ref3.onMouseMove,
var rest = objectWithoutPropertiesLoose_objectWithoutPropertiesLoose(_ref3, _excluded2$1);
var _latest$current = latest.current,
latestProps = _latest$current.props,
latestState = _latest$current.state;
var itemIndex = getItemIndex(index, item, latestProps.items);
throw new Error('Pass either item or item index in getItemProps!');
var onSelectKey = 'onClick';
var customClickHandler = onClick;
var itemHandleMouseMove = function itemHandleMouseMove() {
if (index === latestState.highlightedIndex) {
shouldScrollRef.current = false;
var itemHandleClick = function itemHandleClick() {
inputRef.current.focus();
return extends_extends((_extends3 = {}, _extends3[refKey] = handleRefs(ref, function (itemNode) {
itemRefs.current[elementIds.getItemId(itemIndex)] = itemNode;