docs(site): [autocomplete] complete the document (#753)

This commit is contained in:
yoyo 2023-11-07 22:03:28 -08:00 committed by GitHub
parent f3913c6c99
commit 0a7bc09c1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 216 additions and 491 deletions

View File

@ -1,66 +0,0 @@
<template>
<div class="demo-autocomplete">
<tiny-autocomplete v-model="value" placeholder="请输入内容" :fetch-suggestions="querySearch">
<template #prepend>前置内容</template>
<template #append>后置内容</template>
</tiny-autocomplete>
</div>
</template>
<script setup lang="jsx">
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'
const restaurants = ref([])
const value = ref('')
onMounted(() => {
restaurants.value = loadAll()
})
function querySearch(queryString, cb) {
let results = queryString ? restaurants.value.filter(createFilter(queryString)) : restaurants.value
// callback
cb(results)
}
function createFilter(queryString) {
return (restaurant) => restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
}
function loadAll() {
return [
{
value: 'GFD科技YX公司',
address: '福州'
},
{
value: 'WWWW科技YX公司',
address: '深圳福田区'
},
{
value: 'RFV有限责任公司',
address: '中山市'
},
{
value: 'TGBYX公司',
address: '梅州'
},
{
value: 'YHN科技YX公司',
address: '韶关'
},
{
value: '康康物业YX公司',
address: '广州天河区'
}
]
}
</script>
<style scoped>
.demo-autocomplete .tiny-autocomplete {
width: 270px;
}
</style>

View File

@ -1,8 +0,0 @@
import { test, expect } from '@playwright/test'
test('append-prepend', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#append-prepend')
const prependText = await page.textContent('div.tiny-input-group__prepend')
await expect(prependText).toBe('前置内容')
})

View File

@ -1,73 +0,0 @@
<template>
<div class="demo-autocomplete">
<tiny-autocomplete v-model="value" placeholder="请输入内容" :fetch-suggestions="querySearch">
<template #prepend>前置内容</template>
<template #append>后置内容</template>
</tiny-autocomplete>
</div>
</template>
<script lang="jsx">
import { Autocomplete } from '@opentiny/vue'
export default {
components: {
TinyAutocomplete: Autocomplete
},
data() {
return {
restaurants: [],
value: ''
}
},
methods: {
querySearch(queryString, cb) {
let restaurants = this.restaurants
let results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
// callback
cb(results)
},
createFilter(queryString) {
return (restaurant) => restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
},
loadAll() {
return [
{
value: 'GFD科技YX公司',
address: '福州'
},
{
value: 'WWWW科技YX公司',
address: '深圳福田区'
},
{
value: 'RFV有限责任公司',
address: '中山市'
},
{
value: 'TGBYX公司',
address: '梅州'
},
{
value: 'YHN科技YX公司',
address: '韶关'
},
{
value: '康康物业YX公司',
address: '广州天河区'
}
]
}
},
mounted() {
this.restaurants = this.loadAll()
}
}
</script>
<style scoped>
.demo-autocomplete .tiny-autocomplete {
width: 270px;
}
</style>

View File

@ -4,7 +4,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -5,4 +5,9 @@ test('basic-usage', async ({ page }) => {
await page.goto('autocomplete#basic-usage')
const autocomplete = page.locator('.demo-autocomplete > .tiny-autocomplete')
await expect(autocomplete).toBeVisible()
await page.getByRole('textbox', { name: '请输入内容', exact: true }).click()
await page.getByRole('option', { name: 'GFD科技YX公司' }).click()
await expect(page.getByRole('textbox', { name: '请输入内容', exact: true })).toHaveValue('GFD科技YX公司')
})

View File

@ -4,7 +4,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -10,7 +10,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -3,10 +3,10 @@ import { test, expect } from '@playwright/test'
test('可清除', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#clearable')
await page.getByPlaceholder('请输入内容', { exact: true }).click()
await page.getByRole('textbox', { name: '请输入内容', exact: true }).click()
await page.getByRole('option', { name: 'WWWW科技YX公司' }).click()
await page.getByPlaceholder('请输入内容', { exact: true }).hover()
await page.getByRole('textbox', { name: '请输入内容', exact: true }).hover()
await page.getByRole('combobox').locator('path').click()
await expect(page.getByPlaceholder('请输入内容', { exact: true })).toHaveValue('')
await expect(page.getByRole('textbox', { name: '请输入内容', exact: true })).toHaveValue('')
})

View File

