UNPKG

react-bootstrap-typeahead

Version:
56 lines (55 loc) 2.12 kB
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'; const propTypes = { option: optionType.isRequired, position: PropTypes.number, }; export function useItem({ label, onClick, option, position, ...props }) { const { activeIndex, id, isOnlyResult, onActiveItemChange, onInitialItemChange, onMenuItemClick, setItem, } = useTypeaheadContext(); const itemRef = useRef(null); useEffect(() => { if (position === 0) { onInitialItemChange(option); } }); useEffect(() => { if (position === activeIndex) { onActiveItemChange(option); const node = itemRef.current; node && scrollIntoView(node, { boundary: node.parentNode, scrollMode: 'if-needed', }); } }, [activeIndex, onActiveItemChange, option, position]); const handleClick = useCallback((e) => { onMenuItemClick(option, e); onClick && onClick(e); }, [onClick, onMenuItemClick, option]); const active = isOnlyResult || activeIndex === position; setItem(option, position); return { ...props, active, 'aria-label': label, 'aria-selected': active, id: getMenuItemId(id, position), onClick: handleClick, onMouseDown: preventInputBlur, ref: itemRef, role: 'option', }; } export function withItem(Component) { warn(false, 'Warning: `withItem` is deprecated and will be removed in the next ' + 'major version. Use `useItem` instead.'); const WrappedMenuItem = (props) => (React.createElement(Component, { ...props, ...useItem(props) })); WrappedMenuItem.displayName = `withItem(${getDisplayName(Component)})`; WrappedMenuItem.propTypes = propTypes; return WrappedMenuItem; }