UNPKG

@findify/react-components

Version:
81 lines (66 loc) 2.21 kB
import { useCallback, useEffect, createFactory, useMemo, useState, useReducer, } from 'react'; import { useSuggestions } from '@findify/react-connect'; const arrowCodes = ['ArrowUp', 'ArrowDown']; export const useAutocompleteLogic = () => { const { suggestions, getSuggestionProps, config, meta } = useSuggestions(); const node: HTMLInputElement = config.get('node'); const reduceIndex = (state, e) => { if (!!e && !e.key) return e; if (e.key === 'Enter' && state !== -1) { if (e.defaultPrevented) return; e.stopPropagation(); e.preventDefault(); getSuggestionProps(state, config.get('widgetKey')).onClick(); return state; } if (!arrowCodes.includes(e.key)) return state; e.preventDefault(); const newSuggestionIndex = state + (e.key === 'ArrowUp' ? -1 : 1); const totalSuggestions = (suggestions && suggestions.size) || 0; if (newSuggestionIndex < 0) return totalSuggestions - 1; if (totalSuggestions - 1 < newSuggestionIndex) return 0; return newSuggestionIndex; }; const [selectedSuggestion, setSuggestionIndex] = useReducer(reduceIndex, -1); const closeAutocomplete = useCallback( () => (window as any).findify.emit( 'autocompleteFocusLost', config.get('widgetKey') ), [config.get('widgetKey')] ); useEffect(() => { // node.autocomplete = 'off'; // const handleButtonClick = (e) => { // if (e.target !== node) return; // if (e.key === 'Escape') return closeAutocomplete(); // setSuggestionIndex(e); // }; // document // .querySelector('body')! // .addEventListener('keydown', handleButtonClick, true); // return () => // document // .querySelector('body')! // .removeEventListener('keydown', handleButtonClick, true); }, []); useEffect(() => setSuggestionIndex(-1), [meta.get('q')]); return useMemo(() => ({ selectedSuggestion, closeAutocomplete }), [ selectedSuggestion, ]); }; export default (BaseComponent) => { const factory = createFactory(BaseComponent); return (props) => { const logic = useAutocompleteLogic(); return factory({ ...props, ...logic }); }; };