import { Button, ButtonGroup, DropdownMenu } from "@cloudflare/kumo";
import { CaretDownIcon } from "@phosphor-icons/react";
/**
* Split button: a primary action joined with a dropdown trigger for related
* secondary actions. The caret button uses `shape="square"` and an
* `aria-label`.
*/
export function ButtonGroupSplitDemo() {
return (
<ButtonGroup aria-label="Deploy">
<Button variant="primary">Deploy</Button>
<DropdownMenu>
<DropdownMenu.Trigger
render={
<Button
variant="primary"
shape="square"
aria-label="More deploy options"
>
<CaretDownIcon />
</Button>
}
/>
<DropdownMenu.Content>
<DropdownMenu.Item>Deploy to staging</DropdownMenu.Item>
<DropdownMenu.Item>Deploy and tail logs</DropdownMenu.Item>
<DropdownMenu.Item>Schedule deploy…</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
</ButtonGroup>
);
}适用场景
ButtonGroup 将一小组紧密关联的按钮合并为一个控件——最常见的形式是拆分按钮:一个主操作按钮旁边配一个用于相关次要操作的下拉触发器。
打算把多个相互独立的按钮或输入框组合在一起?请改用
Toolbar。工具栏(例如格式栏或页面级的一组操作)需要可漫游焦点的键盘语义,而 ButtonGroup 有意不提供这一语义。
安装
批量导入
import { ButtonGroup } from "@cloudflare/kumo";按需导入
import { ButtonGroup } from "@cloudflare/kumo/components/button-group";用法
ButtonGroup 是一个布局包装器。其子元素各自保留自己的 variant、size 和 shape——分组只负责抹平内角并重叠边框,使按钮们共享一条接缝。请为分组提供用于描述该操作的 aria-label,并为下拉触发器单独提供 aria-label。
import { Button, ButtonGroup, DropdownMenu } from "@cloudflare/kumo";
import { CaretDownIcon } from "@phosphor-icons/react";
export default function Example() {
return (
<ButtonGroup aria-label="Deploy">
<Button variant="primary">Deploy</Button>
<DropdownMenu>
<DropdownMenu.Trigger
render={
<Button
variant="primary"
shape="square"
aria-label="More deploy options"
>
<CaretDownIcon />
</Button>
}
/>
<DropdownMenu.Content>
<DropdownMenu.Item>Deploy to staging</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
</ButtonGroup>
);
}示例
拆分按钮
主操作与用于次要操作的下拉触发器组合在一起。
import { Button, ButtonGroup, DropdownMenu } from "@cloudflare/kumo";
import { CaretDownIcon } from "@phosphor-icons/react";
/**
* Split button: a primary action joined with a dropdown trigger for related
* secondary actions. The caret button uses `shape="square"` and an
* `aria-label`.
*/
export function ButtonGroupSplitDemo() {
return (
<ButtonGroup aria-label="Deploy">
<Button variant="primary">Deploy</Button>
<DropdownMenu>
<DropdownMenu.Trigger
render={
<Button
variant="primary"
shape="square"
aria-label="More deploy options"
>
<CaretDownIcon />
</Button>
}
/>
<DropdownMenu.Content>
<DropdownMenu.Item>Deploy to staging</DropdownMenu.Item>
<DropdownMenu.Item>Deploy and tail logs</DropdownMenu.Item>
<DropdownMenu.Item>Schedule deploy…</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
</ButtonGroup>
);
}次要
拆分按钮适用于任意按钮变体。
import { Button, ButtonGroup, DropdownMenu } from "@cloudflare/kumo";
import { CaretDownIcon } from "@phosphor-icons/react";
/**
* Split buttons work with any button variant — here the secondary style for a
* lower-emphasis action.
*/
export function ButtonGroupSecondaryDemo() {
return (
<ButtonGroup aria-label="Save">
<Button variant="secondary">Save</Button>
<DropdownMenu>
<DropdownMenu.Trigger
render={
<Button
variant="secondary"
shape="square"
aria-label="More save options"
>
<CaretDownIcon />
</Button>
}
/>
<DropdownMenu.Content>
<DropdownMenu.Item>Save as draft</DropdownMenu.Item>
<DropdownMenu.Item>Save and publish</DropdownMenu.Item>
<DropdownMenu.Item>Save a copy…</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
</ButtonGroup>
);
}尺寸
在两个按钮上使用一致的 size,以保持拆分按钮对齐。
import { Button, ButtonGroup, DropdownMenu } from "@cloudflare/kumo";
import { CaretDownIcon } from "@phosphor-icons/react";
/**
* Match the `size` on both buttons to keep the split button aligned.
*/
export function ButtonGroupSizesDemo() {
const sizes = ["sm", "base", "lg"] as const;
return (
<div className="flex flex-wrap items-center gap-4">
{sizes.map((size) => (
<ButtonGroup key={size} aria-label="Deploy">
<Button size={size} variant="primary">
Deploy
</Button>
<DropdownMenu>
<DropdownMenu.Trigger
render={
<Button
size={size}
variant="primary"
shape="square"
aria-label="More deploy options"
>
<CaretDownIcon />
</Button>
}
/>
<DropdownMenu.Content>
<DropdownMenu.Item>Deploy to staging</DropdownMenu.Item>
<DropdownMenu.Item>Schedule deploy…</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu>
</ButtonGroup>
))}
</div>
);
}API 参考
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Additional CSS classes merged via `cn()`. Use kumo semantic tokens only. |
| id | string | - | - |
| lang | string | - | - |
| title | string | - | - |
| children | ReactNode | - | The tightly-coupled controls to join. Typically two `Button`s: a primary action and a dropdown trigger (a "split button"). |