2023-12-19 18:43:42 +01:00
|
|
|
<script setup lang="ts">
|
|
|
|
import type { InputOption } from '~/types'
|
|
|
|
|
|
|
|
const props = defineProps<{
|
|
|
|
options: InputOption[]
|
2024-09-18 10:48:08 +02:00
|
|
|
modelValue: string | number
|
2023-12-19 18:43:42 +01:00
|
|
|
count?: number
|
2024-09-03 17:13:23 +02:00
|
|
|
titleShowCount?: boolean
|
2023-12-19 18:43:42 +01:00
|
|
|
}>()
|
|
|
|
|
|
|
|
const emits = defineEmits(['update:modelValue', 'selected'])
|
|
|
|
|
|
|
|
const selectedValue = useVModel(props, 'modelValue', emits)
|
|
|
|
const isOptionSelected = computed(() => {
|
|
|
|
return props.options.find(option => option.value === selectedValue.value)
|
|
|
|
})
|
2024-09-18 10:48:08 +02:00
|
|
|
function onOptionSelected(value: string | number) {
|
2023-12-19 18:43:42 +01:00
|
|
|
emits('selected', value)
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
2024-09-02 15:13:43 +02:00
|
|
|
<HeadlessListbox
|
|
|
|
v-model="selectedValue"
|
|
|
|
as="div"
|
|
|
|
>
|
2024-09-03 17:13:23 +02:00
|
|
|
<div class="relative font-700 font-24px">
|
2023-12-19 18:43:42 +01:00
|
|
|
<HeadlessListboxButton
|
2024-09-18 20:46:47 +02:00
|
|
|
class="relative cursor-pointer py-6px px-14px text-left border-2px bg-app-white text-app-black text-xs sm:text-sm sm:leading-6"
|
2023-12-19 18:43:42 +01:00
|
|
|
>
|
2024-09-03 17:13:23 +02:00
|
|
|
<span class="block truncate mr-8px font">{{ isOptionSelected?.label }} <span
|
|
|
|
v-if="titleShowCount"
|
|
|
|
opacity-50
|
|
|
|
>({{ isOptionSelected?.count }})</span></span>
|
2023-12-19 18:43:42 +01:00
|
|
|
<span class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
2024-09-02 15:13:43 +02:00
|
|
|
<UnoIcon
|
2024-09-12 08:42:37 +02:00
|
|
|
i-ic-baseline-arrow-drop-down
|
2024-09-03 17:13:23 +02:00
|
|
|
text-app-black
|
2024-09-02 15:13:43 +02:00
|
|
|
/>
|
2023-12-19 18:43:42 +01:00
|
|
|
</span>
|
|
|
|
</HeadlessListboxButton>
|
|
|
|
|
|
|
|
<transition
|
2024-09-02 15:13:43 +02:00
|
|
|
leave-active-class="transition ease-in duration-100"
|
|
|
|
leave-from-class="opacity-100"
|
2023-12-19 18:43:42 +01:00
|
|
|
leave-to-class="opacity-0"
|
|
|
|
>
|
|
|
|
<HeadlessListboxOptions
|
2024-09-03 17:13:23 +02:00
|
|
|
class="absolute z-100 max-h-60 w-auto border-2px border-t-0 overflow-auto bg-app-black text-app-white focus:outline-none sm:text-sm"
|
2023-12-19 18:43:42 +01:00
|
|
|
>
|
|
|
|
<HeadlessListboxOption
|
|
|
|
v-for="option in props.options"
|
2024-09-02 15:13:43 +02:00
|
|
|
:key="option.value"
|
|
|
|
v-slot="{ active, selected }"
|
|
|
|
as="template"
|
|
|
|
:value="option.value"
|
|
|
|
@click="onOptionSelected(option.value)"
|
2023-12-19 18:43:42 +01:00
|
|
|
>
|
|
|
|
<li
|
2024-09-03 17:13:23 +02:00
|
|
|
class="w-full relative cursor-pointer select-none py-8px p-16px bg-app-black text-app-white"
|
|
|
|
:class="[active ? 'text-app-white' : 'text-app-white']"
|
2023-12-19 18:43:42 +01:00
|
|
|
>
|
2024-09-02 15:13:43 +02:00
|
|
|
<span
|
|
|
|
class="block truncate"
|
|
|
|
:class="[selected ? 'font-semibold' : 'font-normal']"
|
|
|
|
>
|
2023-12-19 18:43:42 +01:00
|
|
|
{{ option.label }}
|
2024-09-12 11:56:16 +02:00
|
|
|
<span
|
|
|
|
v-if="titleShowCount"
|
|
|
|
opacity-50
|
|
|
|
>({{ option.count }})</span>
|
2023-12-19 18:43:42 +01:00
|
|
|
</span>
|
|
|
|
</li>
|
|
|
|
</HeadlessListboxOption>
|
|
|
|
</HeadlessListboxOptions>
|
|
|
|
</transition>
|
|
|
|
</div>
|
|
|
|
</HeadlessListbox>
|
|
|
|
</template>
|