53 lines
1.3 KiB
Vue
53 lines
1.3 KiB
Vue
<template>
|
|
<div class="flex flex-col">
|
|
<button class="px-4 py-4" @click="open = !open" :aria-expanded="open">
|
|
<slot name="title" :open="open" :close="close">
|
|
<div class="flex items-center justify-between">
|
|
<span>{{ title }}</span>
|
|
|
|
<ChevronDownIcon class="h-6 w-6" v-if="!open" aria-hidden="true" />
|
|
<ChevronUpIcon class="h-6 w-6" v-else aria-hidden="true" />
|
|
</div>
|
|
</slot>
|
|
</button>
|
|
|
|
<Transition
|
|
enter-active-class="transition-max-height ease-out duration-500"
|
|
enter-from-class="max-h-0"
|
|
enter-to-class="max-h-screen"
|
|
leave-active-class="transition-max-height ease-in duration-250"
|
|
leave-from-class="max-h-screen"
|
|
leave-to-class="max-h-0"
|
|
>
|
|
<div
|
|
v-if="open"
|
|
:class="[
|
|
open ? 'border-t-2 border-gray-100' : '',
|
|
'overflow-hidden px-4 py-4',
|
|
]"
|
|
>
|
|
<slot :close="close" />
|
|
</div>
|
|
</Transition>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ChevronDownIcon, ChevronUpIcon } from '@heroicons/vue/24/outline';
|
|
import { ref } from 'vue';
|
|
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
title?: string;
|
|
open?: boolean;
|
|
}>(),
|
|
{
|
|
open: false,
|
|
}
|
|
);
|
|
|
|
const open = ref(props.open);
|
|
|
|
const close = () => (open.value = false);
|
|
</script>
|