Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new
DocumentationButtongroup

Buttongroup

A container that groups related buttons together with consistent styling.

Interactive preview

Rendered from the shared Frontfriend stories with React Base, the same preview Studio shows. Styling comes from your Design System; the code below is native to Radix UI.

Installation

Complete project setup first. Your configuration must select react/radix and include your Design System ID.

pnpm exec frontfriend download button-group -f react --primitive radix

Review dependencies reported by the downloader and keep your source changes in version control.

Usage

import { ButtonGroup } from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
<ButtonGroup orientation="horizontal" aria-label="Button group">
  <Button variant="tertiary">Button 1</Button>
  <Button variant="tertiary">Button 2</Button>
</ButtonGroup>;

Examples

Default

import { ButtonGroup } from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
<ButtonGroup  aria-label="Button group">
  <Button variant="tertiary">Button 1</Button>
  <Button variant="tertiary">Button 2</Button>
</ButtonGroup>;

Orientation

import { ButtonGroup } from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
<ButtonGroup
  orientation="vertical"
  aria-label="Media controls"
  className="h-fit"
>
  <Button variant="tertiary" size="icon" aria-label="Increase">
    <Icon name="Plus" size="4" />
  </Button>
  <Button variant="tertiary" size="icon" aria-label="Decrease">
    <Icon name="Minus" size="4" />
  </Button>
</ButtonGroup>;

Size

import { ButtonGroup } from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
<div className="flex flex-col items-start gap-8">
  <ButtonGroup>
    <Button variant="tertiary" size="sm">
      Small
    </Button>
    <Button variant="tertiary" size="sm">
      Button
    </Button>
    <Button variant="tertiary" size="sm">
      Group
    </Button>
  </ButtonGroup>
  <ButtonGroup>
    <Button variant="tertiary">Default</Button>
    <Button variant="tertiary">Button</Button>
    <Button variant="tertiary">Group</Button>
  </ButtonGroup>
  <ButtonGroup>
    <Button variant="tertiary" size="lg">
      Large
    </Button>
    <Button variant="tertiary" size="lg">
      Button
    </Button>
    <Button variant="tertiary" size="lg">
      Group
    </Button>
  </ButtonGroup>
</div>;

Nested

import { ButtonGroup } from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
<ButtonGroup>
  <ButtonGroup>
    {[1, 2, 3, 4, 5].map((value) => (
      <Button key={value} variant="tertiary" size="sm">
        {value}
      </Button>
    ))}
  </ButtonGroup>
  <ButtonGroup>
    <Button variant="tertiary" size="icon" aria-label="Previous">
      <Icon name="ArrowLeft" size="4" />
    </Button>
    <Button variant="tertiary" size="icon" aria-label="Next">
      <Icon name="ArrowRight" size="4" />
    </Button>
  </ButtonGroup>
</ButtonGroup>;

Separator

import {
  ButtonGroup,
  ButtonGroupSeparator,
} from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
<ButtonGroup>
  <Button variant="secondary" size="sm">
    Copy
  </Button>
  <ButtonGroupSeparator />
  <Button variant="secondary" size="sm">
    Paste
  </Button>
</ButtonGroup>;

Split

import {
  ButtonGroup,
  ButtonGroupSeparator,
} from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
<ButtonGroup>
  <Button variant="secondary">Button</Button>
  <ButtonGroupSeparator />
  <Button size="icon" variant="secondary" aria-label="Add">
    <Icon name="Plus" size="4" />
  </Button>
</ButtonGroup>;

With Input

import { ButtonGroup } from "@/components/ui/button-group";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
<ButtonGroup>
  <Input placeholder="Search..." />
  <Button variant="tertiary" aria-label="Search">
    <Icon name="Search" size="4" />
  </Button>
</ButtonGroup>;

With Input Group

import { ButtonGroup } from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
import {
  InputGroup,
  InputGroupInput,
  InputGroupAddon,
  InputGroupButton,
} from "@/components/ui/input-group";
<ButtonGroup>
  <ButtonGroup>
    <Button variant="tertiary" size="icon" aria-label="Add">
      <Icon name="Plus" size="4" />
    </Button>
  </ButtonGroup>
  <ButtonGroup>
    <InputGroup>
      <InputGroupInput placeholder="Send a message..." />
      <InputGroupAddon align="inline-end">
        <InputGroupButton size="icon-xs" aria-label="Share">
          <Icon name="Share" size="4" />
        </InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  </ButtonGroup>
</ButtonGroup>;

