explorer-app/components/SelectBox.vue

79 lines
2.5 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 = withDefaults(defineProps<SelectProps>(), {
isMarginTop: true,
blackAndWhite: true,
2024-09-12 18:03:06 +02:00
borderOpacity: 100,
2023-12-19 18:43:42 +01:00
})
const emits = defineEmits(['update:modelValue'])
interface SelectProps {
options: InputOption[]
2024-09-12 18:03:06 +02:00
label?: string
modelValue: any
2023-12-19 18:43:42 +01:00
isMarginTop?: boolean
blackAndWhite?: boolean
2024-09-12 18:03:06 +02:00
borderOpacity?: number
placeholder?: string
2023-12-19 18:43:42 +01:00
}
const selectedValue = useVModel(props, 'modelValue', emits)
</script>
<template>
<HeadlessListbox
v-model="selectedValue"
as="div"
>
<div
class="relative font-700"
:class="[isMarginTop ? 'mt-2' : 'mt-0', blackAndWhite ? 'bg-app-black' : 'bg-app-white']"
>
2023-12-19 18:43:42 +01:00
<HeadlessListboxButton
2024-09-12 18:03:06 +02:00
class="relative w-full cursor-pointer py-8px p-16px text-left border-2px sm:text-sm sm:leading-6"
:class="[blackAndWhite ? 'text-app-white' : 'text-app-black', `border-white/${borderOpacity}`]"
2023-12-19 18:43:42 +01:00
>
2024-09-12 18:03:06 +02:00
<span
class="block truncate mr-8px"
:class="[selectedValue ? 'text-app-white' : 'font-400 text-white/50']"
>
{{ props.options.find(option => option.value === selectedValue)?.label || props.placeholder }}
</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
:class="[blackAndWhite ? ' text-app-white' : '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-09-12 18:03:06 +02:00
:class="`border-white/${borderOpacity}`"
2023-12-19 18:43:42 +01:00
class="absolute z-100 max-h-60 w-full divide-y-2px border-2px border-t-0 overflow-auto bg-app-black text-app-white focus:outline-none sm:text-sm"
>
<HeadlessListboxOption
v-for="option in props.options"
:key="option.value"
2024-09-12 18:03:06 +02:00
v-slot="{ selected }"
as="template"
:value="option.value"
2024-09-12 18:03:06 +02:00
class="py-8px p-16px cursor-pointer"
:class="`border-white/${borderOpacity}`"
2023-12-19 18:43:42 +01:00
>
2024-09-12 18:03:06 +02:00
<span
class="block truncate"
:class="[selected ? 'font-semibold' : 'font-normal']"
>{{ option.label }}</span>
2023-12-19 18:43:42 +01:00
</HeadlessListboxOption>
</HeadlessListboxOptions>
</transition>
</div>
</HeadlessListbox>
</template>