Sections
Get Started
UI
Components
- Animated Beam
- Animated List
- Animated Logo
- Animated Theme Toggler
- Avatar Circles
- Bento Grid
- Big Name Text
- Border Beam
- Dock
- Feature Card
- Filter Dropdown
- Footer Link
- Hero Badge
- Hero Buttons
- Hyper Text
- Lens
- Magic Card
- Marquee
- Meteors
- Onboarding Form
- Pricing Card
- Scroll Text
- Section Header
- Site Header
- Status Card
- Status
- Tweet Card
"use client";
import {
ArchiveIcon,
ArrowLeftIcon,
CalendarPlusIcon,
ClockIcon,
ListIcon,
MailCheckIcon,
MoreHorizontalIcon,
TagIcon,
} from "lucide-react";
import { Button } from "@/registry/sase/button";
import { ButtonGroup } from "@/registry/sase/button-group";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/registry/sase/dropdown-menu";
export function ButtonGroupDemo() {
return (
<ButtonGroup>
<ButtonGroup className="hidden sm:flex">
<Button variant="outline" size="icon-sm" aria-label="Go Back">
<ArrowLeftIcon />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="sm">
Archive
</Button>
<Button variant="outline" size="sm">
Report
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="sm">
Snooze
</Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon-sm" aria-label="More Options">
<MoreHorizontalIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48 [--radius:1rem]">
<DropdownMenuGroup>
<DropdownMenuItem>
<MailCheckIcon />
Mark as Read
</DropdownMenuItem>
<DropdownMenuItem>
<ArchiveIcon />
Archive
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<ClockIcon />
Snooze
</DropdownMenuItem>
<DropdownMenuItem>
<CalendarPlusIcon />
Add to Calendar
</DropdownMenuItem>
<DropdownMenuItem>
<ListIcon />
Add to List
</DropdownMenuItem>
<DropdownMenuItem>
<TagIcon />
Label As...
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>
</ButtonGroup>
);
}
Installation
pnpm dlx shadcn@latest add https://sase-ui.vercel.app/r/button-group.json
Usage
import { ButtonGroup } from "@/components/ui/button-group";<ButtonGroup>
<Button variant="outline">Previous</Button>
<Button variant="outline">Next</Button>
</ButtonGroup>Examples
With Dropdown
"use client";
import {
ArchiveIcon,
ArrowLeftIcon,
CalendarPlusIcon,
ClockIcon,
ListIcon,
MailCheckIcon,
MoreHorizontalIcon,
TagIcon,
} from "lucide-react";
import { Button } from "@/registry/sase/button";
import { ButtonGroup } from "@/registry/sase/button-group";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/registry/sase/dropdown-menu";
export function ButtonGroupDemo() {
return (
<ButtonGroup>
<ButtonGroup className="hidden sm:flex">
<Button variant="outline" size="icon-sm" aria-label="Go Back">
<ArrowLeftIcon />
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="sm">
Archive
</Button>
<Button variant="outline" size="sm">
Report
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="sm">
Snooze
</Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline" size="icon-sm" aria-label="More Options">
<MoreHorizontalIcon />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-48 [--radius:1rem]">
<DropdownMenuGroup>
<DropdownMenuItem>
<MailCheckIcon />
Mark as Read
</DropdownMenuItem>
<DropdownMenuItem>
<ArchiveIcon />
Archive
</DropdownMenuItem>
</DropdownMenuGroup>
<DropdownMenuSeparator />
<DropdownMenuGroup>
<DropdownMenuItem>
<ClockIcon />
Snooze
</DropdownMenuItem>
<DropdownMenuItem>
<CalendarPlusIcon />
Add to Calendar
</DropdownMenuItem>
<DropdownMenuItem>
<ListIcon />
Add to List
</DropdownMenuItem>
<DropdownMenuItem>
<TagIcon />
Label As...
</DropdownMenuItem>
</DropdownMenuGroup>
</DropdownMenuContent>
</DropdownMenu>
</ButtonGroup>
</ButtonGroup>
);
}
Nested Groups
"use client";
import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react";
import { Button } from "@/registry/sase/button";
import { ButtonGroup } from "@/registry/sase/button-group";
export function ButtonGroupNested() {
return (
<ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="sm">
1
</Button>
<Button variant="outline" size="sm">
2
</Button>
<Button variant="outline" size="sm">
3
</Button>
</ButtonGroup>
<ButtonGroup>
<Button variant="outline" size="icon-sm" aria-label="Previous">
<ArrowLeftIcon />
</Button>
<Button variant="outline" size="icon-sm" aria-label="Next">
<ArrowRightIcon />
</Button>
</ButtonGroup>
</ButtonGroup>
);
}
With Popover
import { BotIcon, ChevronDownIcon } from "lucide-react";
import { Button } from "@/registry/sase/button";
import { ButtonGroup } from "@/registry/sase/button-group";
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/registry/sase/popover";
import { Separator } from "@/registry/sase/separator";
import { Textarea } from "@/registry/sase/textarea";
export function ButtonGroupPopover() {
return (
<ButtonGroup>
<Button variant="outline" size="sm">
<BotIcon /> Copilot
</Button>
<Popover>
<PopoverTrigger asChild>
<Button variant="outline" size="icon-sm" aria-label="Open Popover">
<ChevronDownIcon />
</Button>
</PopoverTrigger>
<PopoverContent align="end" className="rounded-xl p-0 text-sm">
<div className="px-4 py-3">
<div className="text-sm font-medium">Agent Tasks</div>
</div>
<Separator />
<div className="p-4 text-sm *:[p:not(:last-child)]:mb-2">
<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-muted-foreground">
Describe your task in natural language. Copilot will work in the
background and open a pull request for your review.
</p>
</div>
</PopoverContent>
</Popover>
</ButtonGroup>
);
}
With Input
"use client";
import * as React from "react";
import { AudioLinesIcon, PlusIcon } from "lucide-react";
import { Button } from "@/registry/sase/button";
import { ButtonGroup } from "@/registry/sase/button-group";
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
} from "@/registry/sase/input-group";
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/registry/sase/tooltip";
export function ButtonGroupInputGroup() {
const [voiceEnabled, setVoiceEnabled] = React.useState(false);
return (
<ButtonGroup className="[--radius:9999rem]">
<ButtonGroup>
<Button variant="outline" size="icon" aria-label="Add">
<PlusIcon />
</Button>
</ButtonGroup>
<ButtonGroup className="flex-1">
<InputGroup>
<InputGroupInput
placeholder={
voiceEnabled ? "Record and send audio..." : "Send a message..."
}
disabled={voiceEnabled}
/>
<InputGroupAddon align="inline-end">
<Tooltip>
<TooltipTrigger asChild>
<InputGroupButton
onClick={() => setVoiceEnabled(!voiceEnabled)}
data-active={voiceEnabled}
className="data-[active=true]:bg-primary data-[active=true]:text-primary-foreground"
aria-pressed={voiceEnabled}
size="icon-xs"
aria-label="Voice Mode"
>
<AudioLinesIcon />
</InputGroupButton>
</TooltipTrigger>
<TooltipContent>Voice Mode</TooltipContent>
</Tooltip>
</InputGroupAddon>
</InputGroup>
</ButtonGroup>
</ButtonGroup>
);
}