Skip to content

Commit

Permalink
Move ButtonGroup to separate core component
Browse files Browse the repository at this point in the history
  • Loading branch information
solomonhawk committed Nov 21, 2024
1 parent 07d454d commit 6264717
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 54 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import type { Meta, StoryObj } from "@storybook/react";

import { Button } from "#components/core/button/button.js";

import { ButtonGroup } from "./button-group";

const meta = {
title: "UI/Core/ButtonGroup",
component: ButtonGroup,
tags: ["autodocs"],
parameters: {
layout: "centered",
},
} satisfies Meta<typeof ButtonGroup>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
children: [
<Button key="1">Left</Button>,
<Button key="1">Center</Button>,
<Button key="1">Right</Button>,
],
},
};
53 changes: 53 additions & 0 deletions packages/ui/src/components/core/button-group/button-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from "react";

import type { ButtonProps } from "#components/core/button/button.js";
import { cn } from "#lib/utils.js";

interface ButtonGroupProps {
className?: string;
orientation?: "horizontal" | "vertical";
children: React.ReactElement<ButtonProps>[];
}

export function ButtonGroup({
className,
orientation = "horizontal",
children,
}: ButtonGroupProps) {
const totalButtons = React.Children.count(children);
const isHorizontal = orientation === "horizontal";
const isVertical = orientation === "vertical";

return (
<div
className={cn(
"flex",
{
"flex-col": isVertical,
"w-fit": isVertical,
},
className,
)}
>
{React.Children.map(children, (child, index) => {
const isFirst = index === 0;
const isLast = index === totalButtons - 1;

return React.cloneElement(child, {
className: cn(
{
"rounded-l-none": isHorizontal && !isFirst,
"rounded-r-none": isHorizontal && !isLast,
"border-l-0": isHorizontal && !isFirst,

"rounded-t-none": isVertical && !isFirst,
"rounded-b-none": isVertical && !isLast,
"border-t-0": isVertical && !isFirst,
},
child.props.className,
),
});
})}
</div>
);
}
1 change: 1 addition & 0 deletions packages/ui/src/components/core/button-group/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./button-group";
2 changes: 1 addition & 1 deletion packages/ui/src/components/core/button/button.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/react";
import { Button } from "./button";

const meta = {
title: "UI/Button",
title: "UI/Core/Button",
component: Button,
tags: ["autodocs"],
parameters: {
Expand Down
55 changes: 2 additions & 53 deletions packages/ui/src/components/core/button/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as React from "react";

import { cn } from "#lib/utils.js";

const buttonVariants = cva(
export const buttonVariants = cva(
"inline-flex shrink-0 items-center justify-center gap-8 whitespace-nowrap rounded-sm text-sm ring-0 ring-offset-0 ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
Expand Down Expand Up @@ -44,7 +44,7 @@ export interface ButtonProps
asChild?: boolean;
}

const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
Expand All @@ -58,54 +58,3 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
},
);
Button.displayName = "Button";

interface ButtonGroupProps {
className?: string;
orientation?: "horizontal" | "vertical";
children: React.ReactElement<ButtonProps>[];
}

function ButtonGroup({
className,
orientation = "horizontal",
children,
}: ButtonGroupProps) {
const totalButtons = React.Children.count(children);
const isHorizontal = orientation === "horizontal";
const isVertical = orientation === "vertical";

return (
<div
className={cn(
"flex",
{
"flex-col": isVertical,
"w-fit": isVertical,
},
className,
)}
>
{React.Children.map(children, (child, index) => {
const isFirst = index === 0;
const isLast = index === totalButtons - 1;

return React.cloneElement(child, {
className: cn(
{
"rounded-l-none": isHorizontal && !isFirst,
"rounded-r-none": isHorizontal && !isLast,
"border-l-0": isHorizontal && !isFirst,

"rounded-t-none": isVertical && !isFirst,
"rounded-b-none": isVertical && !isLast,
"border-t-0": isVertical && !isFirst,
},
child.props.className,
),
});
})}
</div>
);
}

export { Button, ButtonGroup, buttonVariants };

0 comments on commit 6264717

Please sign in to comment.