@ -10,7 +10,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -1,68 +0,0 @@
<template>
<div class="demo-autocomplete">
<tiny-autocomplete value-key="name" v-model="state1" :fetch-suggestions="querySearch" placeholder="请输入内容">
<template #default="{ slotScope }">
<div>{{ slotScope.name }}</div>
<span style="font-size: 12px; color: #a29b91">{{ slotScope.address }}</span>
</template>
</tiny-autocomplete>
</div>
</template>
<script setup lang="jsx">
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'
const restaurants = ref([])
const state1 = ref('')
onMounted(() => {
restaurants.value = loadAll()
})
function querySearch(queryString, cb) {
let results = queryString ? restaurants.value.filter(createFilter(queryString)) : restaurants.value
// callback
cb(results)
}
function createFilter(queryString) {
return (restaurant) => restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0
}
function loadAll() {
return [
{
name: 'GFD科技YX公司',
address: '福州'
},
{
name: 'WWWW科技YX公司',
address: '深圳福田区'
},
{
name: 'RFV有限责任公司',
address: '中山市'
},
{
name: 'TGBYX公司',
address: '梅州'
},
{
name: 'YHN科技YX公司',
address: '韶关'
},
{
name: '康康物业YX公司',
address: '广州天河区'
}
]
}
</script>
<style scoped>
.demo-autocomplete .tiny-autocomplete {
width: 270px;
}
</style>

View File

@ -1,8 +0,0 @@
import { test, expect } from '@playwright/test'
test('cust-template', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#cust-template')
await page.locator('#preview').getByPlaceholder('请输入内容').click()
await expect(page.getByText('WWWW科技YX公司')).toBeVisible()
})

View File

@ -1,76 +0,0 @@
<template>
<div class="demo-autocomplete">
<tiny-autocomplete value-key="name" v-model="state1" :fetch-suggestions="querySearch" placeholder="请输入内容">
<template #default="{ slotScope }">
<div>{{ slotScope.name }}</div>
<span style="font-size: 12px; color: #a29b91">{{ slotScope.address }}</span>
</template>
</tiny-autocomplete>
</div>
</template>
<script lang="jsx">
import { Autocomplete } from '@opentiny/vue'
export default {
components: {
TinyAutocomplete: Autocomplete
},
data() {
return {
restaurants: [],
state1: '',
state2: ''
}
},
methods: {
querySearch(queryString, cb) {
let restaurants = this.restaurants
let results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
// callback
cb(results)
},
createFilter(queryString) {
return (restaurant) => restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0
},
loadAll() {
return [
{
name: 'GFD科技YX公司',
address: '福州'
},
{
name: 'WWWW科技YX公司',
address: '深圳福田区'
},
{
name: 'RFV有限责任公司',
address: '中山市'
},
{
name: 'TGBYX公司',
address: '梅州'
},
{
name: 'YHN科技YX公司',
address: '韶关'
},
{
name: '康康物业YX公司',
address: '广州天河区'
}
]
}
},
mounted() {
this.restaurants = this.loadAll()
}
}
</script>
<style scoped>
.demo-autocomplete .tiny-autocomplete {
width: 270px;
}
</style>

View File

@ -10,7 +10,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'
import { iconEdit, iconAssociation } from '@opentiny/vue-icon'

View File

@ -3,7 +3,6 @@ import { test, expect } from '@playwright/test'
test('custom-icon', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#custom-icon')
await page.getByText('自定义图标').first().click()
const prefix = page.locator('.tiny-autocomplete > .tiny-input > .tiny-input__prefix')
const suffix = page.locator('.tiny-autocomplete > .tiny-input > div > .tiny-input__suffix')
await expect(prefix).toBeVisible()

View File

@ -10,7 +10,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
import { IconEdit, IconAssociation } from '@opentiny/vue-icon'

View File

@ -9,7 +9,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -4,9 +4,11 @@ test('debounce', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#debounce')
await page.getByText('去抖延时').nth(3).click()
await page.locator('.rel').click()
await page.locator('#preview').getByPlaceholder('请输入内容').click()
await page.getByRole('option', { name: 'WWWW科技YX公司' }).click()
await page.getByRole('textbox', { name: '请输入内容', exact: true }).click()
await expect(page.getByRole('option', { name: 'WWWW科技YX公司' })).not.toBeVisible()
await page.waitForTimeout(1000)
await expect(page.getByRole('option', { name: 'WWWW科技YX公司' })).toBeVisible()
await expect(
page.locator('.demo-autocomplete > .tiny-autocomplete > .tiny-input > .tiny-input-display-only > input')
).toHaveAttribute('debounce', '1000')

View File

@ -9,7 +9,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -4,7 +4,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -2,8 +2,6 @@ import { test, expect } from '@playwright/test'
test('disabled', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#disabled1')
await page.getByTitle('表单组件').click()
await page.locator('.rel').click()
await page.goto('autocomplete#disabled')
await expect(page.locator('//div[@class="tiny-input is-disabled"]')).toHaveClass(/disabled/)
})

View File

@ -4,7 +4,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -1,10 +1,10 @@
<template>
<div class="demo-autocomplete">
<div>
<div class="loading-icon">
默认有加载图标
<tiny-autocomplete v-model="value" placeholder="请输入内容" :fetch-suggestions="querySearch"></tiny-autocomplete>
</div>
<div>
<div class="loading-icon_hide">
隐藏加载图标
<tiny-autocomplete
v-model="value"
@ -16,7 +16,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'
@ -75,4 +75,8 @@ function loadAll() {
display: flex;
width: 270px;
}
.loading-icon {
margin-bottom: 12px;
}
</style>

View File

@ -3,16 +3,8 @@ import { test, expect } from '@playwright/test'
test('hide-loading', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#hide-loading')
await page.getByPlaceholder('请输入内容').nth(1).click()
await expect(
page
.locator('.demo-autocomplete > div > .tiny-autocomplete > .tiny-input > .tiny-input-display-only > input')
.first()
).toHaveAttribute('hideloading', 'false')
await page.getByPlaceholder('请输入内容').nth(2).click()
await expect(
page
.locator('.demo-autocomplete > div > .tiny-autocomplete > .tiny-input > .tiny-input-display-only > input')
.nth(1)
).toHaveAttribute('hideloading', 'true')
await page.getByPlaceholder('请输入内容', { exact: true }).nth(1).click()
await expect(page.getByRole('listitem').getByRole('img')).toBeVisible()
await page.getByPlaceholder('请输入内容', { exact: true }).nth(2).click()
await expect(page.getByRole('listitem').getByRole('img')).not.toBeVisible()
})

