UNPKG

leo-design-ui

Version:

React Design Library

119 lines (118 loc) 5.25 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import classNames from "classnames"; import { useEffect, useRef, useState } from "react"; import Input from "../Input/input"; import Icon from "../Icon/icon"; import useDebounce from "../../hooks/useDebounce"; import useClickOutside from "../../hooks/useClickOutside"; import Transition from "../Transition/transition"; var AutoComplete = function (_a) { var value = _a.value, onSelect = _a.onSelect, onChange = _a.onChange, renderOption = _a.renderOption, fetchSuggestions = _a.fetchSuggestions, restProps = __rest(_a, ["value", "onSelect", "onChange", "renderOption", "fetchSuggestions"]); var classes = classNames('leo-auto-complete'); var _b = useState(value), iptValue = _b[0], setIptValue = _b[1]; var _c = useState([]), suggestions = _c[0], setSuggestions = _c[1]; var _d = useState(false), loading = _d[0], setLoading = _d[1]; var debouncedValue = useDebounce(iptValue, 500); var _e = useState(false), showDropdown = _e[0], setShowDropdown = _e[1]; var _f = useState(-1), highLight = _f[0], setHighLight = _f[1]; var triggerSearch = useRef(false); var componentRef = useRef(null); useClickOutside(componentRef, function () { return setSuggestions([]); }); useEffect(function () { if (debouncedValue && triggerSearch.current) { var results = fetchSuggestions(debouncedValue); if (results instanceof Promise) { setLoading(true); results.then(function (data) { setSuggestions(data); setLoading(false); if (data.length > 0) { setShowDropdown(true); } }); } else { setSuggestions(results); if (results.length > 0) { setShowDropdown(true); } } } else { setShowDropdown(false); } }, [debouncedValue]); var handlerChange = function (e) { triggerSearch.current = true; var value = e.target.value; setIptValue(value); }; // 选中 var handlerSelect = function (item) { triggerSearch.current = false; setIptValue(item.value); setShowDropdown(false); if (onSelect) { onSelect(item); } }; // 自定义模板 var renderTemplate = function (item) { return renderOption ? renderOption(item) : item.value; }; // 键盘事件 var handleKeyDown = function (e) { switch (e.key) { case 'Enter': if (suggestions[highLight]) { handlerSelect(suggestions[highLight]); } break; case 'ArrowUp': highLight > 0 && setHighLight(highLight - 1); break; case 'ArrowDown': highLight < suggestions.length - 1 && setHighLight(highLight + 1); break; case 'Escape': setShowDropdown(false); break; default: break; } }; // 下拉框 var generateDropdown = function () { return (_jsx(_Fragment, { children: _jsx(Transition, { in: showDropdown || loading, animation: "zoom-in-top", timeout: 300, onExited: function () { setSuggestions([]); }, children: _jsxs("ul", { className: "leo-suggestion-list", children: [loading && _jsx("div", { className: "suggstions-loading-icon", children: _jsx(Icon, { icon: "spinner", spin: true }) }), suggestions.map(function (item, index) { var clasees = classNames('suggestion-item', { 'is-active': index === highLight }); return (_jsx("li", { className: clasees, onClick: function () { return handlerSelect(item); }, children: renderTemplate(item) }, index)); })] }) }) })); }; return (_jsxs("div", { className: classes, style: { width: 300 }, ref: componentRef, children: [_jsx(Input, __assign({ value: iptValue, onChange: handlerChange, onKeyDown: handleKeyDown }, restProps)), generateDropdown()] })); }; export default AutoComplete;