UNPKG

@trail-ui/react

Version:
126 lines (123 loc) 3.91 kB
import { customToast } from "./chunk-VRBQ3HMS.mjs"; import { useFocusHandler } from "./chunk-SSX6C2M6.mjs"; import { useTableContext } from "./chunk-LRSSE262.mjs"; import { areArraysSame } from "./chunk-KFZT7QCH.mjs"; // src/editable-table/editable-components/multiselect.tsx import { useEffect, useRef, useState } from "react"; import Select from "react-select"; import { jsx, jsxs } from "react/jsx-runtime"; function EditableMultiSelect({ cell, onCancel }) { const [open, setOpen] = useState(false); const [value, setValue] = useState([]); const [initialValue, setInitialValue] = useState( [] ); const selectRef = useRef(null); const { updateData } = useTableContext(cell); const { isCurrentCellFocused, focusCurrentCell, tableRef } = useFocusHandler(cell, false); const metaData = cell.column.columnDef.meta; const cancelAndExit = () => { setValue(cell.getValue()); requestAnimationFrame(() => { onCancel(); }); }; const saveAndExit = () => { const isEmpty = !areArraysSame(value, initialValue) && value.length === 0; if (isEmpty) { customToast("Value cannot be empty", "error"); cancelAndExit(); return; } if (!areArraysSame(value, initialValue)) { updateData(value); } requestAnimationFrame(() => { onCancel(); }); }; function onKeyDown(e) { if (e.key === "Enter") { e.preventDefault(); saveAndExit(); } else if (e.key === "Escape") { cancelAndExit(); e.preventDefault(); e.stopPropagation(); } else if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(e.key)) { e.stopPropagation(); } } const onBlur = (e) => { if (!areArraysSame(value, initialValue)) { cancelAndExit(); } else { saveAndExit(); } }; useEffect(() => { var _a; setInitialValue(cell.getValue()); setValue(cell.getValue()); (_a = selectRef.current) == null ? void 0 : _a.focus(); const inputElement = document.querySelector("#multi-input input"); if (inputElement) { inputElement.removeAttribute("aria-readonly"); inputElement.removeAttribute("aria-autocomplete"); inputElement.setAttribute("aria-haspopup", "listbox"); } }, []); useEffect(() => { var _a, _b; if (isCurrentCellFocused && ((_a = tableRef.current) == null ? void 0 : _a.contains(document.activeElement))) (_b = selectRef.current) == null ? void 0 : _b.focus(); }, [isCurrentCellFocused]); return /* @__PURE__ */ jsxs("div", { children: [ open && /* @__PURE__ */ jsx("p", { role: "alert", className: "sr-only", "aria-live": "polite", children: "Use Up and Down arrow keys to choose options, press Enter/Space to select the currently focused option, press Escape to exit the multiselect and the editing mode, press Tab to save the selected option to exit the editing mode." }), /* @__PURE__ */ jsx( Select, { id: "multi-input", ref: selectRef, "aria-label": metaData.label, placeholder: metaData.placeholder, styles: metaData.customStyles, className: `max-w-[${cell.column.columnDef.size}px] w-full shadow-red-500`, isMulti: true, isSearchable: false, isClearable: false, closeMenuOnSelect: false, tabSelectsValue: false, menuPosition: "fixed", defaultValue: { label: "", value: "" }, value: metaData.options.filter((opt) => value.includes(opt.value)), onMenuOpen: () => setOpen(true), onMenuClose: () => { setOpen(false); updateData(value); }, onChange: (selectedOptions) => { setValue(selectedOptions.map((opt) => opt.value)); }, onBlur, onKeyDown, onFocus: focusCurrentCell, options: metaData.options } ) ] }); } export { EditableMultiSelect };