View File

@ -1,10 +1,10 @@
<template>
<div class="demo-autocomplete">
<div>
<div class="loading-icon">
默认有加载图标
<tiny-autocomplete v-model="value" placeholder="请输入内容" :fetch-suggestions="querySearch"></tiny-autocomplete>
</div>
<div>
<div class="loading-icon_hide">
隐藏加载图标
<tiny-autocomplete
v-model="value"
@ -16,7 +16,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {
@ -82,4 +82,8 @@ export default {
display: flex;
width: 270px;
}
.loading-icon {
margin-bottom: 12px;
}
</style>

View File

@ -9,7 +9,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'
test('highlight-first-item', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#highlight-first-item')
await page.locator('#preview').getByPlaceholder('请输入内容').click()
await page.getByRole('textbox', { name: '请输入内容', exact: true }).click()
await page.getByRole('option', { name: 'TGBYX公司' }).click()
await expect(page.locator('#preview').getByPlaceholder('请输入内容')).toHaveAttribute('highlightfirstitem', 'true')
await expect(page.getByRole('textbox', { name: '请输入内容', exact: true })).toHaveAttribute('highlightfirstitem', 'true')
})

View File

@ -9,7 +9,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -9,7 +9,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -3,8 +3,8 @@ import { test, expect } from '@playwright/test'
test('no-trigger-on-focus', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#no-trigger-on-focus')
await page.locator('#preview').getByPlaceholder('请输入内容').click()
await page.getByRole('textbox', { name: '请输入内容', exact: true }).click()
await expect(page.locator('.tiny-autocomplete-suggestion')).not.toBeVisible()
await page.locator('#preview').getByPlaceholder('请输入内容').fill('gfd')
await page.getByRole('textbox', { name: '请输入内容', exact: true }).fill('gfd')
await expect(page.locator('.tiny-autocomplete-suggestion')).toBeVisible()
})

View File

@ -9,7 +9,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -9,7 +9,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -9,7 +9,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -16,7 +16,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -16,7 +16,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -1,10 +0,0 @@
import { test, expect } from '@playwright/test'
test('prefix-suffix-slot', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#prefix-suffix-slot')
const prefix = page.locator('.demo-autocomplete > .tiny-autocomplete > .tiny-input > .tiny-input__prefix')
const suffix = page.locator('.demo-autocomplete > .tiny-autocomplete > .tiny-input > div > .tiny-input__suffix')
await expect(prefix).toBeVisible()
await expect(suffix).toBeVisible()
})

View File

@ -7,15 +7,11 @@
:fetch-suggestions="querySearch"
placeholder="请输入内容"
>
<template #default="{ slotScope }">
<div>{{ slotScope.name }}</div>
<span style="font-size: 12px; color: #a29b91">{{ slotScope.address }}</span>
</template>
</tiny-autocomplete>
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -3,7 +3,6 @@ import { test, expect } from '@playwright/test'
test('remote-search', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#remote-search')
await expect(
page.locator('.demo-autocomplete > .tiny-autocomplete > .tiny-input > .tiny-input-display-only > input')
).toHaveAttribute('fetchsuggestions', 'function () { [native code] }')
await page.getByRole('textbox', { name: '请输入内容', exact: true }).click()
await expect(page.getByRole('option', { name: 'GFD科技YX公司' })).toBeVisible()
})

View File

