mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-24 17:00:36 +01:00
@@ -0,0 +1,16 @@
|
|||||||
|
<script setup>
|
||||||
|
const people = ['Wade Cooper', 'Arlene Mccoy', 'Devon Webb', 'Tom Cook', 'Tanya Fox', 'Hellen Schmidt', 'Caroline Schultz', 'Mason Heaney', 'Claudie Smitham', 'Emil Schaefer']
|
||||||
|
|
||||||
|
const selected = ref()
|
||||||
|
const query = ref('Wade')
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<USelectMenu
|
||||||
|
v-model="selected"
|
||||||
|
v-model:query="query"
|
||||||
|
:options="people"
|
||||||
|
placeholder="Select a person"
|
||||||
|
searchable
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
@@ -146,6 +146,18 @@ componentProps:
|
|||||||
---
|
---
|
||||||
::
|
::
|
||||||
|
|
||||||
|
### Control the query :u-badge{label="New" class="align-middle ml-2 !rounded-full" variant="subtle"}
|
||||||
|
|
||||||
|
Use a `v-model:query` to control the search query.
|
||||||
|
|
||||||
|
::component-example
|
||||||
|
---
|
||||||
|
component: 'select-menu-example-search-query'
|
||||||
|
componentProps:
|
||||||
|
class: 'w-full lg:w-48'
|
||||||
|
---
|
||||||
|
::
|
||||||
|
|
||||||
## Creatable
|
## Creatable
|
||||||
|
|
||||||
Use the `creatable` prop to enable the creation of new options when the search doesn't return any results (only works with `searchable`).
|
Use the `creatable` prop to enable the creation of new options when the search doesn't return any results (only works with `searchable`).
|
||||||
|
|||||||
@@ -58,14 +58,13 @@
|
|||||||
<component :is="searchable ? 'HComboboxOptions' : 'HListboxOptions'" static :class="[uiMenu.base, uiMenu.ring, uiMenu.rounded, uiMenu.shadow, uiMenu.background, uiMenu.padding, uiMenu.height]">
|
<component :is="searchable ? 'HComboboxOptions' : 'HListboxOptions'" static :class="[uiMenu.base, uiMenu.ring, uiMenu.rounded, uiMenu.shadow, uiMenu.background, uiMenu.padding, uiMenu.height]">
|
||||||
<HComboboxInput
|
<HComboboxInput
|
||||||
v-if="searchable"
|
v-if="searchable"
|
||||||
ref="searchInput"
|
|
||||||
:display-value="() => query"
|
:display-value="() => query"
|
||||||
name="q"
|
name="q"
|
||||||
:placeholder="searchablePlaceholder"
|
:placeholder="searchablePlaceholder"
|
||||||
autofocus
|
autofocus
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
:class="uiMenu.input"
|
:class="uiMenu.input"
|
||||||
@change="query = $event.target.value"
|
@change="onChange"
|
||||||
/>
|
/>
|
||||||
<component
|
<component
|
||||||
:is="searchable ? 'HComboboxOption' : 'HListboxOption'"
|
:is="searchable ? 'HComboboxOption' : 'HListboxOption'"
|
||||||
@@ -126,7 +125,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ref, computed, toRef, watch, defineComponent } from 'vue'
|
import { ref, computed, toRef, watch, defineComponent } from 'vue'
|
||||||
import type { PropType, ComponentPublicInstance } from 'vue'
|
import type { PropType } from 'vue'
|
||||||
import {
|
import {
|
||||||
Combobox as HCombobox,
|
Combobox as HCombobox,
|
||||||
ComboboxButton as HComboboxButton,
|
ComboboxButton as HComboboxButton,
|
||||||
@@ -177,6 +176,10 @@ export default defineComponent({
|
|||||||
type: [String, Number, Object, Array],
|
type: [String, Number, Object, Array],
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
|
query: {
|
||||||
|
type: String,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
by: {
|
by: {
|
||||||
type: String,
|
type: String,
|
||||||
default: undefined
|
default: undefined
|
||||||
@@ -326,7 +329,7 @@ export default defineComponent({
|
|||||||
default: () => ({})
|
default: () => ({})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:modelValue', 'open', 'close', 'change'],
|
emits: ['update:modelValue', 'update:query', 'open', 'close', 'change'],
|
||||||
setup (props, { emit, slots }) {
|
setup (props, { emit, slots }) {
|
||||||
const { ui, attrs } = useUI('select', toRef(props, 'ui'), config, toRef(props, 'class'))
|
const { ui, attrs } = useUI('select', toRef(props, 'ui'), config, toRef(props, 'class'))
|
||||||
|
|
||||||
@@ -341,8 +344,16 @@ export default defineComponent({
|
|||||||
|
|
||||||
const size = computed(() => sizeButtonGroup.value || sizeFormGroup.value)
|
const size = computed(() => sizeButtonGroup.value || sizeFormGroup.value)
|
||||||
|
|
||||||
const query = ref('')
|
const internalQuery = ref('')
|
||||||
const searchInput = ref<ComponentPublicInstance<HTMLElement>>()
|
const query = computed({
|
||||||
|
get () {
|
||||||
|
return props.query ?? internalQuery.value
|
||||||
|
},
|
||||||
|
set (value) {
|
||||||
|
internalQuery.value = value
|
||||||
|
emit('update:query', value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const selectClass = computed(() => {
|
const selectClass = computed(() => {
|
||||||
const variant = ui.value.color?.[color.value as string]?.[props.variant as string] || ui.value.variant[props.variant]
|
const variant = ui.value.color?.[color.value as string]?.[props.variant as string] || ui.value.variant[props.variant]
|
||||||
@@ -476,17 +487,15 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
|
|
||||||
function onUpdate (event: any) {
|
function onUpdate (event: any) {
|
||||||
if (query.value && searchInput.value?.$el) {
|
|
||||||
query.value = ''
|
|
||||||
// explicitly set input text because `ComboboxInput` `displayValue` is not reactive
|
|
||||||
searchInput.value.$el.value = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
emit('update:modelValue', event)
|
emit('update:modelValue', event)
|
||||||
emit('change', event)
|
emit('change', event)
|
||||||
emitFormChange()
|
emitFormChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onChange (event: any) {
|
||||||
|
query.value = event.target.value
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// eslint-disable-next-line vue/no-dupe-keys
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
ui,
|
ui,
|
||||||
@@ -512,8 +521,10 @@ export default defineComponent({
|
|||||||
trailingWrapperIconClass,
|
trailingWrapperIconClass,
|
||||||
filteredOptions,
|
filteredOptions,
|
||||||
createOption,
|
createOption,
|
||||||
|
// eslint-disable-next-line vue/no-dupe-keys
|
||||||
query,
|
query,
|
||||||
onUpdate
|
onUpdate,
|
||||||
|
onChange
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user