@findify/react-components
Version:
Findify react UI components
81 lines (66 loc) • 2.21 kB
text/typescript
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 });
};
};