Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 105x 105x 568x 28x 28x 105x 75x 570x 28x | import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
import { EyeIcon, EyeOffIcon } from "lucide-react";
import * as UI from "@/components";
import { cn } from "@/utils";
type Props<T extends UI.OsTableColumn> = {
list: T[];
onItemClick: (field: string) => void;
hiddenColumns: T[];
};
export const VisibilityPopover = ({
list,
onItemClick,
hiddenColumns,
}: Props<UI.OsTableColumn>) => {
return (
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<UI.Button
variant="outline"
className="w-full xs:w-fit whitespace-nowrap hover:bg-transparent self-center h-10 flex gap-2"
data-testid="columns-menu-btn"
>
<span className="prose-sm">
{hiddenColumns.length ? `Columns (${hiddenColumns.length} hidden)` : "Columns"}
</span>
</UI.Button>
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<VisibilityMenu list={list} onItemClick={onItemClick} hiddenColumns={hiddenColumns} />
</DropdownMenu.Portal>
</DropdownMenu.Root>
);
};
export const VisiblityItem = <T extends UI.OsTableColumn>(props: T & { onClick: () => void }) => {
const eyeStyles = cn("flex gap-2", {
"text-gray-800": !props.hidden,
"text-gray-500": props.hidden,
});
return (
<li>
<DropdownMenu.Item
asChild
onSelect={(e) => {
e.preventDefault(); // necessary to prevent closing the menu when selecting an item
props.onClick();
}}
>
<button
className={cn("flex items-center gap-2 w-full", {
"text-gray-800": !props.hidden,
"text-gray-500": props.hidden,
})}
type="button"
aria-label={`${props.label}, toggle visibility, currently ${props.hidden ? "hidden" : "visible"}`}
aria-live="polite"
>
{props.hidden ? (
<EyeOffIcon className={eyeStyles} aria-hidden focusable={false} />
) : (
<EyeIcon className={eyeStyles} aria-hidden focusable={false} />
)}
<span aria-hidden>{props.label}</span>
</button>
</DropdownMenu.Item>
</li>
);
};
export const VisibilityMenu = <T extends UI.OsTableColumn>(props: Props<T>) => (
<DropdownMenu.Content asChild>
<ul
className="flex flex-col gap-2 bg-white p-4 shadow-md rounded-md w-72"
data-testid="columns-menu"
>
{props.list.map((IT) =>
IT.field ? (
<VisiblityItem
key={`vis-${IT.field}`}
onClick={() => props.onItemClick(IT.field as string)}
{...IT}
/>
) : null,
)}
</ul>
</DropdownMenu.Content>
);
|