explorer-app/components/CategorySelectBox.vue

86 lines
2.8 KiB
Vue
Raw Normal View History

2023-12-19 18:43:42 +01:00
<script setup lang="ts">
import type { InputOption } from '~/types'
const props = defineProps<{
name: string
2023-12-19 18:43:42 +01:00
options: InputOption[]
modelValue: string | number
2023-12-19 18:43:42 +01:00
count?: number
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)
})
function onOptionSelected(value: string | number) {
2023-12-19 18:43:42 +01:00
emits('selected', value)
}
</script>
<template>
<HeadlessListbox
v-model="selectedValue"
as="div"
>
<div class="relative font-700 font-24px">
2023-12-19 18:43:42 +01:00
<HeadlessListboxButton
:id="`headless-listbox-button-${name}`"
2024-10-03 15:53:44 +02:00
class="w-full 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"
2024-09-27 12:14:49 +02:00
hover="bg-app-black text-app-white"
transition="all"
duration-250
2024-09-23 21:14:59 +02:00
:class="{ 'text-app-danger!': isOptionSelected?.value === 'sunset' }"
2023-12-19 18:43:42 +01: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">
<UnoIcon
i-ic-baseline-arrow-drop-down
text-app-black
/>
2023-12-19 18:43:42 +01:00
</span>
</HeadlessListboxButton>
<transition
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-10-03 15:53:44 +02:00
class="absolute z-100 max-h-60 w-fit 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"
: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
class="w-full relative cursor-pointer select-none py-8px p-16px bg-app-black text-app-white"
2024-09-23 21:14:59 +02:00
:class="[active ? 'text-app-white' : 'text-app-white', { 'text-app-danger!': option.value === 'sunset' }]"
2023-12-19 18:43:42 +01:00
>
<span
class="block truncate"
:class="[selected ? 'font-semibold' : 'font-normal']"
>
2023-12-19 18:43:42 +01:00
{{ option.label }}
<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>