UNPKG

shelving

Version:

Toolkit for using data in JavaScript.

38 lines (37 loc) 2.03 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; import { useInstance } from "../../react/useInstance.js"; import { useStore } from "../../react/useStore.js"; import { PayloadFetchStore } from "../../store/PayloadFetchStore.js"; import { NONE, SECOND } from "../../util/constants.js"; import { formatValue } from "../../util/format.js"; import { ErrorNotice } from "../misc/Catcher.js"; import { LOADING_NOTICE, Notice } from "../notice/Notice.js"; import { ArrayRadioInputs } from "./ArrayRadioInputs.js"; import { Popover } from "./Popover.js"; import { SchemaInput } from "./SchemaInput.js"; /** * Combo box with query input. * - Show an input based on a `schema` of type `I` * - Values from the input are piped to an `onQuery()` callback. * - Show a `<Popover>` that has a radio list of items to allow a final option of type `O` to be picked. * - Errors / loading state / empty state are handled automatically. */ export function QueryInput({ empty = "No results", value, onValue, onQuery, formatter = formatValue, ...props }) { const store = useStore(useInstance(PayloadFetchStore, NONE, undefined, onQuery, SECOND)); const busy = useStore(store.busy).value; // Is popover open? const isOpen = busy || !!store.reason || !!store.value; const close = () => { store.payload.value = NONE; store.value = undefined; }; return (_jsxs(Popover, { open: isOpen, onClose: close, children: [_jsx(SchemaInput, { ...props, value: value, onValue: v => { if (v) store.payload.value = v; else close(); } }), busy ? (LOADING_NOTICE) : store.reason ? (_jsx(ErrorNotice, { reason: store.reason })) : store.value?.length ? (_jsx(ArrayRadioInputs, { items: store.value, onValue: v => { onValue(v); // Set the value. close(); }, formatter: formatter, ...props })) : empty ? (_jsx(Notice, { children: empty })) : null] })); }