ButtonGroup 按钮组
将相关按钮组合在一起,保持一致的样式与间距
用法
import { ButtonGroup, Button } from '@lenso/ui';此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// Adapted from HeroUI v3.2.6 (e385ac2), Apache-2.0.import { ChevronDown, ChevronLeft, ChevronRight, CodeFork, Ellipsis, Picture, Pin, QrCode, Star, TextAlignCenter, TextAlignJustify, TextAlignLeft, TextAlignRight, ThumbsDown, ThumbsUp, Video,} from "@gravity-ui/icons";import { Button, ButtonGroup, Chip, Dropdown } from "@lenso/ui";import * as stylex from "@stylexjs/stylex";import { basicStyles as styles } from "./basic.stylex";import { styles as sourceStyles } from "./source.stylex";export function Basic() { return ( <div {...stylex.props(styles.root)}> <div {...stylex.props(styles.section)}> <ButtonGroup> <Button>Merge pull request</Button> <Dropdown> <Dropdown.Trigger render={<Button isIconOnly aria-label="More options" xstyle={styles.splitTrigger} />} > <ButtonGroup.Separator /> <Button.Icon> <ChevronDown /> </Button.Icon> </Dropdown.Trigger> <Dropdown.Portal> <Dropdown.Positioner side="bottom" align="end"> <Dropdown.Popup xstyle={styles.popup}> {[ { id: "merge", label: "Create a merge commit", description: "All commits from this branch will be added to the base branch", }, { id: "squash", label: "Squash and merge", description: "The 14 commits from this branch will be combined into one commit in the base branch", }, { id: "rebase", label: "Rebase and merge", description: "The 14 commits from this branch will be rebased and added to the base branch", }, ].map((item) => ( <Dropdown.Item key={item.id} xstyle={styles.item}> <span {...stylex.props(sourceStyles.menuLabel)}>{item.label}</span> <span {...stylex.props(sourceStyles.menuDescription)}> {item.description} </span> </Dropdown.Item> ))} </Dropdown.Popup> </Dropdown.Positioner> </Dropdown.Portal> </Dropdown> </ButtonGroup> </div> <div {...stylex.props(styles.section)}> <div {...stylex.props(styles.row)}> <ButtonGroup variant="tertiary"> <Button> <CodeFork {...stylex.props(styles.smallIcon)} /> Fork <Chip color="accent" size="sm" variant="soft"> 24 </Chip> </Button> <Button isIconOnly aria-label="More fork options"> <ButtonGroup.Separator /> <Button.Icon> <ChevronDown /> </Button.Icon> </Button> </ButtonGroup> <ButtonGroup variant="tertiary"> <Button isIconOnly aria-label="Show QR code"> <Button.Icon> <QrCode /> </Button.Icon> </Button> <Button> <ButtonGroup.Separator /> Scan to pay </Button> </ButtonGroup> <ButtonGroup variant="tertiary"> <Button> <Button.Icon> <ThumbsUp /> </Button.Icon> <span {...stylex.props(styles.count)}>2.4K</span> </Button> <Button isIconOnly aria-label="Dislike"> <ButtonGroup.Separator /> <Button.Icon> <ThumbsDown /> </Button.Icon> </Button> </ButtonGroup> <ButtonGroup variant="tertiary"> <Button> <Star {...stylex.props(styles.smallIcon)} /> Star </Button> <Button xstyle={styles.countButton}> <ButtonGroup.Separator /> <Chip color="accent" size="sm" variant="soft"> 104 </Chip> </Button> </ButtonGroup> <ButtonGroup variant="tertiary"> <Button> <Button.Icon> <Pin /> </Button.Icon> Pinned </Button> <Button isIconOnly aria-label="More pin options"> <ButtonGroup.Separator /> <Button.Icon> <ChevronDown /> </Button.Icon> </Button> </ButtonGroup> </div> </div> <div {...stylex.props(styles.section)}> <ButtonGroup variant="tertiary"> <Button> <Button.Icon> <ChevronLeft /> </Button.Icon> Previous </Button> <Button> <ButtonGroup.Separator /> Next <Button.Icon> <ChevronRight /> </Button.Icon> </Button> </ButtonGroup> </div> <div {...stylex.props(styles.section)}> <ButtonGroup variant="tertiary"> <Button> <Button.Icon> <Picture /> </Button.Icon> Photos </Button> <Button> <ButtonGroup.Separator /> <Button.Icon> <Video /> </Button.Icon> Videos </Button> <Button isIconOnly aria-label="More options"> <ButtonGroup.Separator /> <Button.Icon> <Ellipsis /> </Button.Icon> </Button> </ButtonGroup> </div> <div {...stylex.props(styles.section)}> <ButtonGroup variant="tertiary"> <Button>Left</Button> <Button> <ButtonGroup.Separator /> Center </Button> <Button> <ButtonGroup.Separator /> Right </Button> </ButtonGroup> </div> <div {...stylex.props(styles.section)}> <ButtonGroup variant="tertiary"> {[ { label: "Align left", icon: <TextAlignLeft /> }, { label: "Align center", icon: <TextAlignCenter /> }, { label: "Align right", icon: <TextAlignRight /> }, { label: "Justify", icon: <TextAlignJustify /> }, ].map((item, index) => ( <Button key={item.label} isIconOnly aria-label={item.label}> {index > 0 && <ButtonGroup.Separator />} <Button.Icon>{item.icon}</Button.Icon> </Button> ))} </ButtonGroup> </div> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
组件结构
import { ButtonGroup, Button } from '@lenso/ui';
export default () => ( <ButtonGroup> <Button>First</Button> <Button> <ButtonGroup.Separator /> Second </Button> <Button> <ButtonGroup.Separator /> Third </Button> </ButtonGroup>);ButtonGroup 将多个 Button 组合在一起,应用一致的样式、间距与自动圆角处理。它通过 React Context 向所有子按钮传递 size、variant 与 isDisabled 属性。
示例
变体
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";export { Variants } from "./source";Local adaptation source above. Derived from HeroUI v3.2.6 source.
尺寸
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";export { Sizes } from "./source";Local adaptation source above. Derived from HeroUI v3.2.6 source.
方向
使用 orientation 属性可水平或垂直排列按钮。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";export { Orientation } from "./source";Local adaptation source above. Derived from HeroUI v3.2.6 source.
带图标
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";export { WithIcons } from "./source";Local adaptation source above. Derived from HeroUI v3.2.6 source.
宽度充满
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";export { FullWidth } from "./source";Local adaptation source above. Derived from HeroUI v3.2.6 source.
禁用状态
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";export { Disabled } from "./source";Local adaptation source above. Derived from HeroUI v3.2.6 source.
无分隔线
省略按钮中的 <ButtonGroup.Separator /> 组件即可。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";export { WithoutSeparator } from "./source";Local adaptation source above. Derived from HeroUI v3.2.6 source.
自定义样式
Tailwind CSS
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";export { CustomStyles } from "./source";Local adaptation source above. Derived from HeroUI v3.2.6 source.
全局 CSS
可使用 @layer components 指令自定义 ButtonGroup 组件类。
了解更多。
@layer components { .button-group { @apply gap-2 rounded-lg; }
.button-group__separator { @apply opacity-25; }}样式参考
HeroUI 遵循 BEM 方法论,确保组件变体与状态可复用且易于自定义。
CSS 类
ButtonGroup 组件使用以下 CSS 类(查看源码样式):
基础类 [!toc]
.button-group- 按钮组根容器.button-group--full-width- 全宽修饰符.button-group__separator- 按钮之间的分隔元素
ButtonGroup 组件自动为按钮应用圆角:
- 第一个按钮圆角左/起始边
- 最后一个按钮圆角右/结束边
- 中间按钮无圆角
- 单个按钮四边全圆角
在每个 Button 内(第一个除外)添加 <ButtonGroup.Separator /> 以显示分隔线。
API 参考
ButtonGroup
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'tertiary' | 'ghost' | 'danger' | - | 应用于组内所有按钮的视觉变体 |
size | 'sm' | 'md' | 'lg' | - | 应用于组内所有按钮的尺寸 |
orientation | 'horizontal' | 'vertical' | 'horizontal' | 按钮组方向 |
fullWidth | boolean | false | 是否占满容器宽度 |
isDisabled | boolean | false | 是否禁用组内所有按钮(单个按钮可覆盖) |
className | string | - | 附加 CSS 类 |
children | React.ReactNode | - | 要组合的 Button 组件 |
ButtonGroup.Separator
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 附加 CSS 类 |
说明
- ButtonGroup 通过 React Context 向所有子 Button 传递
size、variant与isDisabled属性 - 仅直接子按钮接收 ButtonGroup 属性 - 嵌套在其他组件(如 Modal、Dropdown 等)内的 Button 即使位于 ButtonGroup 后代也不会继承组属性
- 单个 Button 可通过
isDisabled={false}覆盖组的isDisabled属性 - 组件自动处理按钮之间的圆角
- 在每个 Button 内(第一个除外)添加
<ButtonGroup.Separator />以显示分隔线 - 组内按钮移除 active/pressed 缩放变换,外观更统一