Mention

A component used to trigger a mention (@) candidate list during text input, supporting custom trigger characters, matching modes, and rendering templates.

Component Features

  • 🛠️ Multiple Match Modes: Supports prefix matching (prefix), exact matching (exact), and fuzzy matching (fuzzy).
  • ⌨️ Multiple Trigger Characters: Allows custom single or multiple trigger characters (like @, #).
  • 🖱️ High Adaptability: Compatible with standard inputs, textareas, and content-editable elements (like rich text editors).
  • 🎨 Custom Rendering: Supports customizing the display of mention candidate list items via slots.

Basic Usage

The most basic mention display, using prefix matching mode.

<script setup lang="ts">
import { ref } from 'vue'

const text = ref('')
const users = [
  { label: '张三', value: 'zhangsan' },
  { label: '李四', value: 'lisi' },
  { label: '王五', value: 'wangwu' },
  { label: '赵六', value: 'zhaoliu' }
]

const handleSelect = (opt: any) => {
  // console.log('Selected:', opt.label)
}
</script>

<template>
  <BrMention :options="users" @select="handleSelect">
    <BrMentionTrigger>
      <BrInput v-model="text" placeholder="输入 @ 提及用户" class="w-full" />
    </BrMentionTrigger>
    <BrMentionContent />
  </BrMention>
</template>

Fuzzy Matching & Textarea

Using fuzzy matching in a textarea with a set maximum height.

<script setup lang="ts">
import { ref } from 'vue'

const text = ref('')
const projects = Array.from({ length: 30 }).map((_, i) => ({
  label: `BreezeUI 项目 ${i + 1}`,
  value: `project-${i + 1}`
}))

const handleSelect = (opt: any) => {
  // console.log('Selected:', opt.label)
}
</script>

<template>
  <BrMention 
    :options="projects" 
    match-mode="fuzzy" 
    max-height="200px" 
    @select="handleSelect"
  >
    <BrMentionTrigger>
      <BrTextarea 
        v-model="text" 
        placeholder="输入 @ 提及项目 (支持模糊搜索,如输入 '1')" 
        :rows="4" 
        class="w-full" 
      />
    </BrMentionTrigger>
    <BrMentionContent />
  </BrMention>
</template>

Custom Triggers & List Items

Supports multiple trigger characters (such as @, #) and custom list item content display.

<script setup lang="ts">
import { ref } from 'vue'

const text = ref('')
const options = [
  { label: '前端开发部', value: 'fe', description: '负责BreezeUI组件库开发', avatar: 'https://avatars.githubusercontent.com/u/137638062?s=200&v=4' },
  { label: '设计部', value: 'design', description: '负责UI/UX设计规范', avatar: 'https://avatars.githubusercontent.com/u/137638062?s=200&v=4' },
  { label: '产品部', value: 'pm', description: '需求规划', disabled: true }
]

const handleSelect = (opt: any, trigger: string) => {
  // console.log('Selected:', opt.label, 'Trigger:', trigger)
}
</script>

<template>
  <BrMention :options="options" :trigger="['@', '#']" @select="handleSelect">
    <BrMentionTrigger>
      <BrInput v-model="text" placeholder="输入 @ 或 # 触发提及" class="w-full" />
    </BrMentionTrigger>
    <BrMentionContent>
      <template #item="{ option, active }">
        <div class="flex items-center gap-3 w-full p-2">
          <div class="w-6 h-6 rounded-full overflow-hidden shrink-0">
            <img v-if="option.avatar" :src="option.avatar" :alt="option.label" class="w-full h-full object-cover" />
          </div>
          <div class="flex flex-col flex-1">
            <span :class="active ? 'text-primary font-medium' : ''">{{ option.label }}</span>
            <span class="text-xs text-muted-foreground">{{ option.description }}</span>
          </div>
          <span v-if="option.disabled" class="text-xs text-destructive ml-auto">已禁用</span>
        </div>
      </template>
    </BrMentionContent>
  </BrMention>
</template>

ContentEditable Integration

Using the mention component inside a contenteditable element, which is very common in rich text scenarios.

<script setup lang="ts">
import { ref } from 'vue'

const users = [
  { label: '张三', value: 'zhangsan' },
  { label: '李四', value: 'lisi' },
  { label: '王五', value: 'wangwu' }
]
</script>

<template>
  <BrMention :options="users">
    <BrMentionTrigger>
      <div 
        contenteditable="true" 
        class="min-h-[100px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
        placeholder="在此处输入 @ 提及用户..."
      ></div>
    </BrMentionTrigger>
    <BrMentionContent />
  </BrMention>
</template>

Theme Customization

Combined with BrConfigProvider, you can globally override the default styles of the component, such as modifying theme colors and border radius, and deeply customize the highlight style of the selected item using the highlightClass property.

<script setup lang="ts">
import { ref } from 'vue'

const text = ref('')
const users = [
  { label: '张三', value: 'zhangsan' },
  { label: '李四', value: 'lisi' },
  { label: '王五', value: 'wangwu' },
  { label: '赵六', value: 'zhaoliu' }
]

const handleSelect = (opt: any) => {
  // console.log('Selected:', opt.label)
}
</script>

<template>
  <BrConfigProvider :theme="{ primary: '280 84% 67%', radius: '1rem' }">
    <div class="p-6 border rounded-2xl bg-card shadow-sm">
      <BrMention 
        :options="users" 
        highlight-class="!bg-primary/20 !text-primary"
        @select="handleSelect"
      >
        <BrMentionTrigger>
          <BrInput v-model="text" placeholder="自定义主题色与高亮样式" class="w-full" />
        </BrMentionTrigger>
        <BrMentionContent class="shadow-xl border-primary" />
      </BrMention>
    </div>
  </BrConfigProvider>
</template>

API Reference

BrMention

PropTypeDefaultDescription
triggerstring | string[]'@'Trigger character(s)
optionsMentionOption[]-Candidate list data
matchMode'prefix' | 'exact' | 'fuzzy''prefix'Match mode
position'auto' | 'top' | 'bottom' | 'left' | 'right''auto'Candidate list pop-up direction
delaynumber0Trigger delay in ms
disabledbooleanfalseWhether the mention is disabled
loadingbooleanfalseLoading state
maxHeightstring | number-Maximum height of the candidate list
isolatedbooleanfalseWhether to enable style isolation
showEmptybooleantrueWhether to show the empty state
highlightClassstring-Custom class name for highlight style

MentionOption Data Structure

PropTypeDefaultDescription
labelstring-Text content displayed for the option
valuestring-Value of the option
disabledbooleanfalseWhether the option is disabled
descriptionstring-Additional description text
avatarstring-Avatar URL of the option
[key: string]any-Supports extending custom properties

Emits

EventParametersDescription
search(query: string, trigger: string)Triggered when search text changes
select(option: MentionOption, trigger: string)Triggered when an option is selected
open-change(open: boolean)Triggered when candidate list opens/closes

Slots

BrMentionContent

Slot NameParametersDescription
item{ option: MentionOption, active: boolean }Custom candidate list item rendering