85 lines
1.7 KiB
Vue
85 lines
1.7 KiB
Vue
|
<template>
|
||
|
<div class='dropdown'>
|
||
|
<button
|
||
|
id='dropdown-button'
|
||
|
rounded-lg
|
||
|
bg-base2
|
||
|
c-text
|
||
|
p2
|
||
|
b-2
|
||
|
b-text
|
||
|
b-solid
|
||
|
class='dropdown-button'
|
||
|
aria-haspopup='true'
|
||
|
:aria-expanded='isOpen'
|
||
|
@click='() => isOpen = !isOpen'
|
||
|
>
|
||
|
{{ selectedOption || defaultOption }}
|
||
|
</button>
|
||
|
<ul
|
||
|
v-if='isOpen'
|
||
|
bg-base2
|
||
|
c-text
|
||
|
list-none
|
||
|
rounded-lg
|
||
|
p4
|
||
|
b-2
|
||
|
b-text
|
||
|
b-solid
|
||
|
class='dropdown-menu'
|
||
|
role='menu'
|
||
|
aria-labelledby='dropdown-button'
|
||
|
>
|
||
|
<li
|
||
|
v-for='(option, key) in optionsRef'
|
||
|
:key='key'
|
||
|
role='menuitem'
|
||
|
tabindex='0'
|
||
|
@click='selectOption(key)'
|
||
|
@keyup.enter='selectOption(key)'
|
||
|
>
|
||
|
{{ option.name }}
|
||
|
</li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script setup lang="ts">
|
||
|
import { ref } from 'vue'
|
||
|
import { useCookie } from '#imports'
|
||
|
|
||
|
// Define props types
|
||
|
const props = defineProps<{
|
||
|
options: Record<string, { name: string }>
|
||
|
modelValue: string
|
||
|
defaultOption: string
|
||
|
cookieName: string
|
||
|
}>()
|
||
|
|
||
|
const { options, modelValue, defaultOption, cookieName } = props
|
||
|
|
||
|
const optionsRef = ref(options)
|
||
|
|
||
|
const cookie = useCookie(cookieName)
|
||
|
|
||
|
const isOpen = ref(false)
|
||
|
const selectedOption = ref(options[modelValue]?.name || defaultOption)
|
||
|
|
||
|
const selectOption = (key: string) => {
|
||
|
const option = options[key]
|
||
|
|
||
|
// Update classes to use the selected option
|
||
|
document.body.classList.remove(...Object.keys(options))
|
||
|
document.body.classList.add(key)
|
||
|
|
||
|
// Update cookie
|
||
|
cookie.value = key
|
||
|
|
||
|
// Update selected option
|
||
|
selectedOption.value = option.name
|
||
|
|
||
|
// Close dropdown
|
||
|
isOpen.value = false
|
||
|
}
|
||
|
</script>
|