Files
speckle-server/packages/frontend-2/components/layout/Disclosure.vue
T
Kristaps Fabians Geikins b02a07e2b6 feat: Frontend 2.0 MVP
2023-05-08 10:47:01 +03:00

74 lines
1.8 KiB
Vue

<template>
<div>
<Disclosure v-slot="{ open }">
<DisclosureButton :class="buttonClasses">
<div class="inline-flex items-center space-x-2">
<Component :is="icon" v-if="icon" class="h-4 w-4" />
<span>{{ title }}</span>
</div>
<ChevronUpIcon :class="!open ? 'rotate-180 transform' : ''" class="h-5 w-5" />
</DisclosureButton>
<DisclosurePanel :class="panelClasses">
<div class="label-light">
<slot>Panel contents</slot>
</div>
</DisclosurePanel>
</Disclosure>
</div>
</template>
<script setup lang="ts">
import { DisclosureButton, Disclosure, DisclosurePanel } from '@headlessui/vue'
import { ChevronUpIcon } from '@heroicons/vue/24/solid'
import { ConcreteComponent } from 'vue'
type DisclosureColor = 'default' | 'danger'
const props = withDefaults(
defineProps<{
title: string
icon?: ConcreteComponent
color?: DisclosureColor
}>(),
{
color: 'default'
}
)
const buttonClasses = computed(() => {
const classParts = [
'pr-3 h-10 w-full flex items-center justify-between border-l-2 px-2 rounded transition',
'ring-1'
]
switch (props.color) {
case 'danger':
classParts.push('border-danger text-danger ring-danger-lighter hover:ring-danger')
break
case 'default':
default:
classParts.push(
'border-primary text-primary ring-primary-muted hover:ring-primary'
)
break
}
return classParts.join(' ')
})
const panelClasses = computed(() => {
const classParts = ['mt-4 px-3 py-1 border-x ']
switch (props.color) {
case 'danger':
classParts.push('border-danger-lighter')
break
case 'default':
default:
classParts.push('border-primary-muted')
break
}
return classParts.join(' ')
})
</script>