Fix right-click column visibility context menu crash
Replace base-ui DropdownMenu (requires anchor trigger) with a custom positioned panel for the header right-click context menu. The base-ui Menu primitive cannot be rendered free-floating without a trigger element. Made-with: Cursor
This commit is contained in:
parent
7ff9724a63
commit
1168c96ae2
1 changed files with 30 additions and 32 deletions
|
|
@ -28,13 +28,7 @@ import {
|
||||||
TableHeader,
|
TableHeader,
|
||||||
TableRow,
|
TableRow,
|
||||||
} from "@/components/ui/table";
|
} from "@/components/ui/table";
|
||||||
import {
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuCheckboxItem,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuLabel,
|
|
||||||
DropdownMenuSeparator,
|
|
||||||
} from "@/components/ui/dropdown-menu";
|
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import type { ResponseCard } from "./columns";
|
import type { ResponseCard } from "./columns";
|
||||||
|
|
@ -120,6 +114,7 @@ export function DataTable<TData extends ResponseCard>({
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
|
const contextMenuRef = React.useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const table = useReactTable({
|
const table = useReactTable({
|
||||||
data,
|
data,
|
||||||
|
|
@ -185,7 +180,15 @@ export function DataTable<TData extends ResponseCard>({
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (!contextMenu) return;
|
if (!contextMenu) return;
|
||||||
const close = () => setContextMenu(null);
|
const close = (e: MouseEvent) => {
|
||||||
|
if (
|
||||||
|
contextMenuRef.current &&
|
||||||
|
contextMenuRef.current.contains(e.target as Node)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setContextMenu(null);
|
||||||
|
};
|
||||||
window.addEventListener("click", close);
|
window.addEventListener("click", close);
|
||||||
window.addEventListener("contextmenu", close);
|
window.addEventListener("contextmenu", close);
|
||||||
return () => {
|
return () => {
|
||||||
|
|
@ -463,35 +466,30 @@ export function DataTable<TData extends ResponseCard>({
|
||||||
|
|
||||||
{/* Right-click column visibility context menu */}
|
{/* Right-click column visibility context menu */}
|
||||||
{contextMenu && (
|
{contextMenu && (
|
||||||
<DropdownMenu
|
<div
|
||||||
open={true}
|
ref={contextMenuRef}
|
||||||
onOpenChange={(open) => {
|
style={{ left: contextMenu.x, top: contextMenu.y }}
|
||||||
if (!open) setContextMenu(null);
|
className="fixed z-50 min-w-[180px] rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 animate-in fade-in-0 zoom-in-95"
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<DropdownMenuContent
|
<div className="px-2 py-1.5 text-xs font-medium text-muted-foreground">
|
||||||
style={{
|
Toggle Columns
|
||||||
position: "fixed",
|
</div>
|
||||||
left: contextMenu.x,
|
<div className="my-1 h-px bg-border" />
|
||||||
top: contextMenu.y,
|
|
||||||
}}
|
|
||||||
className="w-48"
|
|
||||||
>
|
|
||||||
<DropdownMenuLabel>Toggle Columns</DropdownMenuLabel>
|
|
||||||
<DropdownMenuSeparator />
|
|
||||||
{TOGGLEABLE_COLUMNS.map((col) => (
|
{TOGGLEABLE_COLUMNS.map((col) => (
|
||||||
<DropdownMenuCheckboxItem
|
<label
|
||||||
key={col.id}
|
key={col.id}
|
||||||
|
className="flex cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-sm hover:bg-accent hover:text-accent-foreground"
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
checked={isColumnVisible(col.id)}
|
checked={isColumnVisible(col.id)}
|
||||||
onCheckedChange={(checked) =>
|
onCheckedChange={(checked) =>
|
||||||
toggleColumn(col.id, checked !== false)
|
toggleColumn(col.id, checked !== false)
|
||||||
}
|
}
|
||||||
>
|
/>
|
||||||
{col.label}
|
{col.label}
|
||||||
</DropdownMenuCheckboxItem>
|
</label>
|
||||||
))}
|
))}
|
||||||
</DropdownMenuContent>
|
</div>
|
||||||
</DropdownMenu>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue