ButtonGroup

A flexible button group component that allows you to group related buttons together. Supports multiple variants, orientations, and styling options.

Default

Attached

Separated

Pill

Usage

tsx
1import { ButtonGroup, ButtonGroupItem } from "@/app/ui/molecules/ButtonGroup";
2
3// Basic usage
4<ButtonGroup>
5 <ButtonGroupItem>First</ButtonGroupItem>
6 <ButtonGroupItem>Second</ButtonGroupItem>
7 <ButtonGroupItem>Third</ButtonGroupItem>
8</ButtonGroup>

API Reference

ButtonGroup Props

tsx
1interface ButtonGroupProps {
2 /**
3 * The buttons to render in the group. Each button will be automatically styled.
4 */
5 children: ReactNode;
6
7 /**
8 * The variant of the button group layout.
9 * @default "default"
10 */
11 variant?: "default" | "attached" | "separated" | "pill";
12
13 /**
14 * The size of all buttons in the group.
15 * @default "md"

ButtonGroupItem Props

tsx
1interface ButtonGroupItemProps {
2 /**
3 * The content of the button.
4 */
5 children: ReactNode;
6
7 /**
8 * If true, the button will be disabled.
9 * @default false
10 */
11 disabled?: boolean;
12
13 /**
14 * If true, the button will be in an active/selected state.
15 * @default false

Examples

Basic Usage

tsx
1// Default button group
2<ButtonGroup>
3 <ButtonGroupItem>First</ButtonGroupItem>
4 <ButtonGroupItem>Second</ButtonGroupItem>
5 <ButtonGroupItem>Third</ButtonGroupItem>
6</ButtonGroup>
7
8// Attached buttons (no gaps)
9<ButtonGroup variant="attached">
10 <ButtonGroupItem>Copy</ButtonGroupItem>
11 <ButtonGroupItem>Download</ButtonGroupItem>
12 <ButtonGroupItem>Share</ButtonGroupItem>
13</ButtonGroup>
14
15// Separated buttons with gaps

Variants

tsx
1// Default variant (white background)
2<ButtonGroup buttonVariant="default">
3 <ButtonGroupItem>Copy</ButtonGroupItem>
4 <ButtonGroupItem>Download</ButtonGroupItem>
5 <ButtonGroupItem>Share</ButtonGroupItem>
6</ButtonGroup>
7
8// Primary variant (blue background)
9<ButtonGroup buttonVariant="primary">
10 <ButtonGroupItem>Save</ButtonGroupItem>
11 <ButtonGroupItem>Cancel</ButtonGroupItem>
12</ButtonGroup>
13
14// Secondary variant (gray background)
15<ButtonGroup buttonVariant="secondary">

With Icons

tsx
1import { Copy, Download, Share, Heart, Star, Bookmark } from "lucide-react";
2
3// Icons only
4<ButtonGroup>
5 <ButtonGroupItem>
6 <Copy className="w-4 h-4" />
7 </ButtonGroupItem>
8 <ButtonGroupItem>
9 <Download className="w-4 h-4" />
10 </ButtonGroupItem>
11 <ButtonGroupItem>
12 <Share className="w-4 h-4" />
13 </ButtonGroupItem>
14</ButtonGroup>

Vertical Orientation

tsx
1import { Home, User, Settings } from "lucide-react";
2
3// Vertical orientation
4<ButtonGroup orientation="vertical">
5 <ButtonGroupItem>First</ButtonGroupItem>
6 <ButtonGroupItem>Second</ButtonGroupItem>
7 <ButtonGroupItem>Third</ButtonGroupItem>
8</ButtonGroup>
9
10// Vertical with icons
11<ButtonGroup orientation="vertical" variant="separated">
12 <ButtonGroupItem>
13 <Home className="w-4 h-4 mr-2" />
14 Home
15 </ButtonGroupItem>

Full Width

tsx
1// Full width button group
2<ButtonGroup fullWidth>
3 <ButtonGroupItem>First</ButtonGroupItem>
4 <ButtonGroupItem>Second</ButtonGroupItem>
5 <ButtonGroupItem>Third</ButtonGroupItem>
6</ButtonGroup>
7
8// Full width vertical
9<ButtonGroup orientation="vertical" fullWidth>
10 <ButtonGroupItem>Home</ButtonGroupItem>
11 <ButtonGroupItem>About</ButtonGroupItem>
12 <ButtonGroupItem>Contact</ButtonGroupItem>
13</ButtonGroup>

Implementation

ButtonGroup.tsx
tsx
1import React, { forwardRef, HTMLAttributes, ReactElement, ReactNode } from "react";
2import { cva, type VariantProps } from "class-variance-authority";
3import { cn } from "@/lib/cn";
4
5// Define button group variants using class-variance-authority
6const buttonGroupVariants = cva(
7 [
8 "inline-flex",
9 "shadow-sm",
10 ],
11 {
12 variants: {
13 variant: {
14 default: [
15 "rounded-lg",