87 lines
3.2 KiB
Vue
87 lines
3.2 KiB
Vue
<script setup lang="ts">
|
|
const props = withDefaults(defineProps<{
|
|
title?: string
|
|
initialCollapsed?: boolean
|
|
collapsible?: boolean
|
|
positionClass?: string
|
|
topOffsetClass?: string
|
|
bottomOffsetClass?: string
|
|
widthClass?: string
|
|
}>(), {
|
|
title: '',
|
|
initialCollapsed: false,
|
|
collapsible: true,
|
|
positionClass: 'left-4',
|
|
topOffsetClass: 'top-[96px]',
|
|
bottomOffsetClass: 'bottom-4',
|
|
widthClass: 'w-[min(calc(100vw-1rem),440px)] md:w-[420px] xl:w-[460px]',
|
|
})
|
|
|
|
const collapsed = ref(props.initialCollapsed)
|
|
|
|
function toggleCollapsed() {
|
|
collapsed.value = !collapsed.value
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="pointer-events-none fixed z-40" :class="[positionClass, topOffsetClass, bottomOffsetClass]">
|
|
<section
|
|
class="pointer-events-auto flex h-full flex-col overflow-hidden rounded-[28px] border-0 bg-[#f3eee6] text-[#2f2418] shadow-[0_28px_70px_rgba(38,29,18,0.18)]"
|
|
:class="collapsible && collapsed ? 'w-16 rounded-full' : widthClass"
|
|
style="transition: width 260ms ease;"
|
|
>
|
|
<template v-if="collapsible && collapsed">
|
|
<button
|
|
type="button"
|
|
class="flex h-full w-full cursor-pointer flex-col items-center justify-between px-3 py-3 text-left transition hover:bg-[#eee6dc]"
|
|
:aria-expanded="String(!collapsed)"
|
|
:aria-label="$t('ui.expand_panel')"
|
|
@click="toggleCollapsed"
|
|
>
|
|
<span class="flex h-10 w-10 items-center justify-center rounded-full bg-white text-[#5f4b33] transition">
|
|
<svg viewBox="0 0 24 24" fill="none" class="h-4 w-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="m9 6 6 6-6 6" />
|
|
</svg>
|
|
</span>
|
|
|
|
<p v-if="title" class="origin-center whitespace-nowrap -rotate-90 text-[11px] font-bold uppercase tracking-[0.14em] text-[#6f6353]">
|
|
{{ title }}
|
|
</p>
|
|
|
|
<div class="h-10 w-10" aria-hidden="true" />
|
|
</button>
|
|
</template>
|
|
|
|
<template v-else>
|
|
<header v-if="title || $slots.header" class="flex shrink-0 items-start justify-between gap-3 border-b border-[#ded3c2] bg-[#f3eee6] px-5 py-4">
|
|
<div class="min-w-0 flex-1">
|
|
<slot name="header">
|
|
<h1 v-if="title" class="truncate text-xl font-black text-[#2f2418] md:text-2xl">{{ title }}</h1>
|
|
</slot>
|
|
</div>
|
|
<button
|
|
v-if="collapsible"
|
|
type="button"
|
|
class="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-white text-[#5f4b33] transition hover:bg-[#fbf8f4]"
|
|
:aria-label="$t('ui.collapse_panel')"
|
|
@click="toggleCollapsed"
|
|
>
|
|
<svg viewBox="0 0 24 24" fill="none" class="h-4 w-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
<path d="m15 18-6-6 6-6" />
|
|
</svg>
|
|
</button>
|
|
</header>
|
|
|
|
<div class="min-h-0 flex-1 overflow-y-auto p-4 md:p-5">
|
|
<slot />
|
|
</div>
|
|
|
|
<footer v-if="$slots.footer" class="shrink-0 border-t border-[#ded3c2] bg-[#f3eee6] px-4 py-4 md:px-5 md:py-5">
|
|
<slot name="footer" />
|
|
</footer>
|
|
</template>
|
|
</section>
|
|
</div>
|
|
</template>
|