93 lines
3.5 KiB
TypeScript
93 lines
3.5 KiB
TypeScript
import { CaretDownIcon } from "~/components/ui/icons/vendor";
|
|
import { Button } from "./button";
|
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "./dropdown-menu";
|
|
import { ButtonGroup } from "~/ui/components/ButtonGroup";
|
|
import { Fragment } from "react/jsx-runtime";
|
|
import { Link } from "react-router";
|
|
import { cn } from "~/lib/utils";
|
|
|
|
interface Props {
|
|
children?: React.ReactNode;
|
|
onClick?: () => void;
|
|
href?: string;
|
|
target?: string;
|
|
variant?: "default" | "outline" | "ghost" | "link" | "destructive" | "secondary";
|
|
size?: "default" | "xs" | "sm" | "lg" | "icon";
|
|
items: {
|
|
name: React.ReactNode;
|
|
onClick?: () => void;
|
|
href?: string;
|
|
target?: string;
|
|
main?: boolean;
|
|
disabled?: boolean;
|
|
className?: string;
|
|
}[];
|
|
}
|
|
export default function SplitButton({ items, children, onClick, href, target, variant = "outline", size = "sm" }: Props) {
|
|
let foundMain = items.find((item) => item.main);
|
|
return (
|
|
// Subframe ButtonGroup `variant="split"` (gap-0) is the design-system container for the
|
|
// split-button pattern. `w-fit` neutralizes Subframe's `w-full`; the divider/border math
|
|
// stays on the buttons themselves (rounded-*-none / border-l-0), unchanged.
|
|
<ButtonGroup variant="split" align="start" className="divide-border w-fit items-center divide-x">
|
|
{foundMain?.onClick ? (
|
|
<Button size={size} variant={variant} className={"rounded-r-none"} onClick={foundMain.onClick}>
|
|
{foundMain.name}
|
|
</Button>
|
|
) : foundMain?.href ? (
|
|
<Button size={size} variant={variant} className={"rounded-r-none"} onClick={onClick} asChild>
|
|
<Link to={foundMain.href} target={foundMain.target}>
|
|
{foundMain.name}
|
|
</Link>
|
|
</Button>
|
|
) : href ? (
|
|
<Button size={size} variant={variant} className={"rounded-r-none"} onClick={onClick} asChild>
|
|
<Link to={href} target={target}>
|
|
{children}
|
|
</Link>
|
|
</Button>
|
|
) : (
|
|
<Button size={size} variant={variant} className={"rounded-r-none"} onClick={onClick}>
|
|
{children}
|
|
</Button>
|
|
)}
|
|
<DropdownMenu>
|
|
<DropdownMenuTrigger asChild>
|
|
<Button size={size} variant={variant} className={"rounded-l-none border-l-0 px-2"}>
|
|
<CaretDownIcon />
|
|
</Button>
|
|
</DropdownMenuTrigger>
|
|
<DropdownMenuContent>
|
|
<DropdownMenuGroup>
|
|
{items.map((item, idx) => (
|
|
<Fragment key={idx}>
|
|
{item.name === "separator" ? (
|
|
<DropdownMenuSeparator />
|
|
) : (
|
|
<DropdownMenuItem asChild>
|
|
{item.href ? (
|
|
<Link to={item.href} target={item.target} className="w-full text-left">
|
|
{item.name}
|
|
</Link>
|
|
) : (
|
|
<Button
|
|
size={size}
|
|
variant="ghost"
|
|
className={cn("w-full justify-start font-normal", item.className)}
|
|
onClick={item.onClick}
|
|
disabled={item.disabled}
|
|
>
|
|
{item.name}
|
|
</Button>
|
|
)}
|
|
</DropdownMenuItem>
|
|
)}
|
|
</Fragment>
|
|
))}
|
|
</DropdownMenuGroup>
|
|
</DropdownMenuContent>
|
|
</DropdownMenu>
|
|
</ButtonGroup>
|
|
);
|
|
}
|