@trail-ui/react
Version:
126 lines (123 loc) • 3.91 kB
JavaScript
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
};