表单
Input Group 输入组合
用于输入组合场景的 MoriUI 组件。
资源
导入
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText } from 'moriui'组合方式
InputGroup 组合 InputGroupInput、Addon、Button 与 Text;MoriUI 当前不导出 InputGroupTextarea。
附加内容对齐
Addon align 支持 inline-start、inline-end、block-start 与 block-end;DOM 中应放在控件之后,以保持焦点导航。
自定义控件
MoriUI Textarea 等控件可作为 InputGroup 的自定义控制区,并与块级附加内容共同布局。
RTL
inline-start 和 inline-end 是逻辑方向,在 RTL 中自然翻转。
示例
概览
搜索图标、输入和结果数量共享边界。
12 个结果
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Search } from '@lucide/vue'
import { InputGroup, InputGroupAddon, InputGroupInput } from 'moriui'
const query = shallowRef('')
</script>
<template>
<InputGroup class="w-full max-w-xs">
<InputGroupInput v-model="query" aria-label="搜索" placeholder="搜索…" /><InputGroupAddon><Search /></InputGroupAddon><InputGroupAddon align="inline-end">
12 个结果
</InputGroupAddon>
</InputGroup>
</template>
行内起始
图标位于逻辑起始侧。
图标位于输入框起始侧。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Search } from '@lucide/vue'
import {
Field,
FieldDescription,
FieldLabel,
InputGroup,
InputGroupAddon,
InputGroupInput
} from 'moriui'
const query = shallowRef('')
</script>
<template>
<Field class="w-full max-w-sm">
<FieldLabel for="inline-start">
搜索
</FieldLabel><InputGroup>
<InputGroupInput id="inline-start" v-model="query" /><InputGroupAddon align="inline-start">
<Search />
</InputGroupAddon>
</InputGroup><FieldDescription>图标位于输入框起始侧。</FieldDescription>
</Field>
</template>
行内结束
操作位于逻辑结束侧。
图标位于输入框结束侧。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { EyeOff } from '@lucide/vue'
import {
Field,
FieldDescription,
FieldLabel,
InputGroup,
InputGroupAddon,
InputGroupInput
} from 'moriui'
const password = shallowRef('')
</script>
<template>
<Field class="w-full max-w-sm">
<FieldLabel for="inline-end">
密码
</FieldLabel><InputGroup>
<InputGroupInput id="inline-end" v-model="password" type="password" /><InputGroupAddon align="inline-end">
<EyeOff />
</InputGroupAddon>
</InputGroup><FieldDescription>图标位于输入框结束侧。</FieldDescription>
</Field>
</template>
块级起始
标题附加内容位于控件上方。
完整姓名
附加内容位于输入框上方。
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Field,
FieldDescription,
FieldLabel,
InputGroup,
InputGroupAddon,
InputGroupInput,
InputGroupText
} from 'moriui'
const name = shallowRef('')
</script>
<template>
<Field class="w-full max-w-sm">
<FieldLabel for="block-start">
姓名
</FieldLabel><InputGroup>
<InputGroupInput id="block-start" v-model="name" placeholder="输入姓名" /><InputGroupAddon align="block-start">
<InputGroupText>完整姓名</InputGroupText>
</InputGroupAddon>
</InputGroup><FieldDescription>附加内容位于输入框上方。</FieldDescription>
</Field>
</template>
块级结束
辅助内容位于控件下方。
人民币 CNY
附加内容位于输入框下方。
<script setup lang="ts">
import { shallowRef } from 'vue'
import {
Field,
FieldDescription,
FieldLabel,
InputGroup,
InputGroupAddon,
InputGroupInput,
InputGroupText
} from 'moriui'
const amount = shallowRef('')
</script>
<template>
<Field class="w-full max-w-sm">
<FieldLabel for="block-end">
金额
</FieldLabel><InputGroup>
<InputGroupInput id="block-end" v-model="amount" inputmode="decimal" /><InputGroupAddon align="block-end">
<InputGroupText>人民币 CNY</InputGroupText>
</InputGroupAddon>
</InputGroup><FieldDescription>附加内容位于输入框下方。</FieldDescription>
</Field>
</template>
图标
组合起始与结束图标。
<script setup lang="ts">
import { Check, CreditCard, Mail, Search } from '@lucide/vue'
import { InputGroup, InputGroupAddon, InputGroupInput } from 'moriui'
</script>
<template>
<div class="grid w-full max-w-sm gap-4">
<InputGroup><InputGroupInput aria-label="搜索" placeholder="搜索…" /><InputGroupAddon><Search /></InputGroupAddon></InputGroup><InputGroup><InputGroupInput aria-label="邮箱" type="email" placeholder="输入邮箱" /><InputGroupAddon><Mail /></InputGroupAddon></InputGroup><InputGroup>
<InputGroupInput aria-label="卡号" placeholder="卡号" /><InputGroupAddon><CreditCard /></InputGroupAddon><InputGroupAddon align="inline-end">
<Check />
</InputGroupAddon>
</InputGroup>
</div>
</template>
文字
货币、协议和单位作为附加文字。
¥
CNY
https://
<script setup lang="ts">
import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText } from 'moriui'
</script>
<template>
<div class="grid w-full max-w-sm gap-4">
<InputGroup>
<InputGroupAddon><InputGroupText>¥</InputGroupText></InputGroupAddon><InputGroupInput aria-label="金额" placeholder="0.00" /><InputGroupAddon align="inline-end">
<InputGroupText>CNY</InputGroupText>
</InputGroupAddon>
</InputGroup><InputGroup><InputGroupAddon><InputGroupText>https://</InputGroupText></InputGroupAddon><InputGroupInput aria-label="域名" placeholder="example.com" /></InputGroup>
</div>
</template>
按钮
复制、收藏等操作位于输入边界内。
<script setup lang="ts">
import { shallowRef } from 'vue'
import { Check, Copy, Star } from '@lucide/vue'
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput } from 'moriui'
const copied = shallowRef(false)
const favorite = shallowRef(false)
</script>
<template>
<div class="grid w-full max-w-sm gap-4">
<InputGroup>
<InputGroupInput model-value="https://moriui.dev" readonly /><InputGroupAddon align="inline-end">
<InputGroupButton size="icon-xs" aria-label="复制" @click="copied = true">
<Check v-if="copied" /><Copy v-else />
</InputGroupButton>
</InputGroupAddon>
</InputGroup><InputGroup>
<InputGroupInput aria-label="页面地址" /><InputGroupAddon align="inline-end">
<InputGroupButton
size="icon-xs"
:aria-pressed="favorite"
aria-label="收藏"
@click="favorite = !favorite"
>
<Star :class="{ 'fill-current': favorite }" />
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
</div>
</template>
快捷键
Kbd 提示全局搜索快捷键。
⌘K
<script setup lang="ts">
import { Search } from '@lucide/vue'
import { InputGroup, InputGroupAddon, InputGroupInput, Kbd } from 'moriui'
</script>
<template>
<InputGroup class="w-full max-w-sm">
<InputGroupInput aria-label="全局搜索" placeholder="搜索…" /><InputGroupAddon><Search /></InputGroupAddon><InputGroupAddon align="inline-end">
<Kbd>⌘K</Kbd>
</InputGroupAddon>
</InputGroup>
</template>
菜单入口
紧凑按钮提供更多选择入口。
<script setup lang="ts">
import { ChevronDown, MoreHorizontal } from '@lucide/vue'
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput
} from 'moriui'
</script>
<template>
<div class="grid w-full max-w-sm gap-4">
<InputGroup>
<InputGroupInput aria-label="文件名" placeholder="输入文件名" /><InputGroupAddon align="inline-end">
<DropdownMenu>
<DropdownMenuTrigger as-child>
<InputGroupButton size="icon-xs" aria-label="文件操作">
<MoreHorizontal />
</InputGroupButton>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>重命名</DropdownMenuItem>
<DropdownMenuItem>清空</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</InputGroupAddon>
</InputGroup><InputGroup>
<InputGroupInput aria-label="搜索词" placeholder="搜索…" /><InputGroupAddon align="inline-end">
<DropdownMenu>
<DropdownMenuTrigger as-child>
<InputGroupButton>文档<ChevronDown /></InputGroupButton>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>文档</DropdownMenuItem>
<DropdownMenuItem>代码</DropdownMenuItem>
<DropdownMenuItem>全部内容</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</InputGroupAddon>
</InputGroup>
</div>
</template>
加载状态
Spinner 与状态文字表达进行中任务。
保存中
<script setup lang="ts">
import { LoaderCircle } from '@lucide/vue'
import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, Spinner } from 'moriui'
</script>
<template>
<div class="grid w-full max-w-sm gap-4">
<InputGroup>
<InputGroupInput aria-label="搜索状态" placeholder="搜索中…" /><InputGroupAddon align="inline-end">
<Spinner />
</InputGroupAddon>
</InputGroup><InputGroup>
<InputGroupInput aria-label="保存状态" placeholder="保存更改…" /><InputGroupAddon align="inline-end">
<InputGroupText>保存中</InputGroupText><LoaderCircle class="animate-spin" />
</InputGroupAddon>
</InputGroup>
</div>
</template>
多行输入
MoriUI Textarea 与块级 Addon 组成多行编辑器。
script.js
第 1 行
<script setup lang="ts">
import { Copy, Play } from '@lucide/vue'
import { InputGroup, InputGroupAddon, InputGroupButton, InputGroupText, Textarea } from 'moriui'
</script>
<template>
<InputGroup class="w-full max-w-md">
<Textarea
data-slot="input-group-control"
class="min-h-40 resize-none"
aria-label="代码"
placeholder="console.log('你好,MoriUI')"
/><InputGroupAddon align="block-start">
<InputGroupText>script.js</InputGroupText><InputGroupButton class="ms-auto" size="icon-xs" aria-label="复制">
<Copy />
</InputGroupButton>
</InputGroupAddon><InputGroupAddon align="block-end">
<InputGroupText>第 1 行</InputGroupText><InputGroupButton class="ms-auto" variant="default">
<Play />运行
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
</template>
自定义控件
自定义自动增高 textarea 保持统一焦点处理。
<script setup lang="ts">
import { InputGroup, InputGroupAddon, InputGroupButton, Textarea } from 'moriui'
</script>
<template>
<InputGroup class="w-full max-w-sm">
<Textarea
data-slot="input-group-control"
class="field-sizing-content min-h-16 resize-none"
aria-label="自动增高文本"
placeholder="输入多行内容…"
/><InputGroupAddon align="block-end">
<InputGroupButton class="ms-auto" variant="default">
提交
</InputGroupButton>
</InputGroupAddon>
</InputGroup>
</template>
RTL
逻辑对齐在 RTL 中保持自然顺序。
١٢ نتيجة
جاري الحفظ
<script setup lang="ts">
import { Search } from '@lucide/vue'
import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, Spinner } from 'moriui'
</script>
<template>
<div dir="rtl" class="grid w-full max-w-sm gap-4">
<InputGroup>
<InputGroupInput dir="rtl" aria-label="بحث" placeholder="بحث…" /><InputGroupAddon><Search /></InputGroupAddon><InputGroupAddon align="inline-end">
١٢ نتيجة
</InputGroupAddon>
</InputGroup><InputGroup>
<InputGroupInput dir="rtl" aria-label="حالة الحفظ" placeholder="جاري حفظ التغييرات…" /><InputGroupAddon align="inline-end">
<InputGroupText>جاري الحفظ</InputGroupText><Spinner />
</InputGroupAddon>
</InputGroup>
</div>
</template>
API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| InputGroup class | HTMLAttributes["class"] | undefined | 合并到 role="group" 根容器。 |
| InputGroupAddon align | 'inline-start' | 'inline-end' | 'block-start' | 'block-end' | 'inline-start' | 附加内容的逻辑位置。 |
| InputGroupInput v-model | string | '' | 输入组合中的受控字符串值。 |
| InputGroupInput defaultValue | string | undefined | 非受控初始值。 |
| InputGroupButton variant | ButtonVariants["variant"] | 'ghost' | 内嵌按钮视觉层级。 |
| InputGroupButton size | 'xs' | 'sm' | 'icon-xs' | 'icon-sm' | 'xs' | 内嵌按钮尺寸。 |
无障碍说明
InputGroup 不替代输入标签,仍需 FieldLabel 或 aria-label。Addon 应在 DOM 中位于控件之后;点击非交互附加内容会聚焦 data-slot="input-group-control",按钮、链接等交互元素保持独立焦点。