Skip to content

Commit

Permalink
feat(components): add ButtonGroup component
Browse files Browse the repository at this point in the history
  • Loading branch information
mnlfischer committed Jan 12, 2024
1 parent 558a534 commit c540ead
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/components/button-group/button-group.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Meta, StoryObj } from "@storybook/react";
import React from "react";
import { ButtonGroup } from "./button-group";

const meta: Meta<typeof ButtonGroup> = {
title: "ButtonGroup",
component: ButtonGroup,
parameters: {
options: {
showPanel: false,
},
},
};

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

export const Default: Story = {
render: () => (
<ButtonGroup>
<ButtonGroup.Button type="button">Normal</ButtonGroup.Button>
<ButtonGroup.Button type="button" disabled>
Disabled
</ButtonGroup.Button>
<ButtonGroup.Button type="button" isActive>
Active
</ButtonGroup.Button>
<ButtonGroup.Button type="button" isActive disabled>
Active & Disabled
</ButtonGroup.Button>
<ButtonGroup.Button type="button">Button 1</ButtonGroup.Button>
</ButtonGroup>
),
};
42 changes: 42 additions & 0 deletions src/components/button-group/button-group.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from "react";
import { classNames } from "../../util/class-names";

interface ButtonProps extends React.ComponentPropsWithoutRef<"button"> {
children?: React.ReactNode;
type: "button" | "submit" | "reset";
isActive?: boolean;
}

const Button = ({ children, type, isActive, ...props }: ButtonProps) => {
return (
<button
data-slot="group-button"
// eslint-disable-next-line react/button-has-type
type={type}
className={classNames(
"relative -ml-px inline-flex bg-neutral-0 px-4 py-2 text-xs text-neutral-700 ring-1 ring-inset ring-neutral-400 hover:bg-neutral-100 hover:text-neutral-800 focus:z-10 focus:outline focus:outline-2 focus:outline-offset-0 focus:outline-primary-200 active:bg-neutral-200 disabled:bg-neutral-0 disabled:text-neutral-500",
isActive &&
"bg-primary-50 text-primary-500 hover:bg-primary-50 hover:text-primary-500 active:bg-primary-50 disabled:bg-neutral-100 disabled:text-neutral-500"
)}
{...props}
>
{children}
</button>
);
};

interface ButtonGroupProps {
children?: React.ReactNode;
}

const ButtonGroup = ({ children }: ButtonGroupProps) => {
return (
<div className="isolate inline-flex [&>[data-slot=group-button]:first-of-type]:ml-0 [&>[data-slot=group-button]:first-of-type]:rounded-l [&>[data-slot=group-button]:last-of-type]:rounded-r">
{children}
</div>
);
};

ButtonGroup.Button = Button;

export { ButtonGroup };
1 change: 1 addition & 0 deletions src/components/button-group/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ButtonGroup } from "./button-group";
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,4 @@ export { Toggle } from "./toggle";
export { Tooltip } from "./tooltip";
export { TopBar } from "./top-bar";
export { Disclosure } from "./disclosure";
export { ButtonGroup } from "./button-group";

0 comments on commit c540ead

Please sign in to comment.