表单

Button Group 按钮编组

用于按钮编组场景的 MoriUI 组件。

资源

导入

import { ButtonGroup, ButtonGroupSeparator, ButtonGroupText } from 'moriui'

组合方式

ButtonGroup 可组合 Button、Input、InputGroup、Separator 和 Text,并支持嵌套分组。

无障碍分组

根节点输出 role="group";调用方应通过 aria-label 或 aria-labelledby 描述整组操作。

按钮组与切换组

ButtonGroup 适合立即执行的相关动作;可保持选择状态的选项应使用 ToggleGroup。

RTL

横向组合沿逻辑方向排列,分隔线方向会根据父组 orientation 自动推导。

示例

概览

把相关消息操作组成一组。

<script setup lang="ts">
  import { Button, ButtonGroup } from 'moriui'
</script>

<template>
  <ButtonGroup aria-label="消息操作">
    <Button variant="outline">
      归档
    </Button><Button variant="outline">
      举报
    </Button><Button variant="outline">
      稍后处理
    </Button>
  </ButtonGroup>
</template>

方向

vertical 适合纵向工具条。

<script setup lang="ts">
  import { Minus, Plus } from '@lucide/vue'
  import { Button, ButtonGroup } from 'moriui'
</script>

<template>
  <ButtonGroup orientation="vertical" aria-label="缩放控制">
    <Button size="icon" variant="outline" aria-label="放大">
      <Plus />
    </Button>
    <Button size="icon" variant="outline" aria-label="缩小">
      <Minus />
    </Button>
  </ButtonGroup>
</template>

尺寸

各 Button 自己控制组内尺寸。

<script setup lang="ts">
  import { Button, ButtonGroup } from 'moriui'
</script>

<template>
  <div class="grid gap-4">
    <ButtonGroup>
      <Button size="sm" variant="outline">
        小号
      </Button><Button size="sm" variant="outline">
        组合
      </Button>
    </ButtonGroup>
    <ButtonGroup>
      <Button variant="outline">
        默认
      </Button><Button variant="outline">
        组合
      </Button>
    </ButtonGroup>
    <ButtonGroup>
      <Button size="lg" variant="outline">
        大号
      </Button><Button size="lg" variant="outline">
        组合
      </Button>
    </ButtonGroup>
  </div>
</template>

嵌套

嵌套组为复杂工具条建立间距边界。

<script setup lang="ts">
  import { Plus } from '@lucide/vue'
  import { Button, ButtonGroup, InputGroup, InputGroupInput } from 'moriui'
</script>

<template>
  <ButtonGroup>
    <ButtonGroup>
      <Button size="icon" variant="outline" aria-label="添加附件">
        <Plus />
      </Button>
    </ButtonGroup>
    <ButtonGroup><InputGroup><InputGroupInput aria-label="消息" placeholder="发送消息…" /></InputGroup></ButtonGroup>
  </ButtonGroup>
</template>

分隔线

非描边按钮之间可加入视觉分隔。

<script setup lang="ts">
  import { Button, ButtonGroup, ButtonGroupSeparator } from 'moriui'
</script>

<template>
  <ButtonGroup aria-label="剪贴板操作">
    <Button size="sm" variant="secondary">
      复制
    </Button>
    <ButtonGroupSeparator />
    <Button size="sm" variant="secondary">
      粘贴
    </Button>
  </ButtonGroup>
</template>

拆分按钮

主操作与更多选项保持相邻。

<script setup lang="ts">
  import { ChevronDown } from '@lucide/vue'
  import { Button, ButtonGroup, ButtonGroupSeparator } from 'moriui'
</script>

<template>
  <ButtonGroup aria-label="发布操作">
    <Button variant="secondary">
      发布
    </Button>
    <ButtonGroupSeparator />
    <Button size="icon" variant="secondary" aria-label="更多发布选项">
      <ChevronDown />
    </Button>
  </ButtonGroup>
</template>

输入框

将 Input 与提交按钮组合。

<script setup lang="ts">
  import { shallowRef } from 'vue'
  import { Search } from '@lucide/vue'
  import { Button, ButtonGroup, Input } from 'moriui'

  const query = shallowRef('')
</script>

<template>
  <ButtonGroup>
    <Input v-model="query" aria-label="搜索" placeholder="搜索…" />
    <Button variant="outline" aria-label="提交搜索">
      <Search />
    </Button>
  </ButtonGroup>
</template>

输入组合

嵌套 InputGroup 构建消息编辑器。

<script setup lang="ts">
  import { shallowRef } from 'vue'
  import { Mic, Plus } from '@lucide/vue'
  import {
    Button,
    ButtonGroup,
    InputGroup,
    InputGroupAddon,
    InputGroupButton,
    InputGroupInput
  } from 'moriui'

  const message = shallowRef('')
</script>

<template>
  <ButtonGroup>
    <Button size="icon" variant="outline" aria-label="添加附件">
      <Plus />
    </Button>
    <InputGroup>
      <InputGroupInput v-model="message" aria-label="消息" placeholder="发送消息…" />
      <InputGroupAddon align="inline-end">
        <InputGroupButton size="icon-xs" aria-label="语音输入">
          <Mic />
        </InputGroupButton>
      </InputGroupAddon>
    </InputGroup>
  </ButtonGroup>
</template>

下拉入口

主动作与更多选项入口组成拆分操作。

<script setup lang="ts">
  import { ChevronDown } from '@lucide/vue'
  import {
    Button,
    ButtonGroup,
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuTrigger
  } from 'moriui'
</script>

<template>
  <ButtonGroup aria-label="关注操作">
    <Button variant="outline">
      关注
    </Button>
    <DropdownMenu>
      <DropdownMenuTrigger as-child>
        <Button size="icon" variant="outline" aria-label="更多关注选项">
          <ChevronDown />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem>仅接收重要更新</DropdownMenuItem>
        <DropdownMenuItem>静音此项目</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  </ButtonGroup>
</template>

金额输入

文字前缀、输入框与确认动作共享边界。

<script setup lang="ts">
  import { shallowRef } from 'vue'
  import { ArrowRight } from '@lucide/vue'
  import {
    Button,
    ButtonGroup,
    Input,
    Select,
    SelectContent,
    SelectItem,
    SelectItemIndicator,
    SelectItemText,
    SelectTrigger,
    SelectValue,
    SelectViewport
  } from 'moriui'

  const amount = shallowRef('')
  const currency = shallowRef('CNY')
</script>

<template>
  <ButtonGroup>
    <Select v-model="currency">
      <SelectTrigger aria-label="币种" class="w-24">
        <SelectValue />
      </SelectTrigger>
      <SelectContent>
        <SelectViewport>
          <SelectItem v-for="item in ['CNY', 'USD', 'EUR']" :key="item" :value="item">
            <SelectItemIndicator /><SelectItemText>{{ item }}</SelectItemText>
          </SelectItem>
        </SelectViewport>
      </SelectContent>
    </Select>
    <Input
      v-model="amount"
      aria-label="金额"
      inputmode="decimal"
      placeholder="10.00"
    />
    <Button size="icon" variant="outline" aria-label="确认金额">
      <ArrowRight />
    </Button>
  </ButtonGroup>
</template>

助手菜单

MoriUI 尚未发布 Popover,此处以可操作的 DropdownMenu 承载助手选项。

<script setup lang="ts">
  import { Bot, ChevronDown } from '@lucide/vue'
  import {
    Button,
    ButtonGroup,
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuTrigger
  } from 'moriui'
</script>

<template>
  <ButtonGroup aria-label="智能助手">
    <Button variant="outline">
      <Bot />Copilot
    </Button>
    <DropdownMenu>
      <DropdownMenuTrigger as-child>
        <Button size="icon" variant="outline" aria-label="打开助手选项">
          <ChevronDown />
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end">
        <DropdownMenuItem>总结当前页面</DropdownMenuItem>
        <DropdownMenuItem>生成后续任务</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  </ButtonGroup>
</template>

RTL

在 RTL 文本流中保持自然顺序。

<script setup lang="ts">
  import { MoreHorizontal } from '@lucide/vue'
  import { Button, ButtonGroup } from 'moriui'
</script>

<template>
  <div dir="rtl">
    <ButtonGroup aria-label="إجراءات الرسالة">
      <Button variant="outline">
        أرشفة
      </Button>
      <Button variant="outline">
        تقرير
      </Button>
      <Button size="icon" variant="outline" aria-label="المزيد">
        <MoreHorizontal />
      </Button>
    </ButtonGroup>
  </div>
</template>

API

属性 类型 默认值 说明
ButtonGroup orientation'horizontal' | 'vertical''horizontal'分组排列方向,并写入 data-orientation。
ButtonGroup as / asChildstring | Component / boolean'div' / false根分组的元素组合能力。
ButtonGroupSeparator orientation'horizontal' | 'vertical'按父组推导分隔线方向;缺省时与父组排列方向垂直。
ButtonGroupText as / asChildstring | Component / boolean'div' / false文字槽位的语义元素。

无障碍说明

ButtonGroup 自动输出 role="group",但仍需 aria-label 或 aria-labelledby。Tab 在组内逐个访问按钮;需要单选/多选状态与方向键导航时应改用 ToggleGroup。

关联组件