Dropdown

import { ButtonGroup } from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuSeparator,
} from "@/components/ui/dropdown-menu";
import { Icon } from "@/components/ui/icon";
<ButtonGroup>
  <Button variant="tertiary">Follow</Button>
  <DropdownMenu>
    <DropdownMenuTrigger asChild>
      <Button variant="tertiary" className="pl-2" aria-label="More">
        <Icon name="ChevronDown" size="4" />
      </Button>
    </DropdownMenuTrigger>
    <DropdownMenuContent align="end">
      <DropdownMenuGroup>
        <DropdownMenuItem>
          <Icon name="VolumeOff" size="4" />
          Mute Conversation
        </DropdownMenuItem>
        <DropdownMenuItem>
          <Icon name="Check" size="4" />
          Mark as Read
        </DropdownMenuItem>
        <DropdownMenuItem>
          <Icon name="Share" size="4" />
          Share Conversation
        </DropdownMenuItem>
        <DropdownMenuItem>
          <Icon name="Copy" size="4" />
          Copy Conversation
        </DropdownMenuItem>
      </DropdownMenuGroup>
      <DropdownMenuSeparator />
      <DropdownMenuGroup>
        <DropdownMenuItem variant="destructive">
          <Icon name="Trash" size="4" />
          Delete Conversation
        </DropdownMenuItem>
      </DropdownMenuGroup>
    </DropdownMenuContent>
  </DropdownMenu>
</ButtonGroup>;

Select Pairing

import { ButtonGroup } from "@/components/ui/button-group";
import {
  Select,
  SelectTrigger,
  SelectContent,
  SelectItem,
} from "@/components/ui/select";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
<ButtonGroup>
  <ButtonGroup>
    <Select defaultValue="$">
      <SelectTrigger className="font-mono">$</SelectTrigger>
      <SelectContent className="min-w-24">
        <SelectItem value="$">
          $ <span className="text-neutral-mid">US Dollar</span>
        </SelectItem>
        <SelectItem value="€">
          € <span className="text-neutral-mid">Euro</span>
        </SelectItem>
        <SelectItem value="£">
          £ <span className="text-neutral-mid">British Pound</span>
        </SelectItem>
      </SelectContent>
    </Select>
    <Input placeholder="10.00" pattern="[0-9]*" />
  </ButtonGroup>
  <ButtonGroup>
    <Button aria-label="Send" size="icon" variant="tertiary">
      <Icon name="ArrowRight" size="4" />
    </Button>
  </ButtonGroup>
</ButtonGroup>;

Popover Pairing

import { ButtonGroup } from "@/components/ui/button-group";
import { Button } from "@/components/ui/button";
import { Icon } from "@/components/ui/icon";
import {
  Popover,
  PopoverTrigger,
  PopoverContent,
} from "@/components/ui/popover";
import { Textarea } from "@/components/ui/textarea";
<ButtonGroup>
  <Button variant="tertiary">
    <Icon name="Bot" size="4" /> Copilot
  </Button>
  <Popover>
    <PopoverTrigger asChild>
      <Button variant="tertiary" size="icon" aria-label="Open Popover">
        <Icon name="ChevronDown" size="4" />
      </Button>
    </PopoverTrigger>
    <PopoverContent align="end" padding={false}>
      <div className="px-4 py-3">
        <div className="text-sm font-medium">Agent Tasks</div>
      </div>
      <div className="border-t border-neutral-subtle p-4 text-sm">
        <Textarea
          placeholder="Describe your task in natural language."
          className="mb-4 resize-none"
        />
        <p className="font-medium">Start a new task with Copilot</p>
        <p className="text-neutral-mid">
          Describe your task in natural language.
        </p>
      </div>
    </PopoverContent>
  </Popover>
</ButtonGroup>;

Text As Child

import { ButtonGroup, ButtonGroupText } from "@/components/ui/button-group";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
<ButtonGroup>
  <ButtonGroupText asChild>
    <Label htmlFor="url">https://</Label>
  </ButtonGroupText>
  <Input id="url" placeholder="frontfriend" />
  <ButtonGroupText>.dev</ButtonGroupText>
</ButtonGroup>;

API reference

Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Radix UI.

ButtonGroup

Prop Type Default Description
orientation "horizontal" | "vertical" — Set the button group layout.

ButtonGroupSeparator

Prop Type Default Description
orientation "horizontal" | "vertical" "vertical"

ButtonGroupText

Prop Type Default Description
asChild boolean false

Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.