@grandlinex/react-components
Version:
181 lines (180 loc) • 7.86 kB
JavaScript
"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))))))));
}