Get Started
Input
Feedback
Display
Installation
i18n
"use client"
import * as React from "react"インストール#
pnpm dlx shadcn@latest add https://ui.tyap.me/r/styles/base/button-group.jsonnpx shadcn@latest add https://ui.tyap.me/r/styles/base/button-group.jsonyarn dlx shadcn@latest add https://ui.tyap.me/r/styles/base/button-group.jsonbunx --bun shadcn@latest add https://ui.tyap.me/r/styles/base/button-group.json
以下の依存パッケージをインストールします:
pnpm add @base-ui/reactnpm install @base-ui/reactyarn add @base-ui/reactbun add @base-ui/react
以下のコードをプロジェクトにコピーします。
import { mergeProps } from "@base-ui/react/merge-props"
import { useRender } from "@base-ui/react/use-render"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { Separator } from "@/components/ui/separator"
const buttonGroupVariants = cva(
"flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-4xl [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
{
variants: {
orientation: {
horizontal:
"*:data-slot:rounded-r-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-4xl! [&>[data-slot]~[data-slot]]:rounded-l-none [&>[data-slot]~[data-slot]]:border-l-0",
vertical:
"flex-col *:data-slot:rounded-b-none [&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-4xl! [&>[data-slot]~[data-slot]]:rounded-t-none [&>[data-slot]~[data-slot]]:border-t-0",
},
},
defaultVariants: {
orientation: "horizontal",
},
}
)
function ButtonGroup({
className,
orientation,
...props
}: React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>) {
return (
<div
role="group"
data-slot="button-group"
data-orientation={orientation}
className={cn(buttonGroupVariants({ orientation }), className)}
{...props}
/>
)
}
function ButtonGroupText({
className,
render,
...props
}: useRender.ComponentProps<"div">) {
return useRender({
defaultTagName: "div",
props: mergeProps<"div">(
{
className: cn(
"flex items-center gap-2 rounded-4xl border bg-muted px-2.5 text-sm font-medium [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
className
),
},
props
),
render,
state: {
slot: "button-group-text",
},
})
}
function ButtonGroupSeparator({
className,
orientation = "vertical",
...props
}: React.ComponentProps<typeof Separator>) {
return (
<Separator
data-slot="button-group-separator"
orientation={orientation}
className={cn(
"relative self-stretch bg-input data-horizontal:mx-px data-horizontal:w-auto data-vertical:my-px data-vertical:h-auto",
className
)}
{...props}
/>
)
}
export {
ButtonGroup,
ButtonGroupSeparator,
ButtonGroupText,
buttonGroupVariants,
}
import パスをプロジェクト構成に合わせて更新します。
使い方#
import {
ButtonGroup,
ButtonGroupSeparator,
ButtonGroupText,
} from "@/components/ui/button-group"<ButtonGroup>
<Button>Button 1</Button>
<Button>Button 2</Button>
</ButtonGroup>構成#
ButtonGroup の構成:
ButtonGroup
├── Button or Input
├── ButtonGroupSeparator
└── ButtonGroupTextアクセシビリティ#
ButtonGroupコンポーネントのrole属性はgroupに設定されています。- Tab でグループ内のボタンを移動できます。
aria-labelまたはaria-labelledbyでボタングループにラベルを付けてください。
<ButtonGroup aria-label="Button group">
<Button>Button 1</Button>
<Button>Button 2</Button>
</ButtonGroup>ButtonGroup vs ToggleGroup#
- アクションを実行するボタンをグループ化する場合は
ButtonGroupを使います。 - 状態をトグルするボタンをグループ化する場合は
ToggleGroupを使います。
使用例#
Orientation#
orientation プロパティでボタングループのレイアウトを変更します。
import { MinusIcon, PlusIcon } from "lucide-react"
import { Button } from "@/components/ui/button"Size#
個別ボタンの size プロパティでボタンのサイズを制御します。
import { PlusIcon } from "lucide-react"
import { Button } from "@/components/ui/button"Nested#
<ButtonGroup> をネストして、間隔付きのボタングループを作成します。
import { AudioLinesIcon, PlusIcon } from "lucide-react"
import { Button } from "@/components/ui/button"Separator#
ButtonGroupSeparator コンポーネントはグループ内のボタンを視覚的に分割します。
outline バリアントのボタンにはボーダーがあるためセパレーターは不要です。その他のバリアントにはセパレーターを追加すると視覚的な階層が明確になります。
import { Button } from "@/components/ui/button"
import {
ButtonGroup,Split#
ButtonGroupSeparator で区切った2つのボタンでスプリットボタングループを作成します。
import { IconPlus } from "@tabler/icons-react"
import { Button } from "@/components/ui/button"Input#
ボタンと Input コンポーネントを組み合わせます。
import { SearchIcon } from "lucide-react"
import { Button } from "@/components/ui/button"Input Group#
InputGroup コンポーネントで複雑な入力レイアウトを作成します。
"use client"
import * as React from "react"Dropdown Menu#
DropdownMenu コンポーネントを使ったスプリットボタングループを作成します。
"use client"
import {Select#
Select コンポーネントと組み合わせます。
"use client"
import * as React from "react"Popover#
Popover コンポーネントと組み合わせます。
import { BotIcon, ChevronDownIcon } from "lucide-react"
import { Button } from "@/components/ui/button"RTL#
"use client"
import * as React from "react"API リファレンス#
ButtonGroup#
ButtonGroup コンポーネントは関連するボタンを一貫したスタイルでまとめるコンテナです。
| Prop | Type | Default |
|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" |
<ButtonGroup>
<Button>Button 1</Button>
<Button>Button 2</Button>
</ButtonGroup>複数のボタングループをネストして間隔付きの複雑なレイアウトを作成できます。詳細は nested の例を参照してください。
<ButtonGroup>
<ButtonGroup />
<ButtonGroup />
</ButtonGroup>ButtonGroupSeparator#
ButtonGroupSeparator コンポーネントはグループ内のボタンを視覚的に分割します。
| Prop | Type | Default |
|---|---|---|
orientation | "horizontal" | "vertical" | "vertical" |
<ButtonGroup>
<Button>Button 1</Button>
<ButtonGroupSeparator />
<Button>Button 2</Button>
</ButtonGroup>ButtonGroupText#
ボタングループ内にテキストを表示するためのコンポーネントです。
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
<ButtonGroup>
<ButtonGroupText>Text</ButtonGroupText>
<Button>Button</Button>
</ButtonGroup>asChild プロパティを使ってカスタムコンポーネント(例: label)としてレンダリングできます。
import { ButtonGroupText } from "@/components/ui/button-group"
import { Label } from "@/components/ui/label"
export function ButtonGroupTextDemo() {
return (
<ButtonGroup>
<ButtonGroupText asChild>
<Label htmlFor="name">Text</Label>
</ButtonGroupText>
<Input placeholder="Type something here..." id="name" />
</ButtonGroup>
)
}