@ -7,15 +7,11 @@
:fetch-suggestions="querySearch"
placeholder="请输入内容"
>
<template #default="{ slotScope }">
<div>{{ slotScope.name }}</div>
<span style="font-size: 12px; color: #a29b91">{{ slotScope.address }}</span>
</template>
</tiny-autocomplete>
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -10,7 +10,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete, Modal } from '@opentiny/vue'

View File

@ -3,7 +3,7 @@ import { test, expect } from '@playwright/test'
test('select-event', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#select-event')
await page.getByPlaceholder('请输入内容', { exact: true }).click()
await page.getByRole('option', { name: 'WWWW科技YX公司' }).click()
await expect(page.getByText('当前选择:{"value":"WWWW科技YX公司","address":"深圳福田区"}')).toBeVisible()
await page.getByRole('textbox', { name: '请输入内容', exact: true }).click()
await page.getByRole('option', { name: 'GFD科技YX公司' }).click()
await expect(page.locator('div').filter({ hasText: '当前选择:{"value":"GFD科技YX公司","address":"福州"}' }).nth(1)).toBeVisible()
})

View File

@ -10,7 +10,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete, Modal } from '@opentiny/vue'
export default {

View File

@ -9,7 +9,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -4,7 +4,7 @@ test('size', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#size')
await page.getByText('输入框大小').nth(1).click()
await page.locator('#preview').getByPlaceholder('请输入内容').click()
await page.getByRole('textbox', { name: '请输入内容', exact: true }).click()
await page.getByRole('option', { name: 'WWWW科技YX公司' }).click()
await expect(page.locator('//div[@class="tiny-input tiny-input-medium"]')).toHaveClass(/tiny-input-medium/)
})

View File

@ -9,7 +9,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -1,6 +1,10 @@
<template>
<div class="demo-autocomplete">
<tiny-autocomplete v-model="value" placeholder="请输入内容" :fetch-suggestions="querySearch">
<tiny-autocomplete class="pend-slot" v-model="value" placeholder="请输入内容" :fetch-suggestions="querySearch">
<template #prepend>前置内容</template>
<template #append>后置内容</template>
</tiny-autocomplete>
<tiny-autocomplete class="fix-slot" v-model="value" placeholder="请输入内容" :fetch-suggestions="querySearch">
<template #prefix>
<tiny-icon-edit />
</template>
@ -8,17 +12,22 @@
<tiny-icon-association />
</template>
</tiny-autocomplete>
<tiny-autocomplete class="default-slot" v-model="value" :fetch-suggestions="querySearch">
<template #default="{ slotScope }">
<div>{{ slotScope.value }}</div>
<span class="default-slot-buttom">{{ slotScope.address }}</span>
</template>
</tiny-autocomplete>
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'
import { iconEdit, iconAssociation } from '@opentiny/vue-icon'
const restaurants = ref([])
const value = ref('')
const TinyIconEdit = iconEdit()
const TinyIconAssociation = iconAssociation()
@ -71,4 +80,12 @@ function loadAll() {
.demo-autocomplete .tiny-autocomplete {
width: 270px;
}
.pend-slot, .fix-slot {
margin-right: 12px;
}
.default-slot-buttom {
font-size: 12px;
color: #a29b91
}
</style>

View File

@ -0,0 +1,17 @@
import { test, expect } from '@playwright/test'
test('slot', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#slot')
await expect(page.locator('.demo-autocomplete > .tiny-autocomplete.pend-slot').getByText('前置内容', { exact: true })).toBeVisible()
await expect(page.locator('.demo-autocomplete > .tiny-autocomplete.pend-slot').getByText('后置内容', { exact: true })).toBeVisible()
const prefix = page.locator('.demo-autocomplete > .tiny-autocomplete.fix-slot > .tiny-input > .tiny-input__prefix')
const suffix = page.locator('.demo-autocomplete > .tiny-autocomplete.fix-slot > .tiny-input > div > .tiny-input__suffix')
await expect(prefix).toBeVisible()
await expect(suffix).toBeVisible()
await page.locator('.demo-autocomplete > .tiny-autocomplete.default-slot').click()
await expect(page.getByRole('option', { name: 'GFD科技YX公司 福州' })).toBeVisible()
})

View File

