Basic UI
  • Docs
  • Compressor
  • Parser
Getting Started
  • Introduction
  • Themenew
Components
  • Button
  • Button Group
  • Badge
  • Radio Group
  • Checkbox
  • Avatar
  • Label
  • File Dropzone
  1. Docs/
  2. Components/
  3. Button Group

Button Group

Previous pageNext page

A segmented control component that groups multiple buttons together with shared borders and styling. Button groups are useful for creating toggle controls, navigation tabs, and related action sets.

Loading...

Installation

pnpm dlx shadcn@latest add @basic-ui/button-group

Usage

import { ButtonGroup } from "@/components/ui/button-group"
 
export default function App() {
  return (
    <





Previous
Button
Next
Badge

On This Page

InstallationUsageExamplesBasic Button GroupIcon Button GroupFeaturesPropsButtonGroupButtonGroupTextDesign TokensBest Practices
button-group-demo
ButtonGroup
size
=
"r"
>
<button>Action</button>
<button>Action</button>
<button>Action</button>
</ButtonGroup>
)
}

Examples

Basic Button Group

The button group component automatically handles border styling, spacing, and corner radius for grouped buttons. It supports three size variants.

Loading...

Icon Button Group

Button groups work seamlessly with icon-only buttons, making them ideal for navigation controls and toolbar actions.

Loading...

Features

  • Automatic Border Management: Removes internal borders using CSS selectors
  • Smart Corner Radius: First button keeps left radius, last button keeps right radius, middle buttons get squared
  • CSS Selector-Based: Uses [&>*:not(:first-child)] and [&>*:not(:last-child)] for automatic styling
  • Orientation Support: Horizontal and vertical button groups
  • Size Variants: Three sizes matching the button height system (s: 28px, r: 32px, m: 36px)
  • Full Width Option: Can stretch to full container width
  • Flexible Content: Works with text buttons, icon buttons, or mixed content
  • Radix Slot: ButtonGroupText component supports polymorphic rendering with asChild
  • Accessibility: Proper ARIA roles and keyboard navigation support

Props

ButtonGroup

The ButtonGroup component accepts all standard div HTML attributes plus:

PropTypeDefaultDescription
sizes | r | mrThe size of the button group (s=28px, r=32px, m=36px)
orientationhorizontal | verticalhorizontalThe orientation of the button group
fullWidthbooleanfalseWhether the button group should take full width of its container
childrenReactNode-Button elements to be grouped together

ButtonGroupText

A text/label component that can be used within button groups for non-interactive content.

PropTypeDefaultDescription
asChildbooleanfalseChange the default rendered element for the one passed as a child (uses Radix Slot)
childrenReactNode-Text content or child elements

Design Tokens

The button group uses the following design tokens:

  • Heights: --button-height-s (28px), --button-height-r (32px), --button-height-m (36px)
  • Radius: --button-radius-s (7px), --button-radius-r (8px), --button-radius-m (9px)
  • Colors:
    • --grey-bg-fill-12-bg-white (background)
    • --grey-stroke-alpha-4-hover (borders)
    • --grey-shadow-4 (shadows)
  • Spacing: --gap-4 (8px) for internal spacing

Best Practices

  1. Group Related Actions: Use button groups for related actions that belong together semantically
  2. Consistent Button Types: Keep all buttons within a group the same type (all text or all icons)
  3. Limit Group Size: Aim for 2-5 buttons per group for optimal usability
  4. Clear Labels: Ensure button labels are concise and descriptive
  5. Accessible Icons: Always provide aria-label for icon-only buttons

Size: 28px (s)

Size: 32px (r) - Default

Size: 36px (m)

button-group-demo

Size: 28px (s)

Size: 32px (r) - Default

Size: 36px (m)

button-group-icon

Icon Buttons - 28px

Icon Buttons - 32px

Icon Buttons - 36px

import { ButtonGroup } from '@/registry/basic-ui/button-group';
import { Button } from '@/registry/basic-ui/button';

export function ButtonGroupDemo() {
  return (
    <div className="flex flex-col gap-(--gap-8)">
      {/* Size: 28px (s) */}
      <div className="flex flex-col gap-(--gap-4)">
        <h3 className="text-sm font-medium">Size: 28px (s)</h3>
        <ButtonGroup size="s">
          <Button variant="text">Action</Button>
          <Button variant="text">Action</Button>
          <Button variant="text" disabled>
            Action
          </Button>
          <Button variant="text">
            <div className="flex items-center gap-(--gap-2)">
              <span>Action</span>
              <svg
                className=" w-3.5 h-3.5"
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                strokeLinecap="round"
                strokeLinejoin="round"
              >
                <path d="m6 9 6 6 6-6" />
              </svg>
            </div>
          </Button>
        </ButtonGroup>
      </div>

      {/* Size: 32px (r) - Default */}
      <div className="flex flex-col gap-(--gap-4)">
        <h3 className="text-sm font-medium">Size: 32px (r) - Default</h3>
        <ButtonGroup size="r">
          <button>Action</button>
          <button>Action</button>
          <button disabled>Action</button>
          <button>
            Action
            <svg
              className="ml-(--gap-2) w-3.5 h-3.5"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m6 9 6 6 6-6" />
            </svg>
          </button>
        </ButtonGroup>
      </div>

      {/* Size: 36px (m) */}
      <div className="flex flex-col gap-(--gap-4)">
        <h3 className="text-sm font-medium">Size: 36px (m)</h3>
        <ButtonGroup size="m">
          <button>Action</button>
          <button>Action</button>
          <button disabled>Action</button>
          <button>
            Action
            <svg
              className="ml-(--gap-2) w-3.5 h-3.5"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m6 9 6 6 6-6" />
            </svg>
          </button>
        </ButtonGroup>
      </div>
    </div>
  );
}
import { ButtonGroup } from '@/registry/basic-ui/button-group';
import { Button } from '@/registry/basic-ui/button';

