react-bootstrap-typeahead
Version:
React typeahead with Bootstrap styling
78 lines (75 loc) • 3.58 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["label", "onClick", "option", "position"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import PropTypes from 'prop-types';
import React, { useCallback, useEffect, useRef } from 'react';
import scrollIntoView from 'scroll-into-view-if-needed';
import { useTypeaheadContext } from '../core/Context';
import { getDisplayName, getMenuItemId, preventInputBlur, warn } from '../utils';
import { optionType } from '../propTypes';
var propTypes = {
option: optionType.isRequired,
position: PropTypes.number
};
export function useItem(_ref) {
var label = _ref.label,
onClick = _ref.onClick,
option = _ref.option,
position = _ref.position,
props = _objectWithoutProperties(_ref, _excluded);
var _useTypeaheadContext = useTypeaheadContext(),
activeIndex = _useTypeaheadContext.activeIndex,
id = _useTypeaheadContext.id,
isOnlyResult = _useTypeaheadContext.isOnlyResult,
onActiveItemChange = _useTypeaheadContext.onActiveItemChange,
onInitialItemChange = _useTypeaheadContext.onInitialItemChange,
onMenuItemClick = _useTypeaheadContext.onMenuItemClick,
setItem = _useTypeaheadContext.setItem;
var itemRef = useRef(null);
useEffect(function () {
if (position === 0) {
onInitialItemChange(option);
}
});
useEffect(function () {
if (position === activeIndex) {
onActiveItemChange(option);
// Automatically scroll the menu as the user keys through it.
var node = itemRef.current;
node && scrollIntoView(node, {
boundary: node.parentNode,
scrollMode: 'if-needed'
});
}
}, [activeIndex, onActiveItemChange, option, position]);
var handleClick = useCallback(function (e) {
onMenuItemClick(option, e);
onClick && onClick(e);
}, [onClick, onMenuItemClick, option]);
var active = isOnlyResult || activeIndex === position;
// Update the item's position in the item stack.
setItem(option, position);
return _objectSpread(_objectSpread({}, props), {}, {
active: active,
'aria-label': label,
'aria-selected': active,
id: getMenuItemId(id, position),
onClick: handleClick,
onMouseDown: preventInputBlur,
ref: itemRef,
role: 'option'
});
}
/* istanbul ignore next */
export function withItem(Component) {
warn(false, 'Warning: `withItem` is deprecated and will be removed in the next ' + 'major version. Use `useItem` instead.');
var WrappedMenuItem = function WrappedMenuItem(props) {
return /*#__PURE__*/React.createElement(Component, _extends({}, props, useItem(props)));
};
WrappedMenuItem.displayName = "withItem(".concat(getDisplayName(Component), ")");
WrappedMenuItem.propTypes = propTypes;
return WrappedMenuItem;
}