20260720172840
This commit is contained in:
1 parent
cda7f16d3a
commit
94207c77ff
3117 files changed
+201407
-1236
No files matched your search
@@ -0,0 +1,86 @@
|
||||
# _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 mode = ref<'single' | 'multiple'>('single')
|
||||
|
||||
const options = [
|
||||
{ value: 'aojunhao123', label: 'aojunhao123' },
|
||||
{ value: 'thinkasany', label: 'thinkasany' },
|
||||
{ value: 'meet-student', label: 'meet-student' },
|
||||
]
|
||||
|
||||
const value = computed(() => {
|
||||
if (mode.value !== 'multiple')
|
||||
return []
|
||||
|
||||
return options.length > 0
|
||||
? [options[0]!.value]
|
||||
: []
|
||||
})
|
||||
|
||||
const { t } = useComponentLocale(locales)
|
||||
|
||||
const semantics = computed(() => {
|
||||
const base = [
|
||||
{ name: 'root', desc: t('root') },
|
||||
{ name: 'prefix', desc: t('prefix') },
|
||||
{ name: 'content', desc: t('content') },
|
||||
{ name: 'placeholder', desc: t('placeholder') },
|
||||
{ name: 'clear', desc: t('clear') },
|
||||
{ name: 'input', desc: t('input') },
|
||||
{ name: 'suffix', desc: t('suffix') },
|
||||
{ name: 'popup.root', desc: t('popup.root') },
|
||||
{ name: 'popup.list', desc: t('popup.list') },
|
||||
{ name: 'popup.listItem', desc: t('popup.listItem') },
|
||||
]
|
||||
|
||||
if (mode.value === 'multiple') {
|
||||
return [
|
||||
...base,
|
||||
{ name: 'item', desc: t('item') },
|
||||
{ name: 'itemContent', desc: t('itemContent') },
|
||||
{ name: 'itemRemove', desc: t('itemRemove') },
|
||||
]
|
||||
}
|
||||
|
||||
return base
|
||||
})
|
||||
|
||||
const divRef = ref<HTMLDivElement | null>(null)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<SemanticPreview
|
||||
component-name="Select"
|
||||
:semantics="semantics"
|
||||
>
|
||||
<template #default="{ classes }">
|
||||
<div ref="divRef" :style="{ position: 'absolute', height: '200px' }">
|
||||
<div :style="{ display: 'flex', justifyContent: 'center', marginBottom: '12px' }">
|
||||
<a-segmented v-model:value="mode" :options="['single', 'multiple']" />
|
||||
</div>
|
||||
<div :style="{ display: 'flex', flexDirection: 'column', gap: '12px' }">
|
||||
<a-select
|
||||
prefix="prefix"
|
||||
:style="{ width: '300px' }"
|
||||
:options="options"
|
||||
:value="value"
|
||||
:mode="mode === 'multiple' ? 'multiple' : undefined"
|
||||
open
|
||||
:get-popup-container="() => divRef!"
|
||||
:classes="classes"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</SemanticPreview>
|
||||
</template>
|
||||
```
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
# Automatic tokenization
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Try to copy `Lucy,Jack` and paste to the input. Only available in tags and multiple mode.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
const options = Array.from({ length: 26 }, (_, i) => {
|
||||
const value = (i + 10).toString(36) + (i + 10)
|
||||
return { value, label: value }
|
||||
})
|
||||
|
||||
function handleChange(value: string[]) {
|
||||
console.log(`selected ${value}`)
|
||||
}
|
||||
const value = ref()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
mode="tags"
|
||||
style="width: 100%"
|
||||
:token-separators="[',']"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,32 @@
|
||||
# Basic Usage
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Basic Usage.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const options = [
|
||||
{ value: 'jack', label: 'Jack' },
|
||||
{ value: 'lucy', label: 'Lucy' },
|
||||
{ value: 'Yiminghe', label: 'yiminghe' },
|
||||
{ value: 'disabled', label: 'Disabled', disabled: true },
|
||||
]
|
||||
const value1 = shallowRef('lucy')
|
||||
const value2 = shallowRef('lucy')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-space wrap>
|
||||
<div>
|
||||
{{ value1 }}
|
||||
</div>
|
||||
<a-select v-model:value="value1" style="width: 120px" :options="options" />
|
||||
<a-select v-model:value="value2" style="width: 120px" disabled :options="[{ value: 'lucy', label: 'lucy' }]" />
|
||||
</a-space>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,36 @@
|
||||
# Big Data
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Select use [virtual scroll](https://github.com/react-component/virtual-list) which get better performance, turn off it by setting `:virtual="false"`.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import type { SelectProps } from 'antdv-next'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const options: SelectProps['options'] = []
|
||||
for (let i = 0; i < 100000; i++) {
|
||||
const value = `${i.toString(36)}${i}`
|
||||
options.push({
|
||||
label: value,
|
||||
value,
|
||||
disabled: i === 10,
|
||||
})
|
||||
}
|
||||
const value = shallowRef(['a10', 'c12'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-typography-title :level="4">
|
||||
{{ options?.length }} Items
|
||||
</a-typography-title>
|
||||
<a-select v-model:value="value" mode="multiple" style="width: 100%" placeholder="Please select" :options="options" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
```
|
||||
@@ -0,0 +1,46 @@
|
||||
# Coordinate
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Coordinating the selection of provinces and cities is a common use case and demonstrates how selection can be coordinated. [Cascader](../../cascader/docs.md) component is strongly recommended in this case.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { computed, shallowRef } from 'vue'
|
||||
|
||||
const cityData: Record<string, string[]> = {
|
||||
Zhejiang: ['Hangzhou', 'Ningbo', 'Wenzhou'],
|
||||
Jiangsu: ['Nanjing', 'Suzhou', 'Zhenjiang'],
|
||||
}
|
||||
|
||||
const provinceData: string[] = ['Zhejiang', 'Jiangsu']
|
||||
|
||||
const province = shallowRef(provinceData[0]!)
|
||||
const secondCity = shallowRef(cityData[provinceData[0]!]![0])
|
||||
|
||||
const cities = computed(() => cityData[province.value] ?? [])
|
||||
|
||||
function handleProvinceChange(value: string) {
|
||||
province.value = value
|
||||
secondCity.value = cityData[value]?.[0] ?? ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-space wrap>
|
||||
<a-select
|
||||
v-model:value="province"
|
||||
style="width: 120px"
|
||||
:options="provinceData.map((p) => ({ label: p, value: p }))"
|
||||
@change="handleProvinceChange"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="secondCity"
|
||||
style="width: 120px"
|
||||
:options="cities.map((c) => ({ label: c, value: c }))"
|
||||
/>
|
||||
</a-space>
|
||||
</template>
|
||||
```
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
# Custom dropdown
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Customize the dropdown menu via `popupRender`. If you want to close the dropdown after clicking the custom content, you need to control `open` prop.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { PlusOutlined } from '@antdv-next/icons'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
let index = 0
|
||||
|
||||
const items = shallowRef(['jack', 'lucy'])
|
||||
const name = shallowRef('')
|
||||
|
||||
function addItem(e: MouseEvent) {
|
||||
e.preventDefault()
|
||||
items.value = [...items.value, name.value || `New item ${index++}`]
|
||||
name.value = ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
style="width: 300px"
|
||||
placeholder="custom dropdown render"
|
||||
:options="items.map((item) => ({ label: item, value: item }))"
|
||||
>
|
||||
<template #popupRender="menu">
|
||||
<component :is="menu" />
|
||||
<a-divider style="margin: 8px 0" />
|
||||
<a-space style="padding: 0 8px 4px">
|
||||
<a-input
|
||||
v-model:value="name"
|
||||
placeholder="Please enter item"
|
||||
@keydown.stop
|
||||
/>
|
||||
<a-button type="text" @click="addItem">
|
||||
<template #icon>
|
||||
<PlusOutlined />
|
||||
</template>
|
||||
Add item
|
||||
</a-button>
|
||||
</a-space>
|
||||
</template>
|
||||
</a-select>
|
||||
</template>
|
||||
```
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
# Custom Selected Label Render
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Allows custom rendering of the currently selected label, which can be used for value backfill but the corresponding option is missing and does not want to directly render the value.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const options = [
|
||||
{ label: 'gold', value: 'gold' },
|
||||
{ label: 'lime', value: 'lime' },
|
||||
{ label: 'green', value: 'green' },
|
||||
{ label: 'cyan', value: 'cyan' },
|
||||
]
|
||||
|
||||
const value = shallowRef('1')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
style="width: 100%"
|
||||
:options="options"
|
||||
>
|
||||
<template #labelRender="{ label, value: val }">
|
||||
<template v-if="label">
|
||||
{{ val }}
|
||||
</template>
|
||||
<span v-else>No option match</span>
|
||||
</template>
|
||||
</a-select>
|
||||
</template>
|
||||
```
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
# Custom Tag Render
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Allows for custom rendering of tags.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const options = [
|
||||
{ value: 'gold' },
|
||||
{ value: 'lime' },
|
||||
{ value: 'green' },
|
||||
{ value: 'cyan' },
|
||||
]
|
||||
|
||||
const value = shallowRef(['gold', 'cyan'])
|
||||
|
||||
function onPreventMouseDown(event: MouseEvent) {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
mode="multiple"
|
||||
style="width: 100%"
|
||||
:options="options"
|
||||
>
|
||||
<template #tagRender="{ label, value: tagValue, closable, onClose }">
|
||||
<a-tag
|
||||
:color="tagValue"
|
||||
:closable="closable"
|
||||
style="margin-inline-end: 4px"
|
||||
@mousedown="onPreventMouseDown"
|
||||
@close="onClose"
|
||||
>
|
||||
{{ label }}
|
||||
</a-tag>
|
||||
</template>
|
||||
</a-select>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
# Hide Already Selected
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Hide already selected options in the dropdown.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { computed, shallowRef } from 'vue'
|
||||
|
||||
const OPTIONS = ['Apples', 'Nails', 'Bananas', 'Helicopters']
|
||||
|
||||
const selectedItems = shallowRef<string[]>([])
|
||||
|
||||
const filteredOptions = computed(() =>
|
||||
OPTIONS.filter(o => !selectedItems.value.includes(o)).map(item => ({
|
||||
value: item,
|
||||
label: item,
|
||||
})),
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="selectedItems"
|
||||
mode="multiple"
|
||||
placeholder="Inserted are removed"
|
||||
style="width: 100%"
|
||||
:options="filteredOptions"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# Get value of selected item
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
As a default behavior, the `onChange` callback can only get the `value` of the selected item. The `labelInValue` prop can be used to get the `label` property of the selected item.
|
||||
|
||||
The `label` of the selected item will be packed as an object for passing to the `onChange` callback.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const value = shallowRef({ value: 'lucy', label: 'Lucy (101)' })
|
||||
|
||||
const options = [
|
||||
{ value: 'jack', label: 'Jack (100)' },
|
||||
{ value: 'lucy', label: 'Lucy (101)' },
|
||||
]
|
||||
|
||||
function handleChange(val: { value: string, label: string }) {
|
||||
console.log(val) // { value: "lucy", key: "lucy", label: "Lucy (101)" }
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
label-in-value
|
||||
style="width: 120px"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,46 @@
|
||||
# Max Count
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
You can set the `maxCount` prop to control the max number of items can be selected. When the limit is exceeded, the options will become disabled.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { DownOutlined } from '@antdv-next/icons'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const MAX_COUNT = 3
|
||||
|
||||
const value = shallowRef<string[]>(['Ava Swift'])
|
||||
|
||||
const options = [
|
||||
{ value: 'Ava Swift', label: 'Ava Swift' },
|
||||
{ value: 'Cole Reed', label: 'Cole Reed' },
|
||||
{ value: 'Mia Blake', label: 'Mia Blake' },
|
||||
{ value: 'Jake Stone', label: 'Jake Stone' },
|
||||
{ value: 'Lily Lane', label: 'Lily Lane' },
|
||||
{ value: 'Ryan Chase', label: 'Ryan Chase' },
|
||||
{ value: 'Zoe Fox', label: 'Zoe Fox' },
|
||||
{ value: 'Alex Grey', label: 'Alex Grey' },
|
||||
{ value: 'Elle Blair', label: 'Elle Blair' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
mode="multiple"
|
||||
:max-count="MAX_COUNT"
|
||||
style="width: 100%"
|
||||
placeholder="Please select"
|
||||
:options="options"
|
||||
>
|
||||
<template #suffixIcon>
|
||||
<span>{{ value.length }} / {{ MAX_COUNT }}</span>
|
||||
<DownOutlined />
|
||||
</template>
|
||||
</a-select>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,48 @@
|
||||
# Multiple selection
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Multiple selection, selecting from existing items.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const options = Array.from({ length: 26 }, (_, i) => {
|
||||
const value = (i + 10).toString(36) + (i + 10)
|
||||
return { label: value, value }
|
||||
})
|
||||
|
||||
const value1 = shallowRef(['a10', 'c12'])
|
||||
const value2 = shallowRef(['a10', 'c12'])
|
||||
|
||||
function handleChange(value: string[]) {
|
||||
console.log(`selected ${value}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-space style="width: 100%" vertical>
|
||||
<a-select
|
||||
v-model:value="value1"
|
||||
mode="multiple"
|
||||
allow-clear
|
||||
style="width: 100%"
|
||||
placeholder="Please select"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value2"
|
||||
mode="multiple"
|
||||
disabled
|
||||
style="width: 100%"
|
||||
placeholder="Please select"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</a-space>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,51 @@
|
||||
# Option Group
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Using `OptGroup` to group the options.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const value = shallowRef('Lucy')
|
||||
|
||||
const options = [
|
||||
{
|
||||
label: 'manager',
|
||||
title: 'manager',
|
||||
options: [
|
||||
{ label: 'Jack', value: 'Jack' },
|
||||
{ label: 'Lucy', value: 'Lucy' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'engineer',
|
||||
title: 'engineer',
|
||||
options: [
|
||||
{ label: 'Chloe', value: 'Chloe' },
|
||||
{ label: 'Lucas', value: 'Lucas' },
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
function handleChange(val: string) {
|
||||
console.log(`selected ${val}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
style="width: 200px"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
```
|
||||
@@ -0,0 +1,66 @@
|
||||
# Custom dropdown options
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Use `optionRender` to customize the rendering dropdown options.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const value = shallowRef(['china'])
|
||||
|
||||
const options = [
|
||||
{
|
||||
label: 'China',
|
||||
value: 'china',
|
||||
emoji: '🇨🇳',
|
||||
desc: 'China (中国)',
|
||||
},
|
||||
{
|
||||
label: 'USA',
|
||||
value: 'usa',
|
||||
emoji: '🇺🇸',
|
||||
desc: 'USA (美国)',
|
||||
},
|
||||
{
|
||||
label: 'Japan',
|
||||
value: 'japan',
|
||||
emoji: '🇯🇵',
|
||||
desc: 'Japan (日本)',
|
||||
},
|
||||
{
|
||||
label: 'Korea',
|
||||
value: 'korea',
|
||||
emoji: '🇰🇷',
|
||||
desc: 'Korea (韩国)',
|
||||
},
|
||||
]
|
||||
|
||||
function handleChange(val: string[]) {
|
||||
console.log(`selected ${val}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
mode="multiple"
|
||||
style="width: 100%"
|
||||
placeholder="select one country"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
>
|
||||
<template #optionRender="{ option }">
|
||||
<a-space>
|
||||
<span role="img" :aria-label="option.data.label">
|
||||
{{ option.data.emoji }}
|
||||
</span>
|
||||
{{ option.data.desc }}
|
||||
</a-space>
|
||||
</template>
|
||||
</a-select>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,50 @@
|
||||
# Placement
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
You can manually specify the position of the popup via `placement`.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
type Placement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'
|
||||
|
||||
const placement = shallowRef<Placement>('topLeft')
|
||||
const value = shallowRef('HangZhou')
|
||||
|
||||
const options = [
|
||||
{ value: 'HangZhou', label: 'HangZhou #310000' },
|
||||
{ value: 'NingBo', label: 'NingBo #315000' },
|
||||
{ value: 'WenZhou', label: 'WenZhou #325000' },
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-radio-group v-model:value="placement">
|
||||
<a-radio-button value="topLeft">
|
||||
topLeft
|
||||
</a-radio-button>
|
||||
<a-radio-button value="topRight">
|
||||
topRight
|
||||
</a-radio-button>
|
||||
<a-radio-button value="bottomLeft">
|
||||
bottomLeft
|
||||
</a-radio-button>
|
||||
<a-radio-button value="bottomRight">
|
||||
bottomRight
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
<br>
|
||||
<br>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
style="width: 120px"
|
||||
:popup-match-select-width="false"
|
||||
:placement="placement"
|
||||
:options="options"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,59 @@
|
||||
# Responsive maxTagCount
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Auto collapse to tag with responsive case. Not recommend use in large form case since responsive calculation has a perf cost.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const options = Array.from({ length: 26 }, (_, i) => {
|
||||
const value = (i + 10).toString(36) + (i + 10)
|
||||
return { label: `Long Label: ${value}`, value }
|
||||
})
|
||||
|
||||
const value = shallowRef(['a10', 'c12', 'h17', 'j19', 'k20'])
|
||||
const value1 = shallowRef(['a10', 'c12', 'h17', 'j19'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-space vertical style="width: 100%">
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
mode="multiple"
|
||||
style="width: 100%"
|
||||
:options="options"
|
||||
placeholder="Select Item..."
|
||||
max-tag-count="responsive"
|
||||
/>
|
||||
<a-select
|
||||
mode="multiple"
|
||||
style="width: 100%"
|
||||
disabled
|
||||
:options="options"
|
||||
placeholder="Select Item..."
|
||||
max-tag-count="responsive"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value1"
|
||||
mode="multiple"
|
||||
style="width: 100%"
|
||||
:options="options"
|
||||
placeholder="Select Item..."
|
||||
max-tag-count="responsive"
|
||||
>
|
||||
<template #maxTagPlaceholder="omittedValues">
|
||||
<a-tooltip>
|
||||
<template #title>
|
||||
{{ omittedValues.map((v: any) => v.label).join(', ') }}
|
||||
</template>
|
||||
<span>Hover Me</span>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
</a-select>
|
||||
</a-space>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,76 @@
|
||||
# Search Box
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Search with remote data.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
interface OptionItem {
|
||||
value: string
|
||||
label: string
|
||||
}
|
||||
|
||||
let timeout: ReturnType<typeof setTimeout> | null = null
|
||||
let currentValue = ''
|
||||
|
||||
const data = shallowRef<OptionItem[]>([])
|
||||
const value = shallowRef<string>()
|
||||
|
||||
function fetchData(val: string, callback: (data: OptionItem[]) => void) {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout)
|
||||
timeout = null
|
||||
}
|
||||
currentValue = val
|
||||
|
||||
const params = new URLSearchParams({ code: 'utf-8', q: val })
|
||||
|
||||
const fake = () => {
|
||||
fetch(`https://suggest.taobao.com/sug?${params.toString()}`)
|
||||
.then(response => response.json())
|
||||
.then(({ result }) => {
|
||||
if (currentValue === val) {
|
||||
const options = result.map((item: string[]) => ({
|
||||
value: item[0],
|
||||
label: item[0],
|
||||
}))
|
||||
callback(options)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (val) {
|
||||
timeout = setTimeout(fake, 300)
|
||||
}
|
||||
else {
|
||||
callback([])
|
||||
}
|
||||
}
|
||||
|
||||
function handleSearch(val: string) {
|
||||
fetchData(val, (options) => {
|
||||
data.value = options
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
show-search
|
||||
:filter-option="false"
|
||||
placeholder="input search text"
|
||||
style="width: 200px"
|
||||
:default-active-first-option="false"
|
||||
:suffix-icon="null"
|
||||
:not-found-content="null"
|
||||
:options="data"
|
||||
@search="handleSearch"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
# Custom Search
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Customize search using `filterOption`.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const value = shallowRef<string>()
|
||||
|
||||
const options = [
|
||||
{ value: '1', label: 'Jack' },
|
||||
{ value: '2', label: 'Lucy' },
|
||||
{ value: '3', label: 'Tom' },
|
||||
]
|
||||
|
||||
function filterOption(input: string, option: { label?: string }) {
|
||||
return (option?.label ?? '').toLowerCase().includes(input.toLowerCase())
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
show-search
|
||||
:filter-option="filterOption"
|
||||
placeholder="Select a person"
|
||||
:options="options"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,40 @@
|
||||
# Search with sort
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Search the options with sorting.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const value = shallowRef<string>()
|
||||
|
||||
const options = [
|
||||
{ value: '1', label: 'Not Identified' },
|
||||
{ value: '2', label: 'Closed' },
|
||||
{ value: '3', label: 'Communicated' },
|
||||
{ value: '4', label: 'Identified' },
|
||||
{ value: '5', label: 'Resolved' },
|
||||
{ value: '6', label: 'Cancelled' },
|
||||
]
|
||||
|
||||
function filterSort(optionA: { label?: string }, optionB: { label?: string }) {
|
||||
return (optionA?.label ?? '').toLowerCase().localeCompare((optionB?.label ?? '').toLowerCase())
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
show-search
|
||||
option-filter-prop="label"
|
||||
:filter-sort="filterSort"
|
||||
style="width: 200px"
|
||||
placeholder="Search to Select"
|
||||
:options="options"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,84 @@
|
||||
# Search and Select Users
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
A complete multiple select sample with remote search, debounce fetch, ajax callback order flow, and loading state.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { debounce } from 'es-toolkit'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
interface UserValue {
|
||||
label: string
|
||||
value: string
|
||||
avatar?: string
|
||||
}
|
||||
|
||||
const value = shallowRef<UserValue[]>([])
|
||||
const options = shallowRef<UserValue[]>([])
|
||||
const fetching = shallowRef(false)
|
||||
|
||||
let fetchId = 0
|
||||
|
||||
async function fetchUserList(username: string): Promise<UserValue[]> {
|
||||
console.log('fetching user', username)
|
||||
return fetch(`https://660d2bd96ddfa2943b33731c.mockapi.io/api/users/?search=${username}`)
|
||||
.then(res => res.json())
|
||||
.then((res) => {
|
||||
const results = Array.isArray(res) ? res : []
|
||||
return results.map((user: { name: string, id: string, avatar: string }) => ({
|
||||
label: user.name,
|
||||
value: user.id,
|
||||
avatar: user.avatar,
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
const debounceFetcher = debounce((val: string) => {
|
||||
fetchId += 1
|
||||
const currentFetchId = fetchId
|
||||
options.value = []
|
||||
fetching.value = true
|
||||
|
||||
fetchUserList(val).then((newOptions) => {
|
||||
if (currentFetchId !== fetchId) {
|
||||
return
|
||||
}
|
||||
options.value = newOptions
|
||||
fetching.value = false
|
||||
})
|
||||
}, 300)
|
||||
|
||||
function handleSearch(val: string) {
|
||||
debounceFetcher(val)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
mode="multiple"
|
||||
label-in-value
|
||||
show-search
|
||||
:filter-option="false"
|
||||
placeholder="Select users"
|
||||
style="width: 100%"
|
||||
:options="options"
|
||||
@search="handleSearch"
|
||||
>
|
||||
<template #notFoundContent>
|
||||
<a-spin v-if="fetching" size="small" />
|
||||
<span v-else>No results found</span>
|
||||
</template>
|
||||
<template #optionRender="{ option }">
|
||||
<div style="display: flex; align-items: center">
|
||||
<a-avatar v-if="option.data.avatar" :src="option.data.avatar" style="margin-right: 8px" />
|
||||
{{ option.data.label }}
|
||||
</div>
|
||||
</template>
|
||||
</a-select>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,41 @@
|
||||
# Select with search field
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Search the options while expanded.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const value = shallowRef<string>()
|
||||
|
||||
const options = [
|
||||
{ value: 'jack', label: 'Jack' },
|
||||
{ value: 'lucy', label: 'Lucy' },
|
||||
{ value: 'tom', label: 'Tom' },
|
||||
]
|
||||
|
||||
function onChange(val: string) {
|
||||
console.log(`selected ${val}`)
|
||||
}
|
||||
|
||||
function onSearch(val: string) {
|
||||
console.log('search:', val)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
show-search
|
||||
option-filter-prop="label"
|
||||
placeholder="Select a person"
|
||||
:options="options"
|
||||
@change="onChange"
|
||||
@search="onSearch"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,72 @@
|
||||
# Sizes
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
The height of the input field for the select defaults to 32px. If size is set to large, the height will be 40px, and if set to small, 24px.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
type SizeType = 'large' | 'middle' | 'small'
|
||||
|
||||
const options = Array.from({ length: 26 }, (_, i) => {
|
||||
const value = (i + 10).toString(36) + (i + 10)
|
||||
return { value, label: value }
|
||||
})
|
||||
|
||||
const size = shallowRef<SizeType>('middle')
|
||||
const value1 = shallowRef('a10')
|
||||
const value2 = shallowRef(['a10', 'c12'])
|
||||
const value3 = shallowRef(['a10', 'c12'])
|
||||
|
||||
function handleChange(val: string | string[]) {
|
||||
console.log(`Selected: ${val}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-radio-group v-model:value="size">
|
||||
<a-radio-button value="large">
|
||||
Large
|
||||
</a-radio-button>
|
||||
<a-radio-button value="middle">
|
||||
Default
|
||||
</a-radio-button>
|
||||
<a-radio-button value="small">
|
||||
Small
|
||||
</a-radio-button>
|
||||
</a-radio-group>
|
||||
<br>
|
||||
<br>
|
||||
<a-space vertical style="width: 100%">
|
||||
<a-select
|
||||
v-model:value="value1"
|
||||
:size="size"
|
||||
style="width: 200px"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value2"
|
||||
mode="multiple"
|
||||
:size="size"
|
||||
placeholder="Please select"
|
||||
style="width: 100%"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value3"
|
||||
mode="tags"
|
||||
:size="size"
|
||||
placeholder="Please select"
|
||||
style="width: 100%"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</a-space>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,19 @@
|
||||
# Status
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Add status to Select with `status`, which could be `error` or `warning`.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-space vertical style="width: 100%">
|
||||
<a-select status="error" style="width: 100%" />
|
||||
<a-select status="warning" style="width: 100%" />
|
||||
</a-space>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,74 @@
|
||||
# Custom semantic dom styling
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
You can customize the semantic dom style of Select by passing objects/functions through `classes` and `styles`.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { MehOutlined } from '@antdv-next/icons'
|
||||
|
||||
const options = [
|
||||
{ value: 'GuangZhou', label: 'GuangZhou' },
|
||||
{ value: 'ShenZhen', label: 'ShenZhen' },
|
||||
]
|
||||
|
||||
const stylesObject = {
|
||||
prefix: {
|
||||
color: '#1890ff',
|
||||
},
|
||||
suffix: {
|
||||
color: '#1890ff',
|
||||
},
|
||||
}
|
||||
|
||||
const stylesFilled = {
|
||||
prefix: {
|
||||
color: '#722ed1',
|
||||
},
|
||||
suffix: {
|
||||
color: '#722ed1',
|
||||
},
|
||||
popup: {
|
||||
root: {
|
||||
border: '1px solid #722ed1',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-flex vertical gap="middle">
|
||||
<a-select
|
||||
:options="options"
|
||||
:classes="{ root: 'custom-select' }"
|
||||
:styles="stylesObject"
|
||||
placeholder="Object"
|
||||
>
|
||||
<template #prefix>
|
||||
<MehOutlined />
|
||||
</template>
|
||||
</a-select>
|
||||
<a-select
|
||||
:options="options"
|
||||
:classes="{ root: 'custom-select' }"
|
||||
:styles="stylesFilled"
|
||||
placeholder="Function"
|
||||
variant="filled"
|
||||
>
|
||||
<template #prefix>
|
||||
<MehOutlined />
|
||||
</template>
|
||||
</a-select>
|
||||
</a-flex>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.custom-select {
|
||||
border-radius: 8px;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
@@ -0,0 +1,103 @@
|
||||
# Prefix and Suffix
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Custom `prefix` and `suffixIcon`.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { MehOutlined, SmileOutlined } from '@antdv-next/icons'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const options = [
|
||||
{ value: 'jack', label: 'Jack' },
|
||||
{ value: 'lucy', label: 'Lucy' },
|
||||
{ value: 'Yiminghe', label: 'yiminghe' },
|
||||
{ value: 'disabled', label: 'Disabled', disabled: true },
|
||||
]
|
||||
|
||||
const value1 = shallowRef('lucy')
|
||||
const value2 = shallowRef('lucy')
|
||||
const value3 = shallowRef('lucy')
|
||||
const value4 = shallowRef(['lucy'])
|
||||
const value5 = shallowRef(['lucy'])
|
||||
const value6 = shallowRef(['lucy'])
|
||||
|
||||
function handleChange(val: string | string[]) {
|
||||
console.log(`selected ${val}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-space wrap>
|
||||
<a-select
|
||||
v-model:value="value1"
|
||||
prefix="User"
|
||||
placeholder="Select User"
|
||||
style="width: 200px"
|
||||
:options="options"
|
||||
allow-clear
|
||||
show-search
|
||||
@change="handleChange"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value2"
|
||||
placeholder="Select"
|
||||
style="width: 120px"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
>
|
||||
<template #suffixIcon>
|
||||
<SmileOutlined />
|
||||
</template>
|
||||
</a-select>
|
||||
<a-select
|
||||
v-model:value="value3"
|
||||
placeholder="Select"
|
||||
style="width: 120px"
|
||||
disabled
|
||||
:options="[{ value: 'lucy', label: 'Lucy' }]"
|
||||
>
|
||||
<template #suffixIcon>
|
||||
<MehOutlined />
|
||||
</template>
|
||||
</a-select>
|
||||
<br>
|
||||
<a-select
|
||||
v-model:value="value4"
|
||||
prefix="User"
|
||||
placeholder="Select"
|
||||
mode="multiple"
|
||||
style="width: 200px"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value5"
|
||||
placeholder="Select"
|
||||
mode="multiple"
|
||||
style="width: 120px"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
>
|
||||
<template #suffixIcon>
|
||||
<SmileOutlined />
|
||||
</template>
|
||||
</a-select>
|
||||
<a-select
|
||||
v-model:value="value6"
|
||||
placeholder="Select"
|
||||
mode="multiple"
|
||||
style="width: 120px"
|
||||
disabled
|
||||
:options="[{ value: 'lucy', label: 'Lucy' }]"
|
||||
>
|
||||
<template #suffixIcon>
|
||||
<MehOutlined />
|
||||
</template>
|
||||
</a-select>
|
||||
</a-space>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
# Tags
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Allow user to select tags from list or input custom tag.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const options = Array.from({ length: 26 }, (_, i) => {
|
||||
const value = (i + 10).toString(36) + (i + 10)
|
||||
return { value, label: value }
|
||||
})
|
||||
|
||||
const value = shallowRef<string[]>([])
|
||||
|
||||
function handleChange(val: string[]) {
|
||||
console.log(`selected ${val}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-select
|
||||
v-model:value="value"
|
||||
mode="tags"
|
||||
style="width: 100%"
|
||||
placeholder="Tags Mode"
|
||||
:options="options"
|
||||
@change="handleChange"
|
||||
/>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,99 @@
|
||||
# Variants
|
||||
|
||||
## Description (en-US)
|
||||
|
||||
Variants of Select, there are four variants: `outlined` `filled` `borderless` and `underlined`.
|
||||
|
||||
## Source
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
const options = [
|
||||
{ value: 'jack', label: 'Jack' },
|
||||
{ value: 'lucy', label: 'Lucy' },
|
||||
{ value: 'Yiminghe', label: 'yiminghe' },
|
||||
]
|
||||
|
||||
const value1 = shallowRef<string>()
|
||||
const value2 = shallowRef(['lucy'])
|
||||
const value3 = shallowRef<string>()
|
||||
const value4 = shallowRef(['lucy'])
|
||||
const value5 = shallowRef<string>()
|
||||
const value6 = shallowRef(['lucy'])
|
||||
const value7 = shallowRef<string>()
|
||||
const value8 = shallowRef(['lucy'])
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<a-flex :gap="12" vertical>
|
||||
<a-flex :gap="8">
|
||||
<a-select
|
||||
v-model:value="value1"
|
||||
placeholder="Outlined"
|
||||
style="flex: 1"
|
||||
:options="options"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value2"
|
||||
mode="multiple"
|
||||
placeholder="Outlined"
|
||||
style="flex: 1"
|
||||
:options="options"
|
||||
/>
|
||||
</a-flex>
|
||||
<a-flex :gap="8">
|
||||
<a-select
|
||||
v-model:value="value3"
|
||||
placeholder="Filled"
|
||||
variant="filled"
|
||||
style="flex: 1"
|
||||
:options="options"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value4"
|
||||
mode="multiple"
|
||||
placeholder="Filled"
|
||||
variant="filled"
|
||||
style="flex: 1"
|
||||
:options="options"
|
||||
/>
|
||||
</a-flex>
|
||||
<a-flex :gap="8">
|
||||
<a-select
|
||||
v-model:value="value5"
|
||||
placeholder="Borderless"
|
||||
variant="borderless"
|
||||
style="flex: 1"
|
||||
:options="options"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value6"
|
||||
mode="multiple"
|
||||
placeholder="Borderless"
|
||||
variant="borderless"
|
||||
style="flex: 1"
|
||||
:options="options"
|
||||
/>
|
||||
</a-flex>
|
||||
<a-flex :gap="8">
|
||||
<a-select
|
||||
v-model:value="value7"
|
||||
placeholder="Underlined"
|
||||
variant="underlined"
|
||||
style="flex: 1"
|
||||
:options="options"
|
||||
/>
|
||||
<a-select
|
||||
v-model:value="value8"
|
||||
mode="multiple"
|
||||
placeholder="Underlined"
|
||||
variant="underlined"
|
||||
style="flex: 1"
|
||||
:options="options"
|
||||
/>
|
||||
</a-flex>
|
||||
</a-flex>
|
||||
</template>
|
||||
```
|
||||
@@ -0,0 +1,220 @@
|
||||
---
|
||||
title: Select
|
||||
description: A dropdown menu for displaying choices.
|
||||
---
|
||||
|
||||
## When To Use
|
||||
- A dropdown menu for displaying choices - an elegant alternative to the native `<select>` element.
|
||||
- Utilizing [Radio](../radio/docs.md) is recommended when there are fewer total options (less than 5).
|
||||
- You probably need [AutoComplete](../auto-complete/docs.md) if you're looking for an input box that can be typed or selected.
|
||||
|
||||
## Demos
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
|
||||
| Demo | Path |
|
||||
| --- | --- |
|
||||
| Basic Usage | demo/basic.md |
|
||||
| Select with search field | demo/search.md |
|
||||
| Custom Search | demo/search-filter-option.md |
|
||||
| Multiple selection | demo/multiple.md |
|
||||
| Sizes | demo/size.md |
|
||||
| Custom dropdown options | demo/option-render.md |
|
||||
| Search with sort | demo/search-sorts.md |
|
||||
| Tags | demo/tags.md |
|
||||
| Option Group | demo/optgroup.md |
|
||||
| Coordinate | demo/coordinate.md |
|
||||
| Search Box | demo/search-box.md |
|
||||
| Get value of selected item | demo/label-in-value.md |
|
||||
| Automatic tokenization | demo/automatic-tokenization.md |
|
||||
| Search and Select Users | demo/search-users.md |
|
||||
| Prefix and Suffix | demo/suffix.md |
|
||||
| Custom dropdown | demo/custom-dropdown-menu.md |
|
||||
| Hide Already Selected | demo/hide-selected.md |
|
||||
| Variants | demo/variant.md |
|
||||
| Custom Tag Render | demo/custom-tag-render.md |
|
||||
| Custom Selected Label Render | demo/custom-label-render.md |
|
||||
| Responsive maxTagCount | demo/responsive.md |
|
||||
| Big Data | demo/big-data.md |
|
||||
| Status | demo/status.md |
|
||||
| Placement | demo/placement.md |
|
||||
| Max Count | demo/maxCount.md |
|
||||
| Custom semantic dom styling | demo/style-class.md |
|
||||
|
||||
## API
|
||||
|
||||
### Property
|
||||
Common props ref:[Common props](../../docs/vue/common-props.md)
|
||||
|
||||
| Property | Description | Type | Default | Version | [Global Config](../config-provider/docs.md#component-config) |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| allowClear | Show clear button | boolean \| { clearIcon?: VueNode } | false | - | ✓ |
|
||||
| autoClearSearchValue | Whether the current search will be cleared on selecting an item. Only applies when `mode` is set to `multiple` or `tags` | boolean | true | - | × |
|
||||
| defaultActiveFirstOption | Whether active first option by default | boolean | true | - | × |
|
||||
| disabled | Whether disabled select | boolean | false | - | × |
|
||||
| dropdownClassName | The className of dropdown menu, **Deprecated. Use `classes.popup.root` instead** | string | - | - | × |
|
||||
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width, **Deprecated. Use `popupMatchSelectWidth` instead** | boolean \| number | - | - | × |
|
||||
| dropdownRender | Customize dropdown content, **Deprecated. Use `popupRender` instead** | (originNode: VueNode) => VueNode | - | - | × |
|
||||
| dropdownStyle | The style of dropdown menu, **Deprecated. Use `styles.popup.root` instead** | CSSProperties | - | - | × |
|
||||
| fieldNames | Customize node label, value, options, groupLabel field name | object | { label: 'label', value: 'value', options: 'options', groupLabel: 'label' } | - | × |
|
||||
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded | boolean \| (inputValue: string, option?: Option) => boolean | true | - | × |
|
||||
| filterSort | Sort function for search options sorting, see Array.sort's compareFunction | (optionA: Option, optionB: Option, info: { searchValue: string }) => number | - | - | × |
|
||||
| getPopupContainer | Parent Node which the selector should be rendered to. Default to body. When position issues happen, try to modify it into scrollable content and position it relative | (triggerNode: HTMLElement) => HTMLElement | () => document.body | - | × |
|
||||
| labelInValue | Whether to embed label in value, turn the format of value from `string` to `{ value: string, label: VueNode }` | boolean | false | - | × |
|
||||
| listHeight | Config popup height | number | 256 | - | × |
|
||||
| loading | Indicate loading state | boolean | false | - | × |
|
||||
| maxCount | The max number of items can be selected, only applies when `mode` is `multiple` or `tags` | number | - | - | × |
|
||||
| maxTagCount | Max tag count to show. `responsive` will cost render performance | number \| 'responsive' | - | - | × |
|
||||
| maxTagPlaceholder | Placeholder for not showing tags | VueNode \| (omittedValues: LabeledValue[]) => VueNode | - | - | × |
|
||||
| maxTagTextLength | Max tag text length to show | number | - | - | × |
|
||||
| menuItemSelectedIcon | The custom menuItemSelected icon with multiple options | VueNode | - | - | ✓ |
|
||||
| mode | Set mode of Select | 'multiple' \| 'tags' | - | - | × |
|
||||
| notFoundContent | Specify content to show when no result matches | VueNode | `Not Found` | - | × |
|
||||
| open | Controlled open state of dropdown | boolean | - | - | × |
|
||||
| optionFilterProp | Which prop value of option will be used for filter if filterOption is true. If options is set, it should be set to label. When a string[] is provided, multiple fields are searched using OR matching | string \| string[] | value | - | × |
|
||||
| options | Select options. Will get better perf than jsx definition | { label: VueNode; value: string }[] | - | - | × |
|
||||
| optionRender | Customize the rendering dropdown options | (option: FlattenOptionData<BaseOptionType>, info: { index: number }) => VueNode | - | - | × |
|
||||
| placeholder | The placeholder of select | string | - | - | × |
|
||||
| placement | The position where the selection box pops up | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | - | × |
|
||||
| popupClassName | The className of dropdown menu, use `classes.popup.root` instead | string | - | - | × |
|
||||
| popupMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | - | × |
|
||||
| popupRender | Customize dropdown content | (originNode: VueNode) => VueNode | - | - | × |
|
||||
| prefix | The custom prefix | VueNode | - | - | × |
|
||||
| removeIcon | The custom remove icon | VueNode | - | - | ✓ |
|
||||
| searchValue | The current input "search" text | string | - | - | × |
|
||||
| showSearch | Whether select is searchable | boolean \| Object | single: false, multiple: true | - | ✓ |
|
||||
| size | Size of Select input | `large` \| `middle` \| `small` | - | - | × |
|
||||
| status | Set validation status | 'error' \| 'warning' | - | - | × |
|
||||
| suffixIcon | The custom suffix icon. Customize icon will not response click open to avoid icon designed to do other interactive. You can use `pointer-events: none` style to bypass | VueNode | `<DownOutlined />` | - | ✓ |
|
||||
| tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | (props) => VueNode | - | - | × |
|
||||
| labelRender | Customize selected label render | (props: LabelInValueType) => VueNode | - | - | × |
|
||||
| tokenSeparators | Separator used to tokenize, only applies when `mode="tags"` | string[] | - | - | × |
|
||||
| value | Current selected option (considered as a immutable array), support `v-model:value` | string \| string[] \| number \| number[] | - | - | × |
|
||||
| variant | Variants of selector | `outlined` \| `borderless` \| `filled` \| `underlined` | `outlined` | - | ✓ |
|
||||
| virtual | Disable virtual scroll when set to false | boolean | true | - | × |
|
||||
|
||||
### Events
|
||||
| Event | Description | Type | Version |
|
||||
| --- | --- | --- | --- |
|
||||
| active | Called when keyboard or mouse interaction occurs | (value: string \| number) => void | - |
|
||||
| blur | Called when blur | (event: FocusEvent) => void | - |
|
||||
| change | Called when select an option or input value change | (value, option: Option \| Array<Option>) => void | - |
|
||||
| clear | Called when clear | () => void | - |
|
||||
| deselect | Called when an option is deselected, param is the selected option's value. Only called for `multiple` or `tags`, effective in multiple or tags mode only | (value: string \| number) => void | - |
|
||||
| dropdownVisibleChange | Called when dropdown open, **Deprecated. Use `openChange` instead** | (open: boolean) => void | - |
|
||||
| focus | Called when focus | (event: FocusEvent) => void | - |
|
||||
| inputKeydown | Called when key pressed | (event: KeyboardEvent) => void | - |
|
||||
| openChange | Called when dropdown open | (open: boolean) => void | - |
|
||||
| popupScroll | Called when dropdown scrolls | (event: UIEvent) => void | - |
|
||||
| search | Callback function that is fired when input changed | (value: string) => void | - |
|
||||
| select | Called when an option is selected, the params are option's value (or key) and option instance | (value: string \| number, option: Option) => void | - |
|
||||
|
||||
### Slots
|
||||
| Slot | Description | Type | Version |
|
||||
| --- | --- | --- | --- |
|
||||
| labelRender | Customize selected label render | (props: LabelInValueType) => VueNode | - |
|
||||
| maxTagPlaceholder | Placeholder for not showing tags | (omittedValues: LabeledValue[]) => VueNode | - |
|
||||
| menuItemSelectedIcon | The custom menuItemSelected icon with multiple options | VueNode | - |
|
||||
| notFoundContent | Specify content to show when no result matches | VueNode | - |
|
||||
| optionRender | Customize the rendering dropdown options | (option: FlattenOptionData<BaseOptionType>, info: { index: number }) => VueNode | - |
|
||||
| popupRender | Customize dropdown content | (originNode: VueNode) => VueNode | - |
|
||||
| prefix | The custom prefix | VueNode | - |
|
||||
| removeIcon | The custom remove icon | VueNode | - |
|
||||
| suffixIcon | The custom suffix icon. Customize icon will not response click open to avoid icon designed to do other interactive. You can use `pointer-events: none` style to bypass | VueNode | - |
|
||||
| tagRender | Customize tag render, only applies when `mode` is set to `multiple` or `tags` | (props) => VueNode | - |
|
||||
|
||||
### Select Methods
|
||||
| Name | Description | Version |
|
||||
| --- | --- | --- |
|
||||
| blur() | Remove focus | - |
|
||||
| focus() | Get focus | - |
|
||||
|
||||
### showSearch
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| autoClearSearchValue | Whether the current search will be cleared on selecting an item. Only applies when `mode` is set to `multiple` or `tags` | boolean | true | - |
|
||||
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded | boolean \| (inputValue: string, option?: Option) => boolean | true | - |
|
||||
| filterSort | Sort function for search options sorting, see Array.sort's compareFunction | (optionA: Option, optionB: Option, info: { searchValue: string }) => number | - | - |
|
||||
| optionFilterProp | Which prop value of option will be used for filter if filterOption is true. If options is set, it should be set to label. When a string[] is provided, multiple fields are searched using OR matching | string \| string[] | value | - |
|
||||
| searchValue | The current input "search" text | string | - | - |
|
||||
| onSearch | Callback function that is fired when input changed | (value: string) => void | - | - |
|
||||
|
||||
### Option props
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| disabled | Disable this option | boolean | false | - |
|
||||
| title | title attribute of Select Option | string | - | - |
|
||||
| value | Default to filter with this property | string \| number | - | - |
|
||||
|
||||
### OptGroup props
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| key | Group key | string | - | - |
|
||||
| label | Group label | string \| VueNode | - | - |
|
||||
| title | title attribute of Select Option | string | - | - |
|
||||
|
||||
## Semantic DOM
|
||||
| _semantic | demo/_semantic.md |
|
||||
|
||||
## FAQ
|
||||
|
||||
### Why sometimes search will show 2 same option when in `tags` mode?
|
||||
It's caused by option with different `label` and `value`. You can use `optionFilterProp="label"` to change filter logic instead.
|
||||
|
||||
### When I click elements in popupRender, the select dropdown will not be closed?
|
||||
You can control it by `open` prop.
|
||||
|
||||
### I don't want dropdown close when click inside `popupRender`?
|
||||
Select will close when it lose focus. You can prevent event to handle this:
|
||||
|
||||
```html
|
||||
<a-select>
|
||||
<template #popupRender>
|
||||
<div
|
||||
@mousedown="(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}"
|
||||
>
|
||||
Some Content
|
||||
</div>
|
||||
</template>
|
||||
</a-select>
|
||||
```
|
||||
|
||||
### Why sometimes customize Option cause scroll break?
|
||||
Virtual scroll internal set item height as `24px`. You need to adjust `listItemHeight` when your option height is less and `listHeight` config list container height:
|
||||
|
||||
```html
|
||||
<a-select :list-item-height="10" :list-height="250" />
|
||||
```
|
||||
|
||||
Note: `listItemHeight` and `listHeight` are internal props. Please only modify when necessary.
|
||||
|
||||
### Why a11y test report missing `aria-` props?
|
||||
Select only create a11y auxiliary node when operating on. Please open Select and retry. For `aria-label` & `aria-labelledby` miss warning, please add related prop to Select with your own requirement.
|
||||
|
||||
Default virtual scrolling will create a mock element to simulate an accessible binding. If a screen reader needs to fully access the entire list, you can set `:virtual="false"` to disable virtual scrolling and the accessibility option will be bound to the actual element.
|
||||
|
||||
### Custom tags generated using `tagRender` slot will pop up a drop-down box when clicked to close
|
||||
If you don't want a drop-down menu to appear automatically after clicking on an element (such as a close icon), you can prevent the `mousedown` event from propagating on it.
|
||||
|
||||
```html
|
||||
<a-select>
|
||||
<template #tagRender="{ closable, label, onClose }">
|
||||
<span class="border">
|
||||
{{ label }}
|
||||
<span
|
||||
v-if="closable"
|
||||
class="cursor-pointer"
|
||||
@mousedown.stop
|
||||
@click="onClose"
|
||||
>
|
||||
❎
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</a-select>
|
||||
```
|
||||
@@ -0,0 +1,49 @@
|
||||
# select Token
|
||||
|
||||
Use these variables through `theme.components.Select`. This document lists definitions only and does not include values.
|
||||
|
||||
```vue
|
||||
<a-config-provider
|
||||
:theme="{
|
||||
token: {
|
||||
// Global token configuration
|
||||
},
|
||||
components: {
|
||||
Select: {
|
||||
// Token name: value
|
||||
},
|
||||
},
|
||||
}"
|
||||
>
|
||||
...
|
||||
</a-config-provider>
|
||||
```
|
||||
|
||||
## Token List
|
||||
|
||||
| Token | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| `zIndexPopup` | `number` | z-index of dropdown |
|
||||
| `optionSelectedColor` | `string` | Text color when option is selected |
|
||||
| `optionSelectedFontWeight` | `CSSProperties` | Font weight when option is selected |
|
||||
| `optionSelectedBg` | `string` | Background color when option is selected |
|
||||
| `optionActiveBg` | `string` | Background color when option is active |
|
||||
| `optionPadding` | `CSSProperties` | Padding of option |
|
||||
| `optionFontSize` | `number` | Font size of option |
|
||||
| `optionLineHeight` | `CSSProperties` | Line height of option |
|
||||
| `optionHeight` | `number` | Height of option |
|
||||
| `selectorBg` | `string` | Background color of selector |
|
||||
| `clearBg` | `string` | Background color of clear button |
|
||||
| `singleItemHeightLG` | `number` | Height of single selected item with large size |
|
||||
| `showArrowPaddingInlineEnd` | `number` | Inline end padding of arrow |
|
||||
| `hoverBorderColor` | `string` | Hover border color |
|
||||
| `activeBorderColor` | `string` | Active border color |
|
||||
| `activeOutlineColor` | `string` | Active outline color |
|
||||
| `multipleItemBg` | `string` | Background color of multiple tag |
|
||||
| `multipleItemBorderColor` | `string` | Border color of multiple tag |
|
||||
| `multipleItemHeight` | `number` | Height of multiple tag |
|
||||
| `multipleItemHeightSM` | `number` | Height of multiple tag with small size |
|
||||
| `multipleItemHeightLG` | `number` | Height of multiple tag with large size |
|
||||
| `multipleSelectorBgDisabled` | `string` | Background color of multiple selector when disabled |
|
||||
| `multipleItemColorDisabled` | `string` | Text color of multiple tag when disabled |
|
||||
| `multipleItemBorderColorDisabled` | `string` | Border color of multiple tag when disabled |
|
||||
Reference in new issue
Block a user