UNPKG

@grandlinex/react-components

Version:
181 lines (180 loc) 7.86 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SpotlightModal = SpotlightModal; const react_1 = __importStar(require("react")); const react_icons_1 = require("@grandlinex/react-icons"); const components_1 = require("../../../components"); const util_1 = require("../../../util"); const cmd = (a, space = false) => { return `/${a.commandTag}${space ? ' ' : ''}`; }; function SpotlightModal({ closeFcn, action, defaultSearch, hint, }) { const ui = (0, util_1.useUIContext)(); const [search, setSearch] = (0, react_1.useState)(''); const [command, setCommand] = (0, react_1.useState)(null); const ref = (0, react_1.createRef)(); const refScroll = (0, react_1.createRef)(); const refCur = (0, react_1.createRef)(); const [keyNavigation, setKeyNavigation] = (0, react_1.useState)(-1); let res = []; let emptyRes = null; const defErr = (0, react_1.useMemo)(() => { return [ [ { key: 'err01', optionAction: null, text: ui.translation.get('glx.spotlight.empty.commands'), }, ], [ { key: 'err02', optionAction: null, text: ui.translation.get('glx.spotlight.empty.result'), }, ], ]; }, [ui.translation]); if (search.startsWith('/')) { if (!action) { [res] = defErr; } else { const sel = action.filter((a) => { return cmd(a).startsWith(search) || search.startsWith(cmd(a)); }); if (sel.length === 0) { [res] = defErr; } else if (sel.length === 1 && search.startsWith(cmd(sel[0], true))) { if (!command) { setCommand(sel[0]); } res = sel[0].action(search.split(' '), setSearch, setCommand, closeFcn) || defErr[0]; } else { if (command) { setCommand(null); } for (const cur of sel) { res.push({ key: cur.commandTag, optionAction: () => { setCommand(cur); setSearch(cmd(cur, true)); }, text: `/${cur.commandTag} - ${cur.name}`, icon: cur.icon, }); } } } } else if (search.length > 2) { if (defaultSearch) { res = defaultSearch(search, setSearch, setCommand, closeFcn) || defErr[1]; } else { [, emptyRes] = defErr; } } else if (search === '' && command) { setCommand(null); } function keyListener(e) { if (e.key === 'Escape') { setSearch(''); closeFcn(); } else if (e.key === 'Enter') { if (keyNavigation >= 0 && keyNavigation < res.length) { res[keyNavigation].optionAction?.(); setKeyNavigation(-1); ref.current?.focus(); } else if (res.length > 0) { res[0].optionAction?.(); } } else if (e.key === 'ArrowDown') { e.preventDefault(); if (keyNavigation < res.length - 1) { if (keyNavigation === -1) { ref.current?.blur(); } refScroll.current?.scrollTo({ top: 62 * keyNavigation, }); setKeyNavigation(keyNavigation + 1); } } else if (e.key === 'ArrowUp') { e.preventDefault(); if (keyNavigation >= 0) { if (keyNavigation === 0) { ref.current?.focus(); } refScroll.current?.scrollTo({ top: 62 * (keyNavigation - 1), }); setKeyNavigation(keyNavigation - 1); } } } (0, react_1.useEffect)(() => { document.addEventListener('keydown', keyListener); return () => { document.removeEventListener('keydown', keyListener); }; }); return (react_1.default.createElement(components_1.Grid, { className: "tab-layout--spotlight glx-animation-fade-in-super-fast", flex: true, gap: 12, flexC: true, vCenter: true }, react_1.default.createElement("div", { className: "tab-layout--spotlight-offset" }), react_1.default.createElement(components_1.Grid, { className: "tab-layout--spotlight-input", flex: true, flexRow: true, vCenter: true }, command ? (react_1.default.createElement(components_1.Grid, { className: "option-icon" }, command.icon ? (0, react_icons_1.getIcon)(command.icon)({ size: react_icons_1.ISize.SM }) : null)) : null, react_1.default.createElement(components_1.Grid, { grow: 1 }, react_1.default.createElement("input", { ref: ref, type: "text", autoFocus: true, spellCheck: false, placeholder: ui.translation.get('glx.spotlight.placeholder'), onChange: (e) => { setSearch(e.target.value); }, onFocus: () => { setKeyNavigation(-1); }, value: search }))), react_1.default.createElement(components_1.Grid, null), (emptyRes || res).length === 0 && hint, react_1.default.createElement(components_1.Grid, { divRef: refScroll, className: "tab-layout--spotlight-option glx-no-scroll" }, (emptyRes || res).map(({ icon, optionAction, text, key, path, component }, index) => (react_1.default.createElement(components_1.Grid, { key: key, divRef: index === keyNavigation ? refCur : undefined, className: [ [ optionAction === null, 'option-element--no-action', 'option-element', ], [index === keyNavigation, 'option-element-active'], ], flex: true, flexRow: true, vCenter: true, gap: 8, onClick: optionAction || undefined }, react_1.default.createElement(components_1.Grid, { className: "option-icon" }, icon ? (0, react_icons_1.getIcon)(icon)({ size: react_icons_1.ISize.SM }) : null), react_1.default.createElement(components_1.Grid, { flex: true, flexC: true }, path ? (react_1.default.createElement("div", { className: "option-path" }, path.join(' > '))) : null, react_1.default.createElement("div", null, component || text)))))))); }