@trail-ui/react
Version:
155 lines (152 loc) • 5.5 kB
JavaScript
import {
customToast
} from "./chunk-W6QAAZ3M.mjs";
import {
useFocusHandler
} from "./chunk-F5W73ZFA.mjs";
import {
useTableContext
} from "./chunk-A4IWBDSQ.mjs";
import {
areArraysSame
} from "./chunk-KFZT7QCH.mjs";
import {
replaceSpacesWithHyphens
} from "./chunk-4CU75PXA.mjs";
// src/editable-table/editable-components/multiselect.tsx
import { useEffect, useRef, useState } from "react";
import Select from "react-select";
import { commonColors } from "@trail-ui/theme";
import { jsx, jsxs } from "react/jsx-runtime";
function EditableMultiSelect({ cell, onCancel }) {
const [value, setValue] = useState([]);
const [initialValue, setInitialValue] = useState([]);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const selectRef = useRef(null);
const { updateData, tableRef, tableName, doesRowHeaderExist } = useTableContext(cell);
const { isCurrentCellFocused } = useFocusHandler({
cellType: "dataCell" /* dataCell */,
columnIndex: cell.column.getIndex(),
groupId: null,
rowId: cell.row.id,
rowIndex: cell.row.index
});
const metaData = cell.column.columnDef.meta;
const customStyles = {
control: (base, state) => ({
...base,
borderColor: state.isFocused ? "#5928ED" : "#ccc",
boxShadow: state.isFocused ? "0 0 0 1px #5928ED" : "none",
"&:hover": {
borderColor: "#5928ED"
}
}),
option: (base, state) => ({
...base,
cursor: "pointer",
backgroundColor: state.isSelected ? "#5928ED" : state.isFocused ? commonColors.purple[100] : "white",
color: state.isSelected ? "white" : "#000",
":active": {
backgroundColor: "#5928ED66"
}
})
};
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" && !isMenuOpen) {
cancelAndExit();
e.preventDefault();
e.stopPropagation();
}
}
useEffect(() => {
var _a, _b;
setInitialValue(cell.getValue());
setValue(cell.getValue());
(_a = selectRef.current) == null ? void 0 : _a.focus();
const inputElement = (_b = selectRef.current) == null ? void 0 : _b.inputRef;
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]);
useEffect(() => {
function saveData(e) {
var _a, _b, _c, _d, _e, _f;
if (!((_b = (_a = selectRef.current) == null ? void 0 : _a.menuListRef) == null ? void 0 : _b.contains(e.target)) && !((_d = (_c = selectRef.current) == null ? void 0 : _c.inputRef) == null ? void 0 : _d.contains(e.target)) && !((_f = (_e = selectRef.current) == null ? void 0 : _e.controlRef) == null ? void 0 : _f.contains(e.target))) {
if (areArraysSame(initialValue, value)) {
cancelAndExit();
} else {
saveAndExit();
}
}
}
document.addEventListener("mousedown", saveData);
return () => document.removeEventListener("mousedown", saveData);
}, [initialValue, value]);
return /* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx("p", { role: "alert", className: "sr-only", "aria-live": "polite", children: "Use Up and Down arrow keys to navigate through the options, press Space to select the currently focused option, press delete/backspace to deselect an option, press Escape to close the multiselect dropdown or exit the editing mode, press Enter to save the selected option and exit the editing mode." }),
/* @__PURE__ */ jsx(
Select,
{
ref: selectRef,
...metaData.label ? { label: metaData.label(cell.row.original) } : {
"aria-labelledby": `${doesRowHeaderExist ? cell.row.id : ""} ${replaceSpacesWithHyphens(tableName)}-${cell.column.getIndex()}`
},
placeholder: metaData.placeholder,
styles: {
...customStyles,
...metaData.customStyles || {}
},
className: `max-w-[${cell.column.columnDef.size}px] w-full shadow-red-500 focus:outline-purple-700 focus:[outline-width:1px]`,
isMulti: true,
isSearchable: false,
isClearable: false,
closeMenuOnSelect: false,
tabSelectsValue: false,
menuPosition: "fixed",
defaultValue: { label: "", value: "" },
value: metaData.options.filter((opt) => value.includes(opt.value)),
onChange: (selectedOptions) => {
setValue(selectedOptions.map((opt) => opt.value));
},
onKeyDown,
options: metaData.options,
onMenuClose: () => setIsMenuOpen(false),
onMenuOpen: () => setIsMenuOpen(true)
}
)
] });
}
export {
EditableMultiSelect
};