'use client'; import { Columns3, Check, Bookmark } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; export interface ColumnPickerOption { /** Stable ID matching the column's `id` field in the table. */ id: string; /** Human-readable label shown in the dropdown menu. */ label: string; /** * When true, the column can't be toggled off (e.g. Name + actions). * It still appears in the menu but with a disabled checkmark. */ alwaysVisible?: boolean; } /** * Dropdown menu for toggling table column visibility. Lives next to the * filter bar — single source of truth for which columns the current * user wants to see in this table. Persistence is handled by the * parent (typically via `useTablePreferences`). */ export function ColumnPicker({ columns, hidden, onChange, onSaveView, }: { columns: ColumnPickerOption[]; hidden: string[]; onChange: (hidden: string[]) => void; /** * Optional callback. When provided, a "Save current view" item is * appended to the menu — folds the save-view affordance into the * column picker instead of a separate top-level button. */ onSaveView?: () => void; }) { const hiddenSet = new Set(hidden); function toggle(id: string) { const next = new Set(hiddenSet); if (next.has(id)) next.delete(id); else next.add(id); onChange(Array.from(next)); } function showAll() { onChange([]); } // The "All visible" affordance is only useful when something is // hidden — a no-op button is noise. const canShowAll = hidden.some((id) => columns.some((col) => col.id === id && !col.alwaysVisible), ); return ( {/* Hide entirely on mobile — small viewports render the list as cards (no columns to pick). The desktop table view shows this trigger from the `sm:` breakpoint up. */} Show / hide columns {columns.map((col) => { const isVisible = !hiddenSet.has(col.id); return ( { // Keep the menu open while toggling so the user can // flip multiple columns in one pass. e.preventDefault(); if (col.alwaysVisible) return; toggle(col.id); }} className="flex items-center gap-2" > {isVisible && } {col.label} {col.alwaysVisible && ( always )} ); })} {canShowAll && ( <> Show all columns )} {onSaveView && ( <> Save current view )} ); }