fix: change select component

This commit is contained in:
kur0nek-o
2024-02-23 10:41:54 +07:00
parent 7464cb6d1c
commit d7917fd499
9 changed files with 2713 additions and 278 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4,16 +4,8 @@ interface DataItem {
name: any
}
import { ref, computed, watch } from 'vue'
import {
Combobox,
ComboboxInput,
ComboboxButton,
ComboboxOptions,
ComboboxOption,
TransitionRoot
} from '@headlessui/vue'
import { CheckIcon, ChevronUpDownIcon } from '@heroicons/vue/20/solid'
import { ref, computed } from 'vue'
import { RichSelect } from '@flavorly/vanilla-components'
const props = defineProps({
placeholder: {
@ -32,106 +24,24 @@ const props = defineProps({
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 }
}
})
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)
const selected = ref(data.value[0].id)
</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"
:placeholder="selected.name"
:displayValue="(item: any) => (show || open ? '' : item.name)"
@change="query = $event.target.value"
/>
<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
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>
<div class="w-full">
<RichSelect
v-model="selected"
:options="data"
:clearable="false"
valueAttribute="id"
textAttribute="name"
@update:modelValue="
(value: any) =>
emit(
'update:selected',
data.find((item) => item.id === value)
)
"
/>
</div>
</template>

View File

@ -7,14 +7,30 @@ import router from './router'
import { createApp, provide, h } from 'vue'
import { DefaultApolloClient } from '@vue/apollo-composable'
import { apolloClient } from './utils/graphql'
import { VanillaComponents, defineConfiguration } from '@flavorly/vanilla-components'
const app = createApp({
setup() {
provide(DefaultApolloClient, apolloClient())
},
render: () => h(App),
render: () => h(App)
})
app.use(
VanillaComponents,
defineConfiguration({
RichSelect: {
classes: {
trigger:
'bg-gray-200 border-none 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 relative flex items-center justify-between w-full focus:z-10 cursor-pointer text-sm transition duration-100 ease-in-out disabled:opacity-50 disabled:cursor-not-allowed px-4 py-3',
searchInput:
'inline-block 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 w-full text-sm px-4 py-2.5 text-gray-700 placeholder-gray-500/60 border-0 rounded-lg bg-gray-200',
selectedHighlightedOption: 'font-semibold bg-teal-600 focus:outline-none text-white'
}
}
})
)
app.use(createPinia())
app.use(router)
app.mount('#app')
app.mount('#app')

View File

@ -0,0 +1 @@
declare module '@flavorly/vanilla-components'

View File

@ -1 +1,33 @@
<template></template>
<script setup lang="ts">
import { RichSelect } from '@flavorly/vanilla-components'
import { ref } from 'vue'
const value = ref('Option 1')
const options = [
{ value: 'Option 1', text: 'One Option' },
{ value: 'Option 2', text: 'Two Options' },
{ value: [{ anotherObject: true, nested: 'deep' }], text: 'Complex Object' },
{
value: 'seprator',
text: 'A sperator can be usefull',
children: [
{ value: 'Option 4', text: '4th Option' },
{ value: 'Option 5', text: '5th Option' }
]
}
]
</script>
<template>
<div class="container bg-red-300 m-auto p-5">
<div class="w-full">
<RichSelect
v-model="value"
name="test"
:options="options"
:clearable="true"
placeholder="Please select an option"
/>
</div>
</div>
</template>