SplitButton 分裂按钮
分裂按钮把「当前操作」和「同类操作的其它选择」放在同一个胶囊里:左半段是普通的按钮,右半段带下拉箭头, 点开一个 Menu。它由 SplitButton、Menu 与 MenuItem 组合,菜单项写在默认插槽里。
基础用法
主操作:—;菜单选择:—
vue
<script setup lang="ts">
import { SplitButton, MenuItem } from "@sharpdotnut/dotsharp";
import saveIcon from "@iconify-icons/material-symbols/save";
</script>
<template>
<SplitButton label="保存" :icon="saveIcon" menu-label="更多保存方式">
<MenuItem label="另存为" value="另存为" />
<MenuItem label="保存副本" value="保存副本" />
<MenuItem label="导出为 PDF" value="导出为 PDF" />
</SplitButton>
</template>@click只来自左半段(右半段会阻止冒泡),@select携带被点菜单项的value。- 两段共享容器:底色、文字色、边框与阴影都画在根元素上,中间那条分隔线用
currentColor的 30% 透明度, 所以明暗主题与所有层级都自动适配。
层级
variant 与 Button 完全一致:elevated、filled(默认)、tonal、outlined、text。
vue
<script setup lang="ts">
import { ref } from "vue";
import { SplitButton, MenuItem } from "@sharpdotnut/dotsharp";
import editIcon from "@iconify-icons/material-symbols/edit";
const outlined = ref("—");
</script>
<template>
<SplitButton label="编辑" :icon="editIcon" menu-label="更多编辑操作" variant="filled">
<MenuItem label="重命名" value="重命名" />
</SplitButton>
<SplitButton
label="编辑"
:icon="editIcon"
menu-label="更多编辑操作"
variant="outlined"
@select="outlined = String($event)"
>
<MenuItem label="重命名" value="重命名" />
<MenuItem label="移动到…" value="移动到…" />
</SplitButton>
<SplitButton label="编辑" :icon="editIcon" menu-label="更多编辑操作" variant="text">
<MenuItem label="重命名" value="重命名" />
</SplitButton>
</template>尺寸与禁用
size 与 Button 一致(sm / md / lg)。disabled 同时禁用两段;menuDisabled 只禁用尾部分段, 主操作仍然可用。
vue
<SplitButton label="保存" size="sm" menu-label="更多保存方式">
<MenuItem label="另存为" value="另存为" />
</SplitButton>
<SplitButton label="保存" menu-label="更多保存方式" menu-disabled>
<MenuItem label="另存为" value="另存为" />
</SplitButton>
<SplitButton label="保存" menu-label="更多保存方式" disabled>
<MenuItem label="另存为" value="另存为" />
</SplitButton>菜单方向
placement 默认 bottom-end:菜单的右边缘与按钮的右边缘对齐。其它取值与 Menu 相同 (bottom-start),菜单空间不足时会自动翻到上方。
vue
<SplitButton label="保存" menu-label="更多保存方式" placement="bottom-start">
<MenuItem label="另存为" value="另存为" />
</SplitButton>API
SplitButton
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| label | string | — | 主按钮文本 |
| icon | IconifyIcon | string | — | 主按钮前置图标 |
| menuLabel | string | — | 尾部分段的无障碍名称,必填 |
| variant | "elevated" | "filled" | "tonal" | "outlined" | "text" | "filled" | 视觉层级 |
| size | "sm" | "md" | "lg" | "md" | 高度 32 / 40 / 48px |
| placement | "bottom-start" | "bottom-end" | "right-start" | "bottom-end" | 菜单相对尾部分段的展开方向 |
| disabled | boolean | false | 两段都禁用 |
| menuDisabled | boolean | false | 只禁用尾部分段 |
| type | "button" | "submit" | "reset" | "button" | 主按钮的原生类型 |
| 事件 | 载荷 | 说明 |
|---|---|---|
| select | string | number | 菜单项被选中时的标识值 |
- 默认插槽:菜单内容,通常是若干
MenuItem。 - 根元素是
div,其余属性与事件透传到该元素;class落在容器上。 - 尾部分段带
aria-haspopup="menu"与aria-expanded,↓键可直接展开菜单;Esc收起并把焦点交还尾部。
可访问性
两段都是原生 button,因此各自可 Tab 到达;焦点样式是内侧 2px 的 outline-ds-focus,不会被胶囊边界裁掉。 尾部按钮通过 aria-label(menuLabel)得到名称——它只有图标,没有可见文字。