UNPKG

instantsearch-ui-components

Version:

Common UI components for InstantSearch.

248 lines (247 loc) 8.67 kB
import _typeof from "@babel/runtime/helpers/typeof"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; export function createAutocompletePropGetters(_ref) { var useEffect = _ref.useEffect, useId = _ref.useId, useMemo = _ref.useMemo, useRef = _ref.useRef, useState = _ref.useState; return function usePropGetters(_ref2) { var indices = _ref2.indices, indicesConfig = _ref2.indicesConfig, onRefine = _ref2.onRefine, globalOnSelect = _ref2.onSelect, _onApply = _ref2.onApply, placeholder = _ref2.placeholder; var getElementId = createGetElementId(useId()); var inputRef = useRef(null); var rootRef = useRef(null); var _useState = useState(false), _useState2 = _slicedToArray(_useState, 2), isOpen = _useState2[0], setIsOpen = _useState2[1]; var _useState3 = useState(undefined), _useState4 = _slicedToArray(_useState3, 2), activeDescendant = _useState4[0], setActiveDescendant = _useState4[1]; var _useMemo = useMemo(function () { return buildItems({ indices: indices, indicesConfig: indicesConfig, getElementId: getElementId }); }, [indices, indicesConfig, getElementId]), items = _useMemo.items, itemsIds = _useMemo.itemsIds; useEffect(function () { var onBodyClick = function onBodyClick(event) { var _unwrapRef; if ((_unwrapRef = unwrapRef(rootRef)) !== null && _unwrapRef !== void 0 && _unwrapRef.contains(event.target)) { return; } setIsOpen(false); }; document.body.addEventListener('click', onBodyClick); return function () { document.body.removeEventListener('click', onBodyClick); }; }, [rootRef]); var getNextActiveDescendant = function getNextActiveDescendant(key) { switch (key) { case 'ArrowLeft': case 'ArrowUp': { var prevIndex = itemsIds.indexOf(activeDescendant || '') - 1; return itemsIds[prevIndex] || itemsIds[itemsIds.length - 1]; } case 'ArrowRight': case 'ArrowDown': { var nextIndex = itemsIds.indexOf(activeDescendant || '') + 1; return itemsIds[nextIndex] || itemsIds[0]; } default: return undefined; } }; var submit = function submit() { var _override$activeDesce; var override = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (isOpen) { setIsOpen(false); } else { var _inputRef$current; (_inputRef$current = inputRef.current) === null || _inputRef$current === void 0 ? void 0 : _inputRef$current.blur(); } var actualDescendant = (_override$activeDesce = override.activeDescendant) !== null && _override$activeDesce !== void 0 ? _override$activeDesce : activeDescendant; if (!actualDescendant && override.query) { onRefine(override.query); } if (actualDescendant && items.has(actualDescendant)) { var _getQuery; var _ref3 = items.get(actualDescendant), _item = _ref3.item, _ref3$config = _ref3.config, indexOnSelect = _ref3$config.onSelect, getQuery = _ref3$config.getQuery, getURL = _ref3$config.getURL; var actualOnSelect = indexOnSelect !== null && indexOnSelect !== void 0 ? indexOnSelect : globalOnSelect; actualOnSelect({ item: _item, query: (_getQuery = getQuery === null || getQuery === void 0 ? void 0 : getQuery(_item)) !== null && _getQuery !== void 0 ? _getQuery : '', url: getURL === null || getURL === void 0 ? void 0 : getURL(_item), setQuery: function setQuery(query) { return onRefine(query); } }); setActiveDescendant(undefined); } }; return { getInputProps: function getInputProps() { return { id: getElementId('input'), ref: inputRef, role: 'combobox', 'aria-autocomplete': 'list', 'aria-expanded': isOpen, 'aria-haspopup': 'grid', 'aria-controls': getElementId('panel'), 'aria-activedescendant': activeDescendant, placeholder: placeholder, onFocus: function onFocus() { return setIsOpen(true); }, onKeyDown: function onKeyDown(event) { switch (event.key) { case 'Escape': { if (isOpen) { setIsOpen(false); event.preventDefault(); } else { setActiveDescendant(undefined); } break; } case 'ArrowLeft': case 'ArrowUp': case 'ArrowRight': case 'ArrowDown': { var _document$getElementB; setIsOpen(true); var nextActiveDescendant = getNextActiveDescendant(event.key); setActiveDescendant(nextActiveDescendant); (_document$getElementB = document.getElementById(nextActiveDescendant)) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.scrollIntoView(false); event.preventDefault(); break; } case 'Enter': { submit({ query: event.target.value }); break; } case 'Tab': setIsOpen(false); break; default: setIsOpen(true); return; } }, onKeyUp: function onKeyUp(event) { switch (event.key) { case 'ArrowLeft': case 'ArrowUp': case 'ArrowRight': case 'ArrowDown': case 'Escape': case 'Return': event.preventDefault(); return; default: setActiveDescendant(undefined); break; } } }; }, getItemProps: function getItemProps(item, index) { var id = getElementId('item', item.__indexName, index); return { id: id, role: 'row', 'aria-selected': id === activeDescendant, onSelect: function onSelect() { return submit({ activeDescendant: id }); }, onApply: function onApply() { var _getQuery2; var _ref4 = items.get(id), currentItem = _ref4.item, getQuery = _ref4.config.getQuery; _onApply((_getQuery2 = getQuery === null || getQuery === void 0 ? void 0 : getQuery(currentItem)) !== null && _getQuery2 !== void 0 ? _getQuery2 : ''); } }; }, getPanelProps: function getPanelProps() { return { hidden: !isOpen, id: getElementId('panel'), role: 'grid', 'aria-labelledby': getElementId('input') }; }, getRootProps: function getRootProps() { return { ref: rootRef }; } }; }; } function buildItems(_ref5) { var indices = _ref5.indices, indicesConfig = _ref5.indicesConfig, getElementId = _ref5.getElementId; var itemsIds = []; var items = new Map(); for (var i = 0; i < indicesConfig.length; i++) { var _indices$i; var config = indicesConfig[i]; var hits = ((_indices$i = indices[i]) === null || _indices$i === void 0 ? void 0 : _indices$i.hits) || []; for (var position = 0; position < hits.length; position++) { var itemId = getElementId('item', config.indexName, position); items.set(itemId, { item: hits[position], config: config }); itemsIds.push(itemId); } } return { items: items, itemsIds: itemsIds }; } function createGetElementId(autocompleteId) { return function getElementId() { var prefix = 'autocomplete'; for (var _len = arguments.length, suffixes = new Array(_len), _key = 0; _key < _len; _key++) { suffixes[_key] = arguments[_key]; } return "".concat(prefix).concat(autocompleteId).concat(suffixes.join(':')); }; } /** * Returns the framework-agnostic value of a ref. */ function unwrapRef(ref) { return ref.current && _typeof(ref.current) === 'object' && 'base' in ref.current ? ref.current.base // Preact : ref.current; // React }