2024-03-25 09:41:44 +00:00
|
|
|
<div x-data="{
|
2026-04-09 17:51:31 +00:00
|
|
|
dropdownOpen: false,
|
|
|
|
|
panelStyles: '',
|
|
|
|
|
open() {
|
|
|
|
|
this.dropdownOpen = true;
|
|
|
|
|
this.updatePanelPosition();
|
|
|
|
|
},
|
|
|
|
|
close() {
|
|
|
|
|
this.dropdownOpen = false;
|
|
|
|
|
},
|
|
|
|
|
updatePanelPosition() {
|
|
|
|
|
if (window.innerWidth >= 768) {
|
|
|
|
|
this.panelStyles = '';
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
const triggerRect = this.$refs.trigger.getBoundingClientRect();
|
|
|
|
|
const panelRect = this.$refs.panel.getBoundingClientRect();
|
|
|
|
|
const viewportPadding = 8;
|
|
|
|
|
let left = triggerRect.left;
|
|
|
|
|
|
|
|
|
|
if ((left + panelRect.width + viewportPadding) > window.innerWidth) {
|
|
|
|
|
left = window.innerWidth - panelRect.width - viewportPadding;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
left = Math.max(viewportPadding, left);
|
|
|
|
|
|
|
|
|
|
let top = triggerRect.bottom + 4;
|
|
|
|
|
const maxTop = window.innerHeight - panelRect.height - viewportPadding;
|
|
|
|
|
|
|
|
|
|
if (top > maxTop) {
|
|
|
|
|
top = Math.max(viewportPadding, triggerRect.top - panelRect.height - viewportPadding);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.panelStyles = `position: fixed; left: ${left}px; top: ${top}px;`;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}" class="relative" @click.outside="close()" x-on:resize.window="if (dropdownOpen) updatePanelPosition()">
|
|
|
|
|
<button x-ref="trigger" @click="dropdownOpen ? close() : open()"
|
2025-05-14 10:43:23 +00:00
|
|
|
class="inline-flex items-center justify-start pr-8 transition-colors focus:outline-hidden disabled:opacity-50 disabled:pointer-events-none">
|
2024-03-25 09:41:44 +00:00
|
|
|
<span class="flex flex-col items-start h-full leading-none">
|
|
|
|
|
{{ $title }}
|
|
|
|
|
</span>
|
2024-03-26 09:24:53 +00:00
|
|
|
<svg class="absolute right-0 w-4 h-4 mr-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"
|
2024-03-25 09:41:44 +00:00
|
|
|
stroke-width="1.5" stroke="currentColor">
|
|
|
|
|
<path stroke-linecap="round" stroke-linejoin="round"
|
|
|
|
|
d="M8.25 15L12 18.75 15.75 15m-7.5-6L12 5.25 15.75 9" />
|
|
|
|
|
</svg>
|
|
|
|
|
</button>
|
|
|
|
|
|
2026-04-09 17:51:31 +00:00
|
|
|
<div x-ref="panel" x-show="dropdownOpen" @click.away="close()" x-transition:enter="ease-out duration-200"
|
2024-03-25 09:41:44 +00:00
|
|
|
x-transition:enter-start="-translate-y-2" x-transition:enter-end="translate-y-0"
|
2026-04-09 17:51:31 +00:00
|
|
|
:style="panelStyles" class="absolute top-full z-50 mt-1 min-w-max max-w-[calc(100vw-1rem)] md:top-0 md:mt-6" x-cloak>
|
2025-10-01 06:23:35 +00:00
|
|
|
<div
|
2026-04-09 17:51:31 +00:00
|
|
|
class="border border-neutral-300 bg-white p-1 shadow-sm dark:border-coolgray-300 dark:bg-coolgray-200">
|
2024-03-25 09:41:44 +00:00
|
|
|
{{ $slot }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|