Skip to content
Lenso UI

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'按钮组方向
fullWidthbooleanfalse是否占满容器宽度
isDisabledbooleanfalse是否禁用组内所有按钮(单个按钮可覆盖)
classNamestring-附加 CSS 类
childrenReact.ReactNode-要组合的 Button 组件

ButtonGroup.Separator

Prop类型默认值描述
classNamestring-附加 CSS 类

说明

  • ButtonGroup 通过 React Context 向所有子 Button 传递 size、variant 与 isDisabled 属性
  • 仅直接子按钮接收 ButtonGroup 属性 - 嵌套在其他组件(如 Modal、Dropdown 等)内的 Button 即使位于 ButtonGroup 后代也不会继承组属性
  • 单个 Button 可通过 isDisabled={false} 覆盖组的 isDisabled 属性
  • 组件自动处理按钮之间的圆角
  • 在每个 Button 内(第一个除外)添加 <ButtonGroup.Separator /> 以显示分隔线
  • 组内按钮移除 active/pressed 缩放变换,外观更统一

相关组件