ButtonGroup 按钮组
把几颗相关的按钮(以及输入框、选择器)拼成一整条:相邻项削掉内侧的圆角,边框叠成一条线。 用在一组互相关联的操作上 —— 翻页、「发布 | 更多选项」、搜索框 + 搜索按钮。 它只管排版与语义,不管选中态;「多选一」请用单选组或切换按钮。
相邻按钮合并圆角、边框叠成一条线。宿主默认 role="group"。
<pt-button-group>
<pt-button variant="secondary">上一页</pt-button>
<pt-button variant="secondary">第 3 页</pt-button>
<pt-button variant="secondary">下一页</pt-button>
</pt-button-group>orientation="vertical" 时每一项撑满组宽,合并的是上下相邻的圆角。
<pt-button-group orientation="vertical">
<pt-button variant="secondary">放大</pt-button>
<pt-button variant="secondary">适应画布</pt-button>
<pt-button variant="secondary">缩小</pt-button>
</pt-button-group>pt-input、pt-select 与按钮一样参与合并,高度按各自的 size 对齐。
<pt-button-group>
<pt-select value="all">
<pt-option value="all">全部</pt-option>
<pt-option value="title">标题</pt-option>
</pt-select>
<pt-input placeholder="搜索报表"></pt-input>
<pt-button variant="secondary">搜索</pt-button>
</pt-button-group>实色按钮之间用纵向 pt-separator 隔开。分隔线不参与合并,它两侧的按钮照样削掉内侧圆角。
<pt-button-group>
<pt-button>复制</pt-button>
<pt-separator orientation="vertical"></pt-separator>
<pt-button>粘贴</pt-button>
</pt-button-group>组里直接放组时,子组之间留 8px,组内仍然紧贴。外层可以换成 role="toolbar"。
<pt-button-group role="toolbar">
<pt-button-group>
<pt-button variant="secondary">加粗</pt-button>
<pt-button variant="secondary">斜体</pt-button>
</pt-button-group>
<pt-button-group>
<pt-button variant="secondary">左</pt-button>
<pt-button variant="secondary">中</pt-button>
<pt-button variant="secondary">右</pt-button>
</pt-button-group>
</pt-button-group>哪些子元素参与合并
只有直接子元素里的 pt-button、pt-input、pt-select 参与:
- 不是第一项的削掉行首两个角,不是最后一项的削掉行尾两个角(纵向时是上 / 下两个角)。 圆角用逻辑属性写,RTL 下自动翻转。
- 两个控件直接相邻时,后一个往回叠 1px,让两条边框重合成一条。中间隔着分隔线或说明文字时不叠。
- 悬停的项浮到邻居上面、聚焦的再高一层,焦点环和 hover 描边不会被邻居压住一条。
- 组里的
pt-input吃掉多出来的宽度:给组写了width时按钮保持原宽,输入框拉长。
其它子元素(pt-separator、普通元素)照常排版,不参与合并。包在 pt-tooltip 里的按钮也不参与 —— 直接子元素是 pt-tooltip,不是按钮。
必须引入全局样式表
合并规则写在 @ptengine/ui/dist/ptengine-ui/ptengine-ui.css 里,不在组件自己的影子树里: 它要从外面改子元素影子树里的边框框(::part(base)),而影子树内部写不出 ::slotted(pt-button)::part(base)(规范不允许 ::slotted() 后面再接伪元素)。 这份样式表本来就是安装时要求入口处引一次的;漏了的话按钮组退化成一排紧挨着的独立按钮。
分隔线与说明文字
源设计里的 ButtonGroupSeparator / ButtonGroupText 没有做成单独的元素:
- 分隔线:放一条
<pt-separator orientation="vertical">(纵向组里用默认的横向)。 组里的分隔线颜色默认换成输入框描边色--pt-border-input,与源设计一致。 - 说明文字:放一个普通元素,边框与圆角自己写 —— 它不参与合并,接在输入框前面时只留行首两个角:
<pt-button-group>
<span class="addon">https://</span>
<pt-input placeholder="example.com"></pt-input>
</pt-button-group>
<style>
.addon {
display: flex;
align-items: center;
padding-inline: 12px;
border: 1px solid var(--pt-border-input);
border-inline-end: 0;
border-start-start-radius: var(--pt-radius-md);
border-end-start-radius: var(--pt-radius-md);
background: var(--pt-bg-secondary);
color: var(--pt-text-weak);
}
</style>无障碍
宿主默认 role="group";自己写了 role(比如最外层是一条工具栏时写 role="toolbar")则不覆盖。 给宿主写 aria-label 告诉读屏这组按钮是干什么的,纯图标按钮各自也要有 aria-label。 按钮组本身不接管键盘:每颗按钮照常 Tab 可达。
API
属性
| 属性 | Attribute | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
orientation | orientation | "horizontal" | "vertical" | 'horizontal' | 排列方向。纵向时每一项撑满组的宽度,合并的是上下相邻的圆角 |
插槽
| 名称 | 说明 |
|---|---|
(默认) | 组里的按钮、输入框、选择器,以及分隔线、说明文字等 |