Files
HiveGrid-Wireframes/hivegrid-cloud/apps/web/app/components/ui/button-group.tsx
T

101 lines
3.8 KiB
TypeScript

import * as React from "react";
import { cn } from "~/lib/utils";
import { Button } from "./button";
import { Tabs as TabsComponent, TabsList, TabsTrigger } from "./tabs";
import { ButtonGroup as SubframeButtonGroup } from "~/ui/components/ButtonGroup";
import { Fragment, useState } from "react";
import { Link } from "react-router";
import HintTooltip from "./tooltips/HintTooltip";
interface ButtonGroupProps {
items: {
name: string;
href?: string;
target?: string;
component?: React.ReactNode;
hidden?: boolean;
onClick?: () => void;
active?: boolean;
disabled?: boolean;
}[];
variant?: "default" | "tabs";
size?: "xs" | "sm" | "default" | "lg";
className?: string;
}
export function ButtonGroup({ items, variant = "tabs", size = "sm", className }: ButtonGroupProps) {
let activeItems = items.filter((item) => !item.hidden);
const [value, setValue] = useState(activeItems.find((item) => item.active)?.name || (activeItems.length > 0 ? activeItems[0].name : ""));
if (variant === "tabs") {
return (
<TabsComponent value={value} onValueChange={(v) => setValue(v)} className={cn(className)}>
<TabsList className="w-full">
{activeItems.map((item) =>
item.href ? (
<TabsTrigger
key={item.name}
value={item.name}
onClick={item.onClick}
className={cn(item.active && "bg-secondary text-secondary-foreground")}
asChild
>
<Link to={item.href} target={item.target}>
{item.component || item.name}
</Link>
</TabsTrigger>
) : (
<TabsTrigger key={item.name} value={item.name} onClick={item.onClick} className={cn(item.active && "bg-secondary text-secondary-foreground")}>
{item.component || item.name}
</TabsTrigger>
)
)}
</TabsList>
</TabsComponent>
);
}
return (
// Subframe ButtonGroup `variant="split"` (gap-0) is the design-system container for the
// connected-button row. The original `isolate inline-flex rounded-md` look + width sizing
// are restored via className (neutralizing Subframe's `w-full`); per-button border/radius
// math stays on the buttons, unchanged.
<SubframeButtonGroup variant="split" align="start" className={cn("isolate inline-flex w-fit rounded-md", className)}>
{activeItems.map((item, idx) => (
<Fragment key={item.name}>
<Button
size={size}
variant="outline"
type="button"
onClick={(e) => {
// e.preventDefault();
e.stopPropagation();
item.onClick?.();
}}
className={cn(
item.active && "bg-secondary text-secondary-foreground",
idx > 0 && idx < activeItems.length - 1 && "rounded-none border-x-0",
idx === 0 && "rounded-l-md rounded-r-none border-r-0",
idx === activeItems.length - 1 && "rounded-l-none rounded-r-md border-l-0",
idx < activeItems.length - 1 && "border-r"
)}
asChild={item.href ? true : false}
disabled={item.disabled}
>
{item.href && !item.disabled ? (
<Link to={item.href} target={item.target}>
{item.component ? (
<HintTooltip text={<div className="overflow-hidden">{item.name}</div>}>
<span>{item.component || item.name}</span>
</HintTooltip>
) : (
<div>{item.name}</div>
)}
</Link>
) : (
<span>{item.component || item.name}</span>
)}
</Button>
</Fragment>
))}
</SubframeButtonGroup>
);
}