2025-09-12 14:42:00 -05:00
|
|
|
import { Children, ReactElement, cloneElement, isValidElement } from "react";
|
2025-08-15 01:01:04 -05:00
|
|
|
|
2025-09-12 14:42:00 -05:00
|
|
|
import { type ButtonProps } from "@/components/ui/button";
|
|
|
|
|
import { cn } from "@/lib/utils";
|
2025-08-15 01:01:04 -05:00
|
|
|
|
|
|
|
|
interface ButtonGroupProps {
|
|
|
|
|
className?: string;
|
2025-09-12 14:42:00 -05:00
|
|
|
orientation?: "horizontal" | "vertical";
|
2025-08-16 01:30:18 -05:00
|
|
|
children: ReactElement<ButtonProps>[] | React.ReactNode;
|
2025-08-15 01:01:04 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const ButtonGroup = ({
|
|
|
|
|
className,
|
2025-09-12 14:42:00 -05:00
|
|
|
orientation = "horizontal",
|
2025-08-15 01:01:04 -05:00
|
|
|
children,
|
|
|
|
|
}: ButtonGroupProps) => {
|
2025-09-12 14:42:00 -05:00
|
|
|
const isHorizontal = orientation === "horizontal";
|
|
|
|
|
const isVertical = orientation === "vertical";
|
2025-08-15 01:01:04 -05:00
|
|
|
|
2025-08-16 01:30:18 -05:00
|
|
|
// Normalize and filter only valid React elements
|
2025-09-12 14:42:00 -05:00
|
|
|
const childArray = Children.toArray(children).filter(
|
|
|
|
|
(child): child is ReactElement<ButtonProps> => isValidElement(child),
|
2025-08-16 01:30:18 -05:00
|
|
|
);
|
|
|
|
|
const totalButtons = childArray.length;
|
|
|
|
|
|
2025-08-15 01:01:04 -05:00
|
|
|
return (
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
2025-09-12 14:42:00 -05:00
|
|
|
"flex",
|
2025-08-15 01:01:04 -05:00
|
|
|
{
|
2025-09-12 14:42:00 -05:00
|
|
|
"flex-col": isVertical,
|
|
|
|
|
"w-fit": isVertical,
|
2025-08-15 01:01:04 -05:00
|
|
|
},
|
2025-09-12 14:42:00 -05:00
|
|
|
className,
|
2025-08-15 01:01:04 -05:00
|
|
|
)}
|
|
|
|
|
>
|
2025-08-16 01:30:18 -05:00
|
|
|
{childArray.map((child, index) => {
|
2025-08-15 01:01:04 -05:00
|
|
|
const isFirst = index === 0;
|
|
|
|
|
const isLast = index === totalButtons - 1;
|
|
|
|
|
|
|
|
|
|
return cloneElement(child, {
|
|
|
|
|
className: cn(
|
|
|
|
|
{
|
2025-09-12 14:42:00 -05:00
|
|
|
"rounded-l-none": isHorizontal && !isFirst,
|
|
|
|
|
"rounded-r-none": isHorizontal && !isLast,
|
|
|
|
|
"border-l-0": isHorizontal && !isFirst,
|
2025-08-15 01:01:04 -05:00
|
|
|
|
2025-09-12 14:42:00 -05:00
|
|
|
"rounded-t-none": isVertical && !isFirst,
|
|
|
|
|
"rounded-b-none": isVertical && !isLast,
|
|
|
|
|
"border-t-0": isVertical && !isFirst,
|
2025-08-15 01:01:04 -05:00
|
|
|
},
|
2025-09-12 14:42:00 -05:00
|
|
|
child.props.className,
|
2025-08-15 01:01:04 -05:00
|
|
|
),
|
|
|
|
|
});
|
|
|
|
|
})}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2025-09-12 14:42:00 -05:00
|
|
|
};
|