组件
提及 Mentions
Mentions:提及建议。候选内容显示为浮动卡片。锚点是虚拟的,来自宿主输入框的实时矩形,因此宿主可以保留自己的结构(textarea 放在宿主指定的位置),卡片仍指向正确位置。检测状态通过 `useMentions` 与宿主共享。
#基础用法
The field is empty.
<script setup lang="ts">
import { Mentions } from "@bysages/vue";
import { ref } from "vue";
const text = ref("");
const teammates = [
{ label: "Lin Hua", value: "lin" },
{ label: "Mei Chen", value: "mei" },
{ label: "Hong Wei", value: "hong" },
{ label: "Yan Wu", value: "yan" },
{ label: "Zhou Lan", value: "zhou" },
];
</script>
<template>
<div class="w-full">
<Mentions
v-model="text"
:items="teammates"
placeholder="Describe the task and @who should read it…"
/>
<p role="status" class="mt-4 text-sm text-tertiary">
{{ text ? `Field holds: ${text}` : "The field is empty." }}
</p>
</div>
</template>
<script setup lang="ts">
import { Mentions } from "@bysages/vue";
import { ref } from "vue";
const text = ref("Review with #");
const reviews = [
{ label: "Design review", value: "design-review" },
{ label: "Editorial review", value: "editorial-review" },
{ label: "Civic review", value: "civic-review" },
];
</script>
<template>
<!-- A different trigger character, for systems where @ already means
something else. -->
<Mentions
v-model="text"
:items="reviews"
trigger="#"
placeholder="Tag a review…"
class="w-full"
/>
</template>
Every task needs a body before it files.
<script setup lang="ts">
import { Field, Mentions } from "@bysages/vue";
import { ref } from "vue";
const text = ref("");
const teammates = [
{ label: "Lin Hua", value: "lin" },
{ label: "Mei Chen", value: "mei" },
{ label: "Hong Wei", value: "hong" },
{ label: "Yan Wu", value: "yan" },
{ label: "Zhou Lan", value: "zhou" },
];
</script>
<template>
<!-- Inside a Field.Root the field picks up the label wiring and the
invalid state on its own. -->
<Field.Root invalid class="w-full">
<Field.Label>Describe the task</Field.Label>
<Mentions
v-model="text"
:items="teammates"
placeholder="Describe the task and @who should read it…"
/>
<Field.ErrorText>Every task needs a body before it files.</Field.ErrorText>
</Field.Root>
</template>
#属性
#MentionsVessel
Mentions:提及建议。候选内容显示为浮动卡片。锚点是虚拟的,来自宿主输入框的实时矩形,因此宿主可以保留自己的结构(textarea 放在宿主指定的位置),卡片仍指向正确位置。检测状态通过 useMentions 与宿主共享。
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
open | Boolean | false | — |
matches | Array as PropType<MentionEntry[]> | () => [] | — |
active | Number | 0 | — |
anchor | Object as PropType<HTMLTextAreaElement | null> | null | — |
size | String as PropType<"sm" | "md" | "lg"> | "md" | 宿主输入框的尺寸档位,让选项行与输入框保持一致 |
#Mentions
@ 提及组件基于普通 textarea:当插入符前的文本以触发字符和已输入片段结尾时,会在锚定容器中显示匹配候选;选择候选后,片段会替换为 trigger + label,并通过 update:modelValue 返回整段文本,方向键移动候选,Enter 插入,Escape 关闭。输入框复用 Field.Textarea,自动获得字段能力(label id、invalid 状态、autoresize);候选容器通过弹出层状态机锚定到整个字段而不是插入符坐标,因为常见字段尺寸下按插入符定位需要第二套定位系统,收益有限;保留自定义输入结构的组件(如 AI 提示输入)可不用这层外壳,直接接入 useMentions 和 MentionsVessel。
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
items | Array as PropType<MentionEntry[]> | () => [] | — |
modelValue | String | undefined | — |
trigger | String | "@" | — |
placeholder | String | undefined | — |
autoresize | Boolean | false | — |
invalid | Boolean | false | — |
size | String as PropType<"sm" | "md" | "lg"> | "md" | 输入框使用的控件高度档位 |