: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* @param {HTMLElement} child the child node
* @param {Window} environment The window context where downshift renders.
* @return {Boolean} whether the parent is the child or the child is in the parent
function isOrContainsNode(parent, child, environment) {
const result = parent === child || child instanceof environment.Node && parent.contains && parent.contains(child);
* Simple debounce implementation. Will call the given
* function once after the time given has passed since
* @param {Function} fn the function to call after the time
* @param {Number} time the time to wait
* @return {Function} the debounced function
function debounce(fn, time) {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
timeoutId = setTimeout(() => {
* This is intended to be used to compose event handlers.
* They are executed in order until one of them sets
* `event.preventDownshiftDefault = true`.
* @param {...Function} fns the event handler functions
* @return {Function} the event handler to add to an element
function callAllEventHandlers() {
for (var _len2 = arguments.length, fns = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
fns[_key2] = arguments[_key2];
return function (event) {
for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
args[_key3 - 1] = arguments[_key3];
return event.preventDownshiftDefault || event.hasOwnProperty('nativeEvent') && event.nativeEvent.preventDownshiftDefault;
for (var _len4 = arguments.length, refs = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
refs[_key4] = arguments[_key4];
if (typeof ref === 'function') {
* This generates a unique ID for an instance of Downshift
* @return {String} the unique ID
return String(idCounter++);
* Resets idCounter to 0. Used for SSR.
function resetIdCounter() {
* Default implementation for status message. Only added when menu is open.
* Will specify 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 getA11yStatusMessage$1(_ref2) {
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 key to select.`;
* Takes an argument and if it's an array, returns the first item in the array
* otherwise returns the argument
* @param {*} arg the maybe-array
* @param {*} defaultValue the value if arg is falsey not defined
* @return {*} the arg or it's first item
function unwrapArray(arg, defaultValue) {
arg = Array.isArray(arg) ?
/* istanbul ignore next (preact) */
if (!arg && defaultValue) {
* @param {Object} element (P)react element
* @return {Boolean} whether it's a DOM element
function isDOMElement(element) {
return typeof element.type === 'string';
* @param {Object} element (P)react element
* @return {Object} the props
function getElementProps(element) {
* Throws a helpful error message for required properties. Useful
* to be used as a default in destructuring or object params.
* @param {String} fnName the function name
* @param {String} propName the prop name
function requiredProp(fnName, propName) {
// eslint-disable-next-line no-console
console.error(`The property "${propName}" is required in "${fnName}"`);
const stateKeys = (/* unused pure expression or super */ null && (['highlightedIndex', 'inputValue', 'isOpen', 'selectedItem', 'type']));
* @param {Object} state the state object
* @return {Object} state that is relevant to downshift
function pickState(state) {
if (state.hasOwnProperty(k)) {
* This will perform a shallow merge of the given state object
* with the state coming from props
* (for the controlled component scenario)
* This is used in state updater functions so they're referencing
* the right state regardless of where it comes from.
* @param {Object} state The state of the component/hook.
* @param {Object} props The props that may contain controlled values.
* @returns {Object} The merged controlled state.
function getState(state, props) {
return Object.keys(state).reduce((prevState, key) => {
prevState[key] = isControlledProp(props, key) ? props[key] : state[key];
* This determines whether a prop is a "controlled prop" meaning it is
* state which is controlled by the outside of this component rather
* than within this component.
* @param {Object} props The props that may contain controlled values.
* @param {String} key the key to check
* @return {Boolean} whether it is a controlled controlled prop
function isControlledProp(props, key) {
return props[key] !== undefined;
* Normalizes the 'key' property of a KeyboardEvent in IE/Edge
* @param {Object} event a keyboardEvent object
* @return {String} keyboard key
function normalizeArrowKey(event) {
/* istanbul ignore next (ie) */
if (keyCode >= 37 && keyCode <= 40 && key.indexOf('Arrow') !== 0) {
* Simple check if the value passed is object literal
* @param {*} obj any things
* @return {Boolean} whether it's object literal
function downshift_esm_isPlainObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
* Returns the new index in the list, in a circular way. If next value is out of bonds from the total,
* it will wrap to either 0 or itemCount - 1.
* @param {number} moveAmount Number of positions to move. Negative to move backwards, positive forwards.
* @param {number} baseIndex The initial position to move from.
* @param {number} itemCount The total number of items.
* @param {Function} getItemNodeFromIndex Used to check if item is disabled.
* @param {boolean} circular Specify if navigation is circular. Default is true.
* @returns {number} The new index after the move.
function getNextWrappingIndex(moveAmount, baseIndex, itemCount, getItemNodeFromIndex, circular) {
if (circular === void 0) {
const itemsLastIndex = itemCount - 1;
if (typeof baseIndex !== 'number' || baseIndex < 0 || baseIndex >= itemCount) {
baseIndex = moveAmount > 0 ? -1 : itemsLastIndex + 1;
let newIndex = baseIndex + moveAmount;
newIndex = circular ? itemsLastIndex : 0;
} else if (newIndex > itemsLastIndex) {
newIndex = circular ? 0 : itemsLastIndex;
const nonDisabledNewIndex = getNextNonDisabledIndex(moveAmount, newIndex, itemCount, getItemNodeFromIndex, circular);
if (nonDisabledNewIndex === -1) {
return baseIndex >= itemCount ? -1 : baseIndex;
return nonDisabledNewIndex;
* Returns the next index in the list of an item that is not disabled.
* @param {number} moveAmount Number of positions to move. Negative to move backwards, positive forwards.
* @param {number} baseIndex The initial position to move from.
* @param {number} itemCount The total number of items.
* @param {Function} getItemNodeFromIndex Used to check if item is disabled.
* @param {boolean} circular Specify if navigation is circular. Default is true.
* @returns {number} The new index. Returns baseIndex if item is not disabled. Returns next non-disabled item otherwise. If no non-disabled found it will return -1.
function getNextNonDisabledIndex(moveAmount, baseIndex, itemCount, getItemNodeFromIndex, circular) {
const currentElementNode = getItemNodeFromIndex(baseIndex);
if (!currentElementNode || !currentElementNode.hasAttribute('disabled')) {
for (let index = baseIndex + 1; index < itemCount; index++) {
if (!getItemNodeFromIndex(index).hasAttribute('disabled')) {
for (let index = baseIndex - 1; index >= 0; index--) {
if (!getItemNodeFromIndex(index).hasAttribute('disabled')) {
return moveAmount > 0 ? getNextNonDisabledIndex(1, 0, itemCount, getItemNodeFromIndex, false) : getNextNonDisabledIndex(-1, itemCount - 1, itemCount, getItemNodeFromIndex, false);
* Checks if event target is within the downshift elements.
* @param {EventTarget} target Target to check.
* @param {HTMLElement[]} downshiftElements The elements that form downshift (list, toggle button etc).
* @param {Window} environment The window context where downshift renders.
* @param {boolean} checkActiveElement Whether to also check activeElement.
* @returns {boolean} Whether or not the target is within downshift elements.
function targetWithinDownshift(target, downshiftElements, environment, checkActiveElement) {
if (checkActiveElement === void 0) {
checkActiveElement = true;
return downshiftElements.some(contextNode => contextNode && (isOrContainsNode(contextNode, target, environment) || checkActiveElement && isOrContainsNode(contextNode, environment.document.activeElement, environment)));
} // eslint-disable-next-line import/no-mutable-exports
let validateControlledUnchanged = (/* unused pure expression or super */ null && (downshift_esm_noop));
/* istanbul ignore next */
const cleanupStatus = debounce(documentProp => {
getStatusDiv(documentProp).textContent = '';
* @param {String} status the status message
* @param {Object} documentProp document passed by the user.
function setStatus(status, documentProp) {
const div = getStatusDiv(documentProp);
div.textContent = status;
cleanupStatus(documentProp);
* Get the status node or create it if it does not already exist.
* @param {Object} documentProp document passed by the user.
* @return {HTMLElement} the status node.
function getStatusDiv(documentProp) {
if (documentProp === void 0) {
let statusDiv = documentProp.getElementById('a11y-status-message');
statusDiv = documentProp.createElement('div');
statusDiv.setAttribute('id', 'a11y-status-message');
statusDiv.setAttribute('role', 'status');
statusDiv.setAttribute('aria-live', 'polite');
statusDiv.setAttribute('aria-relevant', 'additions text');
Object.assign(statusDiv.style, {
documentProp.body.appendChild(statusDiv);
const unknown = false ? 0 : 0;
const mouseUp = false ? 0 : 1;
const itemMouseEnter = false ? 0 : 2;
const keyDownArrowUp = false ? 0 : 3;
const keyDownArrowDown = false ? 0 : 4;
const keyDownEscape = false ? 0 : 5;
const keyDownEnter = false ? 0 : 6;
const keyDownHome = false ? 0 : 7;
const keyDownEnd = false ? 0 : 8;
const clickItem = false ? 0 : 9;
const blurInput = false ? 0 : 10;
const changeInput = false ? 0 : 11;
const keyDownSpaceButton = false ? 0 : 12;
const clickButton = false ? 0 : 13;
const blurButton = false ? 0 : 14;
const controlledPropUpdatedSelectedItem = false ? 0 : 15;
const touchEnd = false ? 0 : 16;
var stateChangeTypes$3 = /*#__PURE__*/Object.freeze({
itemMouseEnter: itemMouseEnter,
keyDownArrowUp: keyDownArrowUp,
keyDownArrowDown: keyDownArrowDown,
keyDownEscape: keyDownEscape,
keyDownEnter: keyDownEnter,
keyDownHome: keyDownHome,
changeInput: changeInput,
keyDownSpaceButton: keyDownSpaceButton,
clickButton: clickButton,
controlledPropUpdatedSelectedItem: controlledPropUpdatedSelectedItem,
const Downshift = /*#__PURE__*/(/* unused pure expression or super */ null && ((() => {
class Downshift extends Component {
this.id = this.props.id || `downshift-${generateId()}`;
this.menuId = this.props.menuId || `${this.id}-menu`;
this.labelId = this.props.labelId || `${this.id}-label`;
this.inputId = this.props.inputId || `${this.id}-input`;
this.getItemId = this.props.getItemId || (index => `${this.id}-item-${index}`);
this.previousResultCount = 0;
this.internalSetTimeout = (fn, time) => {
const id = setTimeout(() => {
this.timeoutIds = this.timeoutIds.filter(i => i !== id);