20260720172840

This commit is contained in:
oneao committed 2026-07-20 17:28:47 +08:00
1 parent cda7f16d3a
commit 94207c77ff
3117 files changed
+201407 -1236

No files matched your search

@@ -0,0 +1,52 @@
# _semantic
## Source
```vue
<script setup lang="ts">
import { computed, ref } from 'vue'
import { SemanticPreview } from '@/components/semantic'
import { useComponentLocale } from '@/composables/use-locale'
import { locales } from '../locales'
const { t } = useComponentLocale(locales)
const semantics = computed(() => [
{ name: 'root', desc: t('root'), version: '1.0.0' },
{ name: 'textarea', desc: t('textarea'), version: '1.0.0' },
{ name: 'suffix', desc: t('suffix'), version: '1.0.0' },
{ name: 'popup', desc: t('popup'), version: '1.0.0' },
])
const divRef = ref<HTMLDivElement | null>(null)
const options = [
{ value: 'afc163', label: 'afc163' },
{ value: 'zombieJ', label: 'zombieJ' },
{ value: 'thinkasany', label: 'thinkasany' },
{ value: 'meet-student', label: 'meet-student' },
]
</script>
<template>
<SemanticPreview
component-name="Mentions"
:semantics="semantics"
>
<template #default="{ classes }">
<div ref="divRef" :style="{ position: 'absolute', height: '200px' }">
<a-mentions
placement="bottom"
:style="{ width: '100%' }"
value="Hi, @"
allow-clear
open
:get-popup-container="() => divRef!"
:options="options"
:classes="classes"
/>
</div>
</template>
</SemanticPreview>
</template>
```
@@ -0,0 +1,27 @@
# With clear icon
## Description (en-US)
Customize clear button.
## Source
```vue
<script setup lang="ts">
import { CloseSquareFilled } from '@antdv-next/icons'
import { h, ref } from 'vue'
const value = ref('hello world')
const customAllowClear = {
clearIcon: h(CloseSquareFilled),
}
</script>
<template>
<a-flex vertical gap="middle">
<a-mentions v-model:value="value" allow-clear />
<a-mentions v-model:value="value" :allow-clear="customAllowClear" />
<a-mentions v-model:value="value" allow-clear :rows="3" />
</a-flex>
</template>
```
@@ -0,0 +1,101 @@
# Asynchronous loading
## Description (en-US)
async.
## Source
```vue
<script setup lang="ts">
import type { MentionsOptionProps } from 'antdv-next'
import { debounce } from 'es-toolkit'
import { computed, shallowRef } from 'vue'
interface GithubUser {
login: string
avatar_url: string
}
const loading = shallowRef(false)
const users = shallowRef<GithubUser[]>([])
let fetchId = 0
async function fetchGithubUsers(search: string): Promise<GithubUser[]> {
return fetch(`https://api.github.com/search/users?q=${search}`)
.then(res => res.json())
.then((res) => {
const items = Array.isArray(res?.items) ? res.items : []
return items.slice(0, 10)
})
}
const debounceFetcher = debounce((search: string) => {
fetchId += 1
const currentFetchId = fetchId
loading.value = true
users.value = []
fetchGithubUsers(search)
.then((items) => {
if (currentFetchId !== fetchId) {
return
}
loading.value = false
users.value = items
})
.catch(() => {
if (currentFetchId !== fetchId) {
return
}
loading.value = false
users.value = []
})
}, 800)
const options = computed<MentionsOptionProps[]>(() => {
return users.value.map(({ login, avatar_url: avatar }) => ({
key: login,
value: login,
class: 'mentions-demo-dynamic-option',
label: avatar,
}))
})
function handleSearch(search: string) {
if (!search) {
loading.value = false
users.value = []
return
}
debounceFetcher(search)
}
</script>
<template>
<a-mentions
style="width: 100%"
:loading="loading"
:options="options"
@search="handleSearch"
>
<template #labelRender="{ option }">
<img :draggable="false" :src="option.label as string" :alt="option.value">
<span>{{ option.value }}</span>
</template>
</a-mentions>
</template>
<style>
.mentions-demo-dynamic-option-content {
display: inline-flex;
align-items: center;
}
.mentions-demo-dynamic-option img {
width: 20px;
height: 20px;
margin-inline-end: 8px;
}
</style>
```
@@ -0,0 +1,32 @@
# autoSize
## Description (en-US)
Height autoSize.
## Source
```vue
<script setup lang="ts">
import type { MentionsProps } from 'antdv-next'
const options: MentionsProps['options'] = [
{
value: 'afc163',
label: 'afc163',
},
{
value: 'zombieJ',
label: 'zombieJ',
},
{
value: 'yesmeck',
label: 'yesmeck',
},
]
</script>
<template>
<a-mentions auto-size style="width: 100%" :options="options" />
</template>
```
@@ -0,0 +1,54 @@
# autoSize debug
## Description (en-US)
autoSize debug
## Source
```vue
<script setup lang="ts">
import type { MentionsEmits, MentionsProps } from 'antdv-next'
const options: MentionsProps['options'] = [
{
value: 'afc163',
label: 'afc163',
},
{
value: 'zombieJ',
label: 'zombieJ',
},
{
value: 'yesmeck',
label: 'yesmeck',
},
]
const handleChange: MentionsEmits['change'] = (value) => {
console.log('Change:', value)
}
const handleSelect: MentionsEmits['select'] = (option) => {
console.log('select', option)
}
</script>
<template>
<a-flex vertical gap="large">
<a-mentions
placeholder="can resize"
:options="options"
@change="handleChange"
@select="handleSelect"
/>
<a-mentions
placeholder="disable resize"
:options="options"
:style="{ resize: 'none' }"
@change="handleChange"
@select="handleSelect"
/>
</a-flex>
</template>
```
@@ -0,0 +1,46 @@
# Basic
## Description (en-US)
Basic usage.
## Source
```vue
<script setup lang="ts">
import type { MentionsOptionProps } from 'antdv-next'
import { ref } from 'vue'
const value = ref<string>('@afc163')
function onChange(value: string) {
console.log('Change:', value)
}
function onSelect(option: MentionsOptionProps) {
console.log('select', option)
}
</script>
<template>
<a-mentions
v-model:value="value"
style="width: 100%"
:options="[
{
value: 'afc163',
label: 'afc163',
},
{
value: 'zombieJ',
label: 'zombieJ',
},
{
value: 'yesmeck',
label: 'yesmeck',
},
]"
@change="onChange"
@select="onSelect"
/>
</template>
```
@@ -0,0 +1,89 @@
# With Form
## Description (en-US)
Controlled mode, for example, to work with `Form`.
## Source
```vue
<script setup lang="ts">
import type { FormInstance } from 'antdv-next'
import { Mentions } from 'antdv-next'
import { reactive, shallowRef } from 'vue'
const model = reactive({
coders: '',
bio: '',
})
const formRef = shallowRef<FormInstance>()
const options = [
{
value: 'afc163',
label: 'afc163',
},
{
value: 'zombieJ',
label: 'zombieJ',
},
{
value: 'yesmeck',
label: 'yesmeck',
},
]
function handleFinish(values: any) {
console.log('Submit:', values)
}
function handleFinishFailed(errorInfo: any) {
console.log('Error:', errorInfo)
}
function handleReset() {
formRef.value?.resetFields?.()
}
async function checkMention(_rule: any, value: string) {
const mentions = Mentions.getMentions(value || '')
if (mentions.length < 2) {
throw new Error('More than one must be selected!')
}
}
</script>
<template>
<a-form
ref="formRef"
:model="model"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 16 }"
@finish="handleFinish"
@finish-failed="handleFinishFailed"
>
<a-form-item name="coders" label="Top coders" :rules="[{ validator: checkMention }]">
<a-mentions v-model:value="model.coders" :rows="1" :options="options" />
</a-form-item>
<a-form-item name="bio" label="Bio" :rules="[{ required: true, message: 'Please enter your bio!' }]">
<a-mentions
v-model:value="model.bio"
:rows="3"
placeholder="You can use @ to ref user here"
:options="options"
/>
</a-form-item>
<a-form-item :label="null">
<a-space wrap>
<a-button type="primary" html-type="submit">
Submit
</a-button>
<a-button html-type="button" @click="handleReset">
Reset
</a-button>
</a-space>
</a-form-item>
</a-form>
</template>
```
@@ -0,0 +1,32 @@
# Placement
## Description (en-US)
Change the suggestions placement.
## Source
```vue
<script setup lang="ts">
import type { MentionsProps } from 'antdv-next'
const options: MentionsProps['options'] = [
{
value: 'afc163',
label: 'afc163',
},
{
value: 'zombieJ',
label: 'zombieJ',
},
{
value: 'yesmeck',
label: 'yesmeck',
},
]
</script>
<template>
<a-mentions style="width: 100%" placement="top" :options="options" />
</template>
```
@@ -0,0 +1,46 @@
# Customize Trigger Token
## Description (en-US)
Customize Trigger Token by `prefix` props. Default to `@`, `Array<string>` also supported.
## Source
```vue
<script setup lang="ts">
import type { MentionsEmits } from 'antdv-next'
import { computed, ref } from 'vue'
const mockData = {
'@': ['afc163', 'zombiej', 'yesmeck'],
'#': ['1.0', '2.0', '3.0'],
}
type PrefixType = keyof typeof mockData
const prefix = ref<PrefixType>('@')
const handleSearch: MentionsEmits['search'] = (_text, newPrefix) => {
prefix.value = (newPrefix as PrefixType) || '@'
}
const options = computed(() => {
const data = mockData[prefix.value] || []
return data.map(value => ({
key: value,
value,
label: value,
}))
})
</script>
<template>
<a-mentions
style="width: 100%"
placeholder="input @ to mention people, # to mention tag"
:prefix="['@', '#']"
:options="options"
@search="handleSearch"
/>
</template>
```
@@ -0,0 +1,36 @@
# disabled or readOnly
## Description (en-US)
Configure `disabled` and `readOnly`.
## Source
```vue
<script setup lang="ts">
import type { MentionsProps } from 'antdv-next'
const options: MentionsProps['options'] = ['afc163', 'zombiej', 'yesmeck'].map(value => ({
value,
key: value,
label: value,
}))
</script>
<template>
<a-flex vertical gap="middle">
<a-mentions
style="width: 100%"
placeholder="this is disabled Mentions"
disabled
:options="options"
/>
<a-mentions
style="width: 100%"
placeholder="this is readOnly Mentions"
readonly
:options="options"
/>
</a-flex>
</template>
```
@@ -0,0 +1,17 @@
# Size
## Description (en-US)
Configure size via `size` property.
## Source
```vue
<template>
<a-flex vertical gap="middle">
<a-mentions size="large" placeholder="large size" />
<a-mentions placeholder="default size" />
<a-mentions size="small" placeholder="small size" />
</a-flex>
</template>
```
@@ -0,0 +1,55 @@
# Status
## Description (en-US)
Add status to Mentions with `status`, which could be `error` or `warning`.
## Source
```vue
<script setup lang="ts">
import type { MentionsEmits, MentionsProps } from 'antdv-next'
const options: MentionsProps['options'] = [
{
value: 'afc163',
label: 'afc163',
},
{
value: 'zombieJ',
label: 'zombieJ',
},
{
value: 'yesmeck',
label: 'yesmeck',
},
]
const handleChange: MentionsEmits['change'] = (value) => {
console.log('Change:', value)
}
const handleSelect: MentionsEmits['select'] = (option) => {
console.log('select', option)
}
</script>
<template>
<a-flex vertical gap="middle">
<a-mentions
default-value="@afc163"
status="error"
:options="options"
@change="handleChange"
@select="handleSelect"
/>
<a-mentions
default-value="@afc163"
status="warning"
:options="options"
@change="handleChange"
@select="handleSelect"
/>
</a-flex>
</template>
```
@@ -0,0 +1,71 @@
# Custom semantic dom styling
## Description (en-US)
## Source
```vue
<script setup lang="ts">
import type { MentionsProps } from 'antdv-next'
const options: MentionsProps['options'] = [
{ value: 'afc163', label: 'afc163' },
{ value: 'zombieJ', label: 'zombieJ' },
{ value: 'meet-student', label: 'meet-student' },
{ value: 'thinkasany', label: 'thinkasany' },
]
const classes: MentionsProps['classes'] = {
root: 'mentions-demo-root',
}
const stylesObject: MentionsProps['styles'] = {
textarea: {
fontSize: '14px',
resize: 'vertical',
fontWeight: 200,
},
}
const stylesFn: MentionsProps['styles'] = ({ props }) => {
if (props.variant === 'filled') {
return {
root: {
border: '1px solid #722ed1',
},
popup: {
border: '1px solid #722ed1',
},
}
}
return {}
}
</script>
<template>
<a-flex vertical gap="middle">
<a-mentions
:options="options"
:classes="classes"
:styles="stylesObject"
placeholder="Object"
:rows="2"
/>
<a-mentions
:options="options"
:classes="classes"
:styles="stylesFn"
variant="filled"
placeholder="Function"
/>
</a-flex>
</template>
<style scoped>
:deep(.mentions-demo-root) {
border: 1px solid #1677ff;
border-radius: 8px;
width: 300px;
}
</style>
```
@@ -0,0 +1,18 @@
# Variants
## Description (en-US)
Variants of Mentions, there are four variants: `outlined` `filled` `borderless` and `underlined`.
## Source
```vue
<template>
<a-flex vertical gap="middle">
<a-mentions placeholder="Outlined" />
<a-mentions placeholder="Filled" variant="filled" />
<a-mentions placeholder="Borderless" variant="borderless" />
<a-mentions placeholder="Underlined" variant="underlined" />
</a-flex>
</template>
```
@@ -0,0 +1,67 @@
---
title: Mentions
description: Used to mention someone or something in an input.
---
## When To Use
When you need to mention someone or something.
## Demos
| Demo | Path |
| --- | --- |
| Basic | demo/basic.md |
| Size | demo/size.md |
| Variants | demo/variant.md |
| Asynchronous loading | demo/async.md |
| With Form | demo/form.md |
| Customize Trigger Token | demo/prefix.md |
| disabled or readOnly | demo/readonly.md |
| Placement | demo/placement.md |
| With clear icon | demo/allow-clear.md |
| autoSize | demo/auto-size.md |
| Status | demo/status.md |
| Custom semantic dom styling | demo/style-class.md |
| autoSize debug | demo/autosize-textarea-debug.md |
## API
Common props ref:[Common props](../../docs/vue/common-props.md)
### Props
| Property | Description | Type | Default | Version | [Global Config](../config-provider/docs.md#component-config) |
| --- | --- | --- | --- | --- | --- |
| loading | - | boolean | - | - | × |
| status | Set validation status | InputStatus | - | - | × |
| options | Option Configuration | MentionsOptionProps[] | \[] | - | × |
| popupClassName | - | string | - | - | × |
| variant | Variants of Input | Variant | `outlined` | - | ✓ |
| classes | Customize class for each semantic structure inside the component. Supports object or function. | MentionsClassNamesType | - | - | ✓ |
| styles | Customize inline style for each semantic structure inside the component. Supports object or function. | MentionsStylesType | - | - | ✓ |
| size | - | SizeType | - | - | × |
| labelRender | - | (ctx: &#123; option: MentionsOptionProps, index: number &#125;) =&gt; any | - | - | × |
| allowClear | If allow to remove mentions content with clear icon | boolean \| &#123; clearIcon?: VueNode &#125; | false | - | ✓ |
| disabled | - | boolean | - | - | × |
### Events
| Event | Description | Type | Version |
| --- | --- | --- | --- |
| focus | Trigger when mentions get focus | (event: FocusEvent) =&gt; void | - |
| blur | Trigger when mentions lose focus | (event: FocusEvent) =&gt; void | - |
| change | Trigger when value changed | (value: string) =&gt; void | - |
| select | Trigger when user select the option | (option: MentionsOptionProps, prefix: string) =&gt; void | - |
| popupScroll | Trigger when mentions scroll | (event: Event) =&gt; void | - |
| search | Trigger when prefix hit | (text: string, prefix: string) =&gt; void | - |
| update:value | - | (value: string) =&gt; void | - |
### Slots
| Slot | Description | Type | Version |
| --- | --- | --- | --- |
| suffix | - | () =&gt; any | - |
| labelRender | - | (ctx: &#123; option: MentionsOptionProps, index: number &#125;) =&gt; any | - |
## Semantic DOM
| _semantic | demo/_semantic.md |
@@ -0,0 +1,45 @@
# mentions Token
Use these variables through `theme.components.Mentions`. This document lists definitions only and does not include values.
```vue
<a-config-provider
:theme="{
token: {
// Global token configuration
},
components: {
Mentions: {
// Token name: value
},
},
}"
>
...
</a-config-provider>
```
## Token List
| Token | Type | Description |
| --- | --- | --- |
| `zIndexPopup` | `number` | z-index of popup |
| `dropdownHeight` | `string \| number` | Height of popup |
| `controlItemWidth` | `string \| number` | Height of menu item |
| `paddingInline` | `number` | Horizontal padding of input |
| `paddingInlineSM` | `number` | Horizontal padding of small input |
| `paddingInlineLG` | `number` | Horizontal padding of large input |
| `paddingBlock` | `number` | Vertical padding of input |
| `paddingBlockSM` | `number` | Vertical padding of small input |
| `paddingBlockLG` | `number` | Vertical padding of large input |
| `addonBg` | `string` | Background color of addon |
| `hoverBorderColor` | `string` | Hover border color |
| `activeBorderColor` | `string` | Active border color |
| `activeShadow` | `string` | Box-shadow when active |
| `errorActiveShadow` | `string` | Box-shadow when active in error status |
| `warningActiveShadow` | `string` | Box-shadow when active in warning status |
| `hoverBg` | `string` | Background color when the input box hovers |
| `activeBg` | `string` | Background color when the input box is activated |
| `inputFontSize` | `number` | Font size |
| `inputFontSizeLG` | `number` | Font size of large |
| `inputFontSizeSM` | `number` | Font size of small |