lingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
50 lines • 2.54 kB
JavaScript
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "preact/jsx-runtime";
import { useSignal } from "@preact/signals";
import { useLayoutEffect, useState } from "preact/compat";
import useLatest from "../hooks/useLatest";
import MenuButton from "./MenuButton";
import TextInput from "./TextInput";
const TextOptionsInput = ({ style, className, placeholder, autoFocus, onEnter, onEscape, options }) => {
const optionsRef = useLatest(options);
const textSignal = useSignal("");
const [includeKeys, setIncludeKeys] = useState();
const filteredOptions = includeKeys ?? options;
const [selected, setSelected] = useState("");
useLayoutEffect(() => {
const options = optionsRef.current;
if (!options)
return;
if (!textSignal.value) {
setIncludeKeys(undefined);
return;
}
setIncludeKeys(options.filter((key) => key.toLowerCase().includes(textSignal.value.toLowerCase())));
}, [textSignal.value]);
useLayoutEffect(() => {
if (!optionsRef.current || !filteredOptions || !textSignal.value)
return;
setSelected(filteredOptions[0]);
return () => {
setSelected("");
};
}, [textSignal.value, filteredOptions]);
return (_jsx(TextInput, { style: style, className: className, placeholder: placeholder, autoFocus: autoFocus, onEnter: (val) => {
if (!options) {
onEnter?.(val);
return;
}
selected && onEnter?.(selected);
}, onEscape: onEscape, onArrowDown: () => {
if (!filteredOptions)
return;
const index = filteredOptions.indexOf(selected) + 1;
setSelected(filteredOptions[index >= filteredOptions.length ? 0 : index]);
}, onArrowUp: () => {
if (!filteredOptions)
return;
const index = filteredOptions.indexOf(selected) - 1;
setSelected(filteredOptions[index < 0 ? filteredOptions.length - 1 : index]);
}, textSignal: textSignal, inputPadding: options ? 20 : undefined, children: !!filteredOptions?.length && (_jsxs(_Fragment, { children: [_jsx("div", { style: { height: 10 } }), _jsx("div", { style: { width: "100%" }, children: filteredOptions.map((option) => (_jsx(MenuButton, { onClick: () => onEnter?.(option), highlight: selected === option, children: option }, option))) })] })) }));
};
export default TextOptionsInput;
//# sourceMappingURL=TextOptionsInput.js.map