@ -1,25 +1,35 @@
<template>
<div class="demo-autocomplete">
<tiny-autocomplete v-model="value" placeholder="请输入内容" :fetch-suggestions="querySearch">
<tiny-autocomplete class="pend-slot" v-model="value" :fetch-suggestions="querySearch">
<template #prepend>前置内容</template>
<template #append>后置内容</template>
</tiny-autocomplete>
<tiny-autocomplete class="fix-slot" v-model="value" :fetch-suggestions="querySearch">
<template #prefix>
<icon-edit />
<tiny-icon-edit />
</template>
<template #suffix>
<icon-association />
<tiny-icon-association />
</template>
</tiny-autocomplete>
<tiny-autocomplete class="default-slot" v-model="value" :fetch-suggestions="querySearch">
<template #default="{ slotScope }">
<div>{{ slotScope.value }}</div>
<span class="default-slot-buttom">{{ slotScope.address }}</span>
</template>
</tiny-autocomplete>
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
import { IconEdit, IconAssociation } from '@opentiny/vue-icon'
export default {
components: {
TinyAutocomplete: Autocomplete,
IconEdit: IconEdit(),
IconAssociation: IconAssociation()
TinyIconEdit: IconEdit(),
TinyIconAssociation: IconAssociation()
},
data() {
return {
@ -77,4 +87,12 @@ export default {
.demo-autocomplete .tiny-autocomplete {
width: 270px;
}
.pend-slot, .fix-slot {
margin-right: 12px;
}
.default-slot-buttom {
font-size: 12px;
color: #a29b91
}
</style>

View File

@ -9,7 +9,7 @@
</div>
</template>
<script setup lang="jsx">
<script setup>
import { ref, onMounted } from 'vue'
import { Autocomplete as TinyAutocomplete } from '@opentiny/vue'

View File

@ -3,7 +3,8 @@ import { test, expect } from '@playwright/test'
test('value-key', async ({ page }) => {
page.on('pageerror', (exception) => expect(exception).toBeNull())
await page.goto('autocomplete#value-key')
await expect(
page.locator('.demo-autocomplete > .tiny-autocomplete > .tiny-input > .tiny-input-display-only > input')
).toHaveAttribute('valuekey', 'name')
await page.getByRole('textbox', { name: '请输入内容', exact: true }).fill('GFD科技YX公司')
await expect(await page.getByRole('option', { name: 'GFD科技YX公司' })).toBeVisible()
})

View File

@ -9,7 +9,7 @@
</div>
</template>
<script lang="jsx">
<script>
import { Autocomplete } from '@opentiny/vue'
export default {

View File

@ -3,7 +3,16 @@ export default {
owner: '',
demos: [
{
'demoId': 'disabled1',
'demoId': 'basic-usage',
'name': { 'zh-CN': '基础用法', 'en-US': 'Basic Usage' },
'desc': {
'zh-CN': '<p>基础用法。</p>',
'en-US': '<p>Basic Usage. </p>\n'
},
'codeFiles': ['basic-usage.vue']
},
{
'demoId': 'disabled',
'name': { 'zh-CN': '禁用', 'en-US': 'Disabled' },
'desc': {
'zh-CN': '<p>通过 <code>disabled</code> 属性可以设置为禁用状态。</p>\n',
@ -11,18 +20,12 @@ export default {
},
'codeFiles': ['disabled.vue']
},
{
'demoId': 'disabled',
'name': { 'zh-CN': '原生属性', 'en-US': 'Native Attribute' },
'desc': { 'zh-CN': '详细用法参考如下示例', 'en-US': 'For details, see the following example.' },
'codeFiles': ['disabled.vue']
},
{
'demoId': 'size',
'name': { 'zh-CN': '输入框大小', 'en-US': 'Text box size' },
'desc': {
'zh-CN': '<p>可选择值为mediumsmallmini</p>\n',
'en-US': '<p>The value can be medium, small, or mini</p>\n'
'zh-CN': '<p>可选择值为<code>medium</code><code>small</code><code>mini</code></p>\n',
'en-US': '<p>The value can be <code>medium</code>, <code>small</code>, or <code>mini</code></p>\n'
},
'codeFiles': ['size.vue']
},
@ -37,26 +40,17 @@ export default {
'codeFiles': ['clearable.vue']
},
{
'demoId': 'append-prepend',
'name': { 'zh-CN': '输入框前置内容', 'en-US': 'Pre-content in the text box' },
'demoId': 'slot',
'name': { 'zh-CN': '插槽', 'en-US': 'slot' },
'desc': {
'zh-CN': '<p>配置 <code>prepend</code> 属性设置输入框前置内容。</p>\n',
'en-US': '<p>Configure the <code>prepend</code> attribute to set the front content of the text box. </p>\n'
'zh-CN': '<p>分别配置 <code>prepend</code>、<code>append</code>、<code>prefix</code>、<code>suffix</code>、<code>default</code> 插槽</p>\n',
'en-US': '<p>Configure <code>prepend</code>, <code>append</code>, <code>prefix</code>, <code>default</code>, and <code>suffix</code> slots.</p>\n'
},
'codeFiles': ['append-prepend.vue']
},
{
'demoId': 'append-append',
'name': { 'zh-CN': '输入框后置内容', 'en-US': 'Content after the text box' },
'desc': {
'zh-CN': '<p>配置 <code>append</code> 属性设置输入框后置内容。</p>\n',
'en-US': '<p>Configure the <code>append</code> attribute to set the content behind the text box. </p>\n'
},
'codeFiles': ['append-prepend.vue']
'codeFiles': ['slot.vue']
},
{
'demoId': 'custom-icon',
'name': { 'zh-CN': '自定义图标', 'en-US': 'Custom Icon' },
'name': { 'zh-CN': '图标', 'en-US': 'Icon' },
'desc': {
'zh-CN':
'<p>配置 <code>prefix-icon</code> 和 <code>suffix-icon</code> 属性可分别自定义输入框前后置图标。</p>\n',
@ -65,16 +59,6 @@ export default {
},
'codeFiles': ['custom-icon.vue']
},
{
'demoId': 'prefix-suffix-slot',
'name': { 'zh-CN': '通过插槽自定义图标', 'en-US': 'Customize icons by slot' },
'desc': {
'zh-CN': '<p>通过 <code>prefix</code> 和 <code>suffix</code> 插槽也可以分别自定义输入框前后置图标。</p>\n',
'en-US':
'<p>You can also customize the front and rear icons of the text box through the <code>prefix</code> and <code>suffix</code> slots. </p>\n'
},
'codeFiles': ['prefix-suffix-slot.vue']
},
{
'demoId': 'debounce',
'name': { 'zh-CN': '去抖延时', 'en-US': 'Debounce Delay' },
@ -87,31 +71,13 @@ export default {
},
{
'demoId': 'hide-loading',
'name': { 'zh-CN': '隐藏加载图标', 'en-US': 'Hide the loading icon' },
'name': { 'zh-CN': '加载图标', 'en-US': 'Loading Icon' },
'desc': {
'zh-CN': '<p>设置 <code>hide-loading</code> 属性为 true ,可以隐藏加载图标。</p>\n',
'en-US': '<p>Set <code>hide-loading</code> to true to hide the loading icon. </p>\n'
},
'codeFiles': ['hide-loading.vue']
},
{
'demoId': 'hide-loading1',
'name': { 'zh-CN': '输入框占位文本', 'en-US': 'Placeholder text in the text box' },
'desc': {
'zh-CN': '<p>通过 <code>placeholder</code> 属性设置输入框占位文本。</p>\n',
'en-US': '<p>Use the <code>placeholder</code> attribute to set the placeholder text in the text box. </p>\n'
},
'codeFiles': ['hide-loading.vue']
},
{
'demoId': 'cust-template',
'name': { 'zh-CN': '自定义模板', 'en-US': 'Custom Template' },
'desc': {
'zh-CN': '<p>通过作用域插槽可以自定义输入建议模板。</p>\n',
'en-US': '<p>You can customize the input suggestion template through the scope slot. </p>\n'
},
'codeFiles': ['cust-template.vue']
},
{
'demoId': 'remote-search',
'name': { 'zh-CN': '远程搜索', 'en-US': 'Remote Search' },
@ -123,7 +89,7 @@ export default {
},
{
'demoId': 'value-key',
'name': { 'zh-CN': '指定显示的键名', 'en-US': 'Specify the key name to be displayed.' },
'name': { 'zh-CN': '显示的键名', 'en-US': 'Key Name to be displayed.' },
'desc': {
'zh-CN':
'<p>输入内容后,建议列表中默认显示输入建议对象中 value 键名对应的值,若对象中没有 value 键名,就可以通过 <code>value-key</code> 属性指定显示的键名。</p>\n',
@ -134,7 +100,7 @@ export default {
},
{
'demoId': 'popper-class',
'name': { 'zh-CN': '自定义列表样式', 'en-US': 'Custom List Style' },
'name': { 'zh-CN': '列表样式', 'en-US': 'List Style' },
'desc': {
'zh-CN':
'<p><code>popper-class</code> 属性可指定一个样式类名,可自定义建议列表的样式。\n<code>popper-append-to-body</code> 属性可设置是否将下拉列表插入至 body 元素。在下拉列表的定位出现问题时,可将该属性设置为 false。</p>\n',
@ -145,18 +111,18 @@ export default {
},
{
'demoId': 'placement',
'name': { 'zh-CN': '设置菜单弹出位置', 'en-US': 'Set menu pop-up position' },
'name': { 'zh-CN': '菜单弹出位置', 'en-US': 'Menu Pop-up Position' },
'desc': {
'zh-CN':
'<p><code>placement</code> 属性可以设置菜单弹出位置,默认为 <code>bottom-start</code>。可选值有 top、top-start、top-end、bottom、bottom-start、bottom-end 。</p>\n',
'<p><code>placement</code> 属性可以设置菜单弹出位置,默认为 <code>bottom-start</code>。</p>\n',
'en-US':
'<p><code>placement</code> property can be used to set the menu pop-up position. The default value is <code>bottom-start</code>. The options are top, top-start, top-end, bottom, bottom-start, and bottom-end. </p>\n'
'<p><code>placement</code> property can be used to set the menu pop-up position. The default value is <code>bottom-start</code>. </p>\n'
},
'codeFiles': ['placement.vue']
},
{
'demoId': 'highlight-first-item',
'name': { 'zh-CN': '高亮显示第一项', 'en-US': 'Highlight the first item' },
'name': { 'zh-CN': '第一项高亮', 'en-US': 'Highlight the first item' },
'desc': {
'zh-CN': '<p>设置 <code>highlight-first-item</code> 属性为 true ,可以突出显示远程搜索建议中的第一项。</p>\n',
'en-US':
@ -166,7 +132,7 @@ export default {
},
{
'demoId': 'no-trigger-on-focus',
'name': { 'zh-CN': '聚焦不显示建议列表', 'en-US': 'Focus does not display the suggestion list' },
'name': { 'zh-CN': '触发', 'en-US': 'Trigger' },
'desc': {
'zh-CN':
'<p>默认输入框聚焦就会显示全部的建议列表,但设置 <code>trigger-on-focus</code> 属性为 false 后只有在匹配到输入建议后才会显示匹配到的建议列表。</p>\n',
@ -195,7 +161,7 @@ export default {
{
'name': 'clearable',
'type': 'boolean',
'defaultValue': '该属性的默认值为 false',
'defaultValue': 'false',
'desc': { 'zh-CN': '是否可清空', 'en-US': 'Whether to clear data' },
'demoId': 'clearable'
},
@ -204,47 +170,48 @@ export default {
'type': 'string',
'defaultValue': '',
'desc': { 'zh-CN': '输入框占位文本', 'en-US': 'Placeholder text in the text box' },
'demoId': 'hide-loading1'
'demoId': 'hide-loading'
},
{
'name': 'disabled',
'type': 'boolean',
'defaultValue': '',
'desc': { 'zh-CN': '禁用', 'en-US': 'Disabled' },
'demoId': 'disabled1'
'desc': { 'zh-CN': '是否禁用', 'en-US': 'Whether to disabled' },
'demoId': 'disabled'
},
{
'name': 'value-key',
'type': 'string',
'defaultValue': '',
'defaultValue': 'value',
'desc': {
'zh-CN': '输入建议对象中用于显示的键名',
'en-US': 'Enter the key name for display in the suggestion object.'
'zh-CN': '输入建议对象中用于显示和匹配输入的键名',
'en-US': 'In the Input Suggestion object, key names for displaying and matching inputs'
},
'demoId': 'value-key'
},
{
'name': 'value',
'name': 'v-model',
'type': 'string',
'defaultValue': '',
'desc': { 'zh-CN': '必填值,输入绑定值', 'en-US': 'This parameter is mandatory. Enter a bound value.' },
'demoId': 'clearable'
'demoId': 'basic-usage'
},
{
'name': 'debounce',
'type': 'number',
'defaultValue': '该属性的默认值为 300',
'defaultValue': '300',
'desc': { 'zh-CN': '获取输入建议的去抖延时', 'en-US': 'Obtain the recommended input dejitter delay.' },
'demoId': 'debounce'
},
{
'name': 'placement',
'type': 'string',
'defaultValue': '该属性的默认值为 bottom-start',
'typeAnchorName': 'IAutocompletePlacement',
'type': 'IAutocompletePlacement',
'defaultValue': '"bottom-start"',
'desc': {
'zh-CN': '菜单弹出位置;该属性的可选值为 top / top-start / top-end / bottom / bottom-start / bottom-end',
'zh-CN': '菜单弹出位置',
'en-US':
'Menu pop-up position; The optional value of this attribute is top / top-start / top-end / bottom / bottom-start / bottom-end'
'Menu pop-up position'
},
'demoId': 'placement'
},
@ -253,25 +220,25 @@ export default {
'type': 'string',
'defaultValue': '',
'desc': {
'zh-CN': 'Autocomplete 下拉列表的类名',
'zh-CN': '下拉列表的类名',
'en-US': 'Class name of the Autocomplete drop-down list box'
},
'demoId': 'popper-class'
},
{
'name': 'size',
'type': 'string',
'type': '"medium" | "small" | "mini"',
'defaultValue': '',
'desc': {
'zh-CN': '设置组件大小可设置为mediumsmallmini',
'en-US': 'Set the component size. The value can be medium, small, or mini.'
'zh-CN': '设置组件大小',
'en-US': 'Set the component size.'
},
'demoId': 'size'
},
{
'name': 'trigger-on-focus',
'type': 'boolean',
'defaultValue': '该属性的默认值为 true',
'defaultValue': 'true',
'desc': {
'zh-CN': '是否在输入框 focus 时显示建议列表',
'en-US': 'Whether to display the suggestion list when the text box is focused'
@ -282,13 +249,12 @@ export default {
'name': 'name',
'type': 'string',
'defaultValue': '',
'desc': { 'zh-CN': '原生属性', 'en-US': 'Native attribute' },
'demoId': 'clearable'
'desc': { 'zh-CN': 'input元素的原生属性', 'en-US': 'Native attributes of the input element' }
},
{
'name': 'select-when-unmatched',
'type': 'boolean',
'defaultValue': '该属性的默认值为 false',
'defaultValue': 'false',
'desc': {
'zh-CN': '在输入没有任何匹配建议的情况下,按下回车是否触发 select 事件',
'en-US':
@ -300,19 +266,19 @@ export default {
'name': 'label',
'type': 'string',
'defaultValue': '',
'desc': { 'zh-CN': '输入框关联的label文字', 'en-US': 'Label text associated with the text box' },
'desc': { 'zh-CN': '等价于原生 input aria-label 属性', 'en-US': 'Equiphorus input aria-label attribute' },
'demoId': ''
},
{
'name': 'prefix-icon',
'type': 'string',
'type': 'Component',
'defaultValue': '',
'desc': { 'zh-CN': '输入框头部图标', 'en-US': 'Icon on the header of the text box' },
'demoId': 'custom-icon'
},
{
'name': 'suffix-icon',
'type': 'string',
'type': 'Component',
'defaultValue': '',
'desc': { 'zh-CN': '输入框尾部图标', 'en-US': 'Icon at the end of the text box' },
'demoId': 'custom-icon'
@ -320,7 +286,7 @@ export default {
{
'name': 'hide-loading',
'type': 'boolean',
'defaultValue': '该属性的默认值为 false',
'defaultValue': 'false',
'desc': {
'zh-CN': '是否隐藏远程加载时的加载图标',
'en-US': 'Whether to hide the loading icon during remote loading'
@ -330,7 +296,7 @@ export default {
{
'name': 'popper-append-to-body',
'type': 'boolean',
'defaultValue': '该属性的默认值为 true',
'defaultValue': 'true',
'desc': {
'zh-CN': '是否将下拉列表插入至 body 元素。在下拉列表的定位出现问题时,可将该属性设置为 false',
'en-US':
@ -340,19 +306,20 @@ export default {
},
{
'name': 'fetch-suggestions',
'type': 'Function(queryString, callback)',
'typeAnchorName': 'IAutocompleteFetchSuggestions',
'type': 'IAutocompleteFetchSuggestions',
'defaultValue': '',
'desc': {
'zh-CN': '返回输入建议的方法,仅当你的输入建议数据 resolve 时,通过调用 callback(data:[]) 来返回它',
'zh-CN': '返回输入建议的方法,仅当你的输入建议数据 resolve 时,通过调用 callback 来返回它',
'en-US':
'This method is used to return input suggestions. It is returned by calling callback(data:[]) only when your input suggestions are resolved.'
'This method is used to return input suggestions. It is returned by calling callback only when your input suggestions are resolved.'
},
'demoId': 'remote-search'
},
{
'name': 'highlight-first-item',
'type': 'boolean',
'defaultValue': '该属性的默认值为 false',
'defaultValue': 'false',
'desc': {
'zh-CN': '是否默认突出显示远程搜索建议中的第一项',
'en-US': 'Whether to highlight the first item in remote search suggestions by default'
@ -363,10 +330,10 @@ export default {
'events': [
{
'name': 'select',
'type': '',
'type': '(selection: object) => void',
'defaultValue': '',
'desc': {
'zh-CN': '点击选中建议项时触发。回调参数为选中建议项',
'zh-CN': '点击选中建议项时触发。回调参数为选中建议项',
'en-US':
'This event is triggered when a suggestion item is selected. The callback parameter is: Selected Suggestions'
},
@ -379,30 +346,49 @@ export default {
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '输入框头部内容', 'en-US': 'Content in the text box header' },
'demoId': 'custom-icon'
'demoId': 'slot'
},
{
'name': 'suffix',
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '输入框尾部内容', 'en-US': 'Content at the end of the text box' },
'demoId': 'custom-icon'
'demoId': 'slot'
},
{
'name': 'prepend',
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '输入框前置内容', 'en-US': 'Pre-content in the text box' },
'demoId': 'append-prepend'
'demoId': 'slot'
},
{
'name': 'append',
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '输入框后置内容', 'en-US': 'Content after the text box' },
'demoId': 'append-prepend'
'demoId': 'slot'
},
{
'name': 'default',
'type': '',
'defaultValue': '',
'desc': { 'zh-CN': '下拉列表项插槽,插槽参数: arg: { slotScope: object }', 'en-US': 'Dropdown list item slot, slot parameters: arg: { slotScope: object }' },
'demoId': 'slot'
}
]
}
],
types: [
{
name: 'IAutocompletePlacement',
type: 'type',
code: `type IAutocompletePlacement = "top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end"`
},
{
name: 'IAutocompleteFetchSuggestions',
type: 'type',
code: 'type IAutocompleteFetchSuggestions = (queryString: string, callback: (suggestions: object[]) => void) => void'
}
]
}