apkt-eis/src/components/Select.vue
probdg f8349ad88c Refactor Select component and update Type1.vue
The commit message suggests that the developer refactored the Select component and made updates to the Type1.vue file.
2024-02-06 18:22:17 +07:00

117 lines
3.7 KiB
Vue

<script setup lang="ts">
interface DataItem {
id: number;
name: string;
}
import { ref, computed, watch } from 'vue'
import {
Combobox,
ComboboxInput,
ComboboxButton,
ComboboxOptions,
ComboboxOption,
TransitionRoot
} from '@headlessui/vue'
import { CheckIcon, ChevronUpDownIcon } from '@heroicons/vue/20/solid'
const props = defineProps({
placeholder: {
type: String,
default: '0'
},
data: {
type: Array as () => DataItem[],
default: []
},
selected: {
type: Object as () => DataItem,
default: () => ({ id: 0, name: '' })
}
})
const emit = defineEmits(["update:selected"])
const data = computed(() => [{ id:0, name: props.placeholder }, ...props.data]);
computed(() => {
if (props.selected.id === 0) {
selected.value = { id:0, name: props.placeholder }
}
console.log('selected', selected.value.name);
})
watch(() => props.selected, (value) => {
if (value.id === 0) {
selected.value = { id:0, name: props.placeholder }
}
})
let selected = ref<DataItem>(data.value[0])
let query = ref('')
let filteredData = computed(() =>
query.value === ''
? data.value
: data.value.filter((item: DataItem) =>
item.name
.toLowerCase()
.replace(/\s+/g, '')
.includes(query.value.toLowerCase().replace(/\s+/g, ''))
)
)
const show = ref(false)
</script>
<template>
<Combobox
@update:modelValue="value => emit('update:selected', value)"
v-model="selected" v-slot="{ open }">
<div class="relative mt-1">
<div
class="relative w-full cursor-default overflow-hidden rounded-lg bg-gray-200 text-left focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-teal-300 sm:text-sm">
<ComboboxInput class="w-full border-none py-2 pl-3 pr-10 bg-gray-200 text-sm leading-5 text-gray-900 focus:ring-0"
:displayValue="(item: any) => (show || open ? '' : item.name)" @change="query = $event.target.value"
@click="show = true" @blur="show = false" defaultValue="" />
<ComboboxButton class="absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronUpDownIcon class="h-5 w-5 text-gray-400" aria-hidden="true" />
</ComboboxButton>
</div>
<TransitionRoot :show="show || open"
leave="transition ease-in duration-100" leaveFrom="opacity-100"
leaveTo="opacity-0" @after-leave="query = ''">
<ComboboxOptions static
class="absolute mt-1 z-10 max-h-60 w-full overflow-auto rounded-md bg-gray-200 py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
<div v-if="filteredData.length === 0 && query !== ''"
class="relative cursor-default select-none py-2 px-4 text-gray-700">
Nothing found.
</div>
<ComboboxOption v-for="item in filteredData"
as="template" :key="item.id" :value="item"
v-slot="{ selected, active }">
<li class="relative cursor-default select-none py-2 pl-10 pr-4" :class="{
'bg-teal-600 text-white': active,
'text-gray-900': !active
}">
<span class="block truncate" :class="{ 'font-medium': selected, 'font-normal': !selected }">
{{ item.name }}
</span>
<span v-if="selected" class="absolute inset-y-0 left-0 flex items-center pl-3"
:class="{ 'text-white': active, 'text-teal-600': !active }">
<CheckIcon class="h-5 w-5" aria-hidden="true" />
</span>
</li>
</ComboboxOption>
</ComboboxOptions>
</TransitionRoot>
</div>
</Combobox>
</template>