seti-ramesesv1
Version:
Reusable components and context for Next.js apps
54 lines (51 loc) • 3.48 kB
JavaScript
import { jsxs, jsx } from 'react/jsx-runtime';
import React__default, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
import '../../ui/Button/Button.module.css.js';
import '../../../styles/Checkbox.module.css.js';
import '../../../styles/Text.module.css.js';
import '../../../styles/Modal.module.css.js';
import '../../../styles/Panel.module.css.js';
import '../../../styles/Radio.module.css.js';
import '../RadioGroup.js';
import '../../ui/Select/Select.module.css.js';
import Tooltip from '../../ui/Tooltip.js';
import Columns2 from '../../../node_modules/lucide-react/dist/esm/icons/columns-2.js';
const ColumnMenu = ({ columns, visibleCols, setVisibleCols }) => {
const [open, setOpen] = useState(false);
const [menuPos, setMenuPos] = useState({ top: 0, left: 0 });
const [mounted, setMounted] = useState(false);
const btnRef = React__default.useRef(null);
useEffect(() => setMounted(true), []);
useEffect(() => {
const handleClickOutside = (e) => {
if (!e.target.closest(".column-menu-wrapper"))
setOpen(false);
};
document.addEventListener("click", handleClickOutside);
return () => document.removeEventListener("click", handleClickOutside);
}, []);
const toggleMenu = (e) => {
e.stopPropagation();
const rect = e.currentTarget.getBoundingClientRect();
setMenuPos({ top: rect.bottom + window.scrollY + 4, left: rect.left });
setOpen((p) => !p);
};
const menuContent = (jsxs("div", { className: "absolute bg-white border border-gray-200 rounded-xl shadow-lg z-[9999] w-52 p-2", style: { top: menuPos.top, left: menuPos.left }, onClick: (e) => e.stopPropagation(), children: [jsx("p", { className: "text-xs font-semibold text-gray-500 px-2 pb-2 border-b border-gray-100", children: "Columns" }), jsx("div", { className: "max-h-60 overflow-y-auto mt-1", children: columns
.filter((col) => col.visible !== false)
.map((col) => (jsxs("label", { className: "flex items-center px-2 py-1 text-sm text-gray-700 hover:bg-gray-50 rounded cursor-pointer", children: [jsx("input", { type: "checkbox", checked: visibleCols.some((c) => c.id === col.id), onChange: (e) => {
if (e.target.checked) {
setVisibleCols((prev) => {
const updated = [...prev, col];
// Sort by original columns order
return columns.filter((c) => updated.some((v) => v.id === c.id));
});
}
else {
setVisibleCols((prev) => prev.filter((c) => c.id !== col.id));
}
}, className: "mr-2 accent-blue-600" }), col.title ?? col.id] }, col.id))) })] }));
return (jsxs("div", { className: "relative column-menu-wrapper", children: [jsx(Tooltip, { content: "Show/Hide Columns", position: "top", children: jsx("button", { ref: btnRef, type: "button", className: `hover:bg-gray-100 transition ${open ? "bg-gray-100" : "bg-white"}`, onClick: toggleMenu, children: jsx(Columns2, { size: 17 }) }) }), mounted && open && ReactDOM.createPortal(menuContent, document.body)] }));
};
export { ColumnMenu as default };
//# sourceMappingURL=ColumnMenu.js.map