@trail-ui/react
Version:
113 lines (110 loc) • 3.9 kB
JavaScript
import {
customToast
} from "./chunk-VRBQ3HMS.mjs";
import {
useFocusHandler
} from "./chunk-SSX6C2M6.mjs";
import {
useTableContext
} from "./chunk-LRSSE262.mjs";
// src/editable-table/editable-components/select.tsx
import { ChevronDownIcon } from "@trail-ui/icons";
import { useEffect, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
var placeholderValue = "editable-select-placeholder-value";
function EditableSelect(props) {
const [initialValue, setInitialValue] = useState("");
const [newValue, setNewValue] = useState("");
const selectRef = useRef(null);
const { updateData } = useTableContext(props.cell);
const { focusCurrentCell, isCurrentCellFocused, tableRef } = useFocusHandler(props.cell, false);
const label = props.cell.column.columnDef.header;
const metaData = props.cell.column.columnDef.meta;
const onBlur = (e) => {
var _a;
if (newValue === initialValue) {
cancelAndExit();
} else {
const relatedTarget = e.relatedTarget;
const isMovingWithinTable = relatedTarget && ((_a = selectRef.current) == null ? void 0 : _a.contains(relatedTarget));
if (!isMovingWithinTable) {
saveAndExit();
}
}
};
const cancelAndExit = () => {
setNewValue(props.cell.getValue());
requestAnimationFrame(() => {
props.onCancel();
});
};
const saveAndExit = () => {
const isEmpty = newValue.toString().trim().length == 0;
if (isEmpty) {
customToast("Value cannot be empty", "error");
cancelAndExit();
return;
}
if (newValue !== initialValue) {
updateData(newValue);
}
requestAnimationFrame(() => {
props.onCancel();
});
};
useEffect(() => {
var _a;
(_a = selectRef.current) == null ? void 0 : _a.focus();
setInitialValue(props.cell.getValue());
setNewValue(props.cell.getValue());
}, []);
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", { className: "relative w-full", children: [
/* @__PURE__ */ jsxs(
"select",
{
"aria-label": `${label}`,
className: "h-10 w-fit min-w-full max-w-full cursor-pointer appearance-none rounded border border-neutral-300 bg-neutral-50 p-2 pr-10 text-sm font-medium text-neutral-900 outline-none -outline-offset-1 hover:outline-neutral-600 focus:outline-purple-600",
ref: selectRef,
value: newValue != null ? newValue : placeholderValue,
onChange: (e) => setNewValue(e.target.value),
onBlur,
onKeyDown: (e) => {
if (e.key === "Enter") {
if ((newValue == null ? void 0 : newValue.toString()) === placeholderValue) {
cancelAndExit();
return;
}
saveAndExit();
} else if (e.key === "Escape") {
cancelAndExit();
e.preventDefault();
e.stopPropagation();
} else if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(e.key)) {
e.stopPropagation();
}
},
onFocus: focusCurrentCell,
children: [
/* @__PURE__ */ jsx("option", { value: placeholderValue, children: metaData.placeholder }),
metaData.options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
]
}
),
/* @__PURE__ */ jsx(
"div",
{
style: { top: "0px", bottom: "0px" },
className: "pointer-events-none absolute right-0 flex items-center px-2",
children: /* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-6 w-6 text-neutral-800" })
}
)
] });
}
export {
EditableSelect
};