export function ButtonGroupDemo() {
  return (
    <div className="flex flex-col gap-(--gap-8)">
      {/* Size: 28px (s) */}
      <div className="flex flex-col gap-(--gap-4)">
        <h3 className="text-sm font-medium">Size: 28px (s)</h3>
        <ButtonGroup size="s">
          <Button variant="text">Action</Button>
          <Button variant="text">Action</Button>
          <Button variant="text" disabled>
            Action
          </Button>
          <Button variant="text">
            <div className="flex items-center gap-(--gap-2)">
              <span>Action</span>
              <svg
                className=" w-3.5 h-3.5"
                xmlns="http://www.w3.org/2000/svg"
                viewBox="0 0 24 24"
                fill="none"
                stroke="currentColor"
                strokeWidth="2"
                strokeLinecap="round"
                strokeLinejoin="round"
              >
                <path d="m6 9 6 6 6-6" />
              </svg>
            </div>
          </Button>
        </ButtonGroup>
      </div>

      {/* Size: 32px (r) - Default */}
      <div className="flex flex-col gap-(--gap-4)">
        <h3 className="text-sm font-medium">Size: 32px (r) - Default</h3>
        <ButtonGroup size="r">
          <button>Action</button>
          <button>Action</button>
          <button disabled>Action</button>
          <button>
            Action
            <svg
              className="ml-(--gap-2) w-3.5 h-3.5"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m6 9 6 6 6-6" />
            </svg>
          </button>
        </ButtonGroup>
      </div>

      {/* Size: 36px (m) */}
      <div className="flex flex-col gap-(--gap-4)">
        <h3 className="text-sm font-medium">Size: 36px (m)</h3>
        <ButtonGroup size="m">
          <button>Action</button>
          <button>Action</button>
          <button disabled>Action</button>
          <button>
            Action
            <svg
              className="ml-(--gap-2) w-3.5 h-3.5"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m6 9 6 6 6-6" />
            </svg>
          </button>
        </ButtonGroup>
      </div>
    </div>
  );
}
import { ButtonGroup } from '@/registry/basic-ui/button-group';

export function ButtonGroupIconDemo() {
  return (
    <div className="flex flex-col gap-(--gap-8)">
      {/* Icon buttons - Size 28px */}
      <div className="flex flex-col gap-(--gap-4)">
        <h3 className="text-sm font-medium">Icon Buttons - 28px</h3>
        <ButtonGroup size="s">
          <button className="w-8" aria-label="Previous">
            <svg
              className="w-4 h-4"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m15 18-6-6 6-6" />
            </svg>
          </button>
          <button className="w-8" aria-label="Up">
            <svg
              className="w-4 h-4"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m18 15-6-6-6 6" />
            </svg>
          </button>
          <button className="w-8" aria-label="Next">
            <svg
              className="w-4 h-4"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m9 18 6-6-6-6" />
            </svg>
          </button>
        </ButtonGroup>
      </div>

      {/* Icon buttons - Size 32px */}
      <div className="flex flex-col gap-(--gap-4)">
        <h3 className="text-sm font-medium">Icon Buttons - 32px</h3>
        <ButtonGroup size="r">
          <button className="w-9" aria-label="Previous">
            <svg
              className="w-4 h-4"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m15 18-6-6 6-6" />
            </svg>
          </button>
          <button className="w-9" aria-label="Up">
            <svg
              className="w-4 h-4"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m18 15-6-6-6 6" />
            </svg>
          </button>
          <button className="w-9" aria-label="Next">
            <svg
              className="w-4 h-4"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m9 18 6-6-6-6" />
            </svg>
          </button>
        </ButtonGroup>
      </div>

      {/* Icon buttons - Size 36px */}
      <div className="flex flex-col gap-(--gap-4)">
        <h3 className="text-sm font-medium">Icon Buttons - 36px</h3>
        <ButtonGroup size="m">
          <button className="w-10" aria-label="Previous">
            <svg
              className="w-[18px] h-[18px]"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m15 18-6-6 6-6" />
            </svg>
          </button>
          <button className="w-10" aria-label="Up">
            <svg
              className="w-[18px] h-[18px]"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m18 15-6-6-6 6" />
            </svg>
          </button>
          <button className="w-10" aria-label="Next">
            <svg
              className="w-[18px] h-[18px]"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              strokeWidth="2"
              strokeLinecap="round"
              strokeLinejoin="round"
            >
              <path d="m9 18 6-6-6-6" />
            </svg>
          </button>
        </ButtonGroup>
      </div>
    </div>
  );
}