fix(ui): prevent floating dropdown Alpine scope errors (#11311)

This commit is contained in:
Andras Bacsai authored and GitHub committed 2026-08-16 13:44:30 +02:00
1 parent 4c22919d38
commit 9729e765b4
6 files changed
+140 -136

No files matched your search

@@ -6,63 +6,19 @@
@php($panelId = 'table-dropdown-'.uniqid())
<div class="relative" x-data="{
open: false,
positioned: false,
toggle() {
this.open = !this.open;
this.positioned = false;
if (this.open) {
this.$nextTick(() => requestAnimationFrame(() => this.positionPanel()));
}
},
close() {
this.open = false;
this.positioned = false;
},
positionPanel() {
const trigger = this.$refs.trigger;
const panel = document.getElementById(@js($panelId));
if (!trigger || !panel) return;
const gap = 4;
const edge = 12;
const triggerRect = trigger.getBoundingClientRect();
const panelWidth = Math.min(panel.offsetWidth, window.innerWidth - (edge * 2));
const panelHeight = Math.min(panel.scrollHeight, window.innerHeight - (edge * 2));
const fitsBelow = window.innerHeight - triggerRect.bottom - gap >= panelHeight;
const top = fitsBelow
? triggerRect.bottom + gap
: Math.max(edge, triggerRect.top - gap - panelHeight);
const left = window.innerWidth < 768
? (window.innerWidth - panelWidth) / 2
: Math.min(
Math.max(edge, triggerRect.right - panelWidth),
window.innerWidth - panelWidth - edge,
);
panel.style.top = `${top}px`;
panel.style.left = `${left}px`;
panel.style.width = `${panelWidth}px`;
panel.style.maxWidth = `${window.innerWidth - (edge * 2)}px`;
panel.style.maxHeight = `${window.innerHeight - (edge * 2)}px`;
this.positioned = true;
}
}" @click.outside="close()" @keydown.escape.window="close()"
@resize.window="open && positionPanel()" @scroll.window="open && positionPanel()">
<div class="relative"
x-data="floatingDropdown({ panelId: @js($panelId), portal: true, align: 'right', matchTriggerWidth: false })"
@click.outside="close()" @keydown.escape.window="close()"
@resize.window="open && schedulePosition()" @scroll.window="open && schedulePosition()">
<div x-ref="trigger" @click="toggle()">
{{ $trigger }}
</div>
<template x-teleport="body">
<div id="{{ $panelId }}" x-show="open" x-cloak
class="listbox-panel floating-dropdown-panel z-[9999]! {{ $panelClass }}" style="position: fixed; visibility: hidden"
:style="{ visibility: positioned ? 'visible' : 'hidden' }"
x-effect="if (open) requestAnimationFrame(() => positionPanel())" role="{{ $role }}"
@if ($multiselectable) aria-multiselectable="true" @endif>
{{ $slot }}
</div>
</template>
<div id="{{ $panelId }}" x-show="open" x-cloak
class="listbox-panel floating-dropdown-panel z-[9999]! {{ $panelClass }}" style="position: fixed; visibility: hidden"
:style="{ visibility: positioned ? 'visible' : 'hidden' }"
x-effect="if (open) schedulePosition($el)" role="{{ $role }}"
@if ($multiselectable) aria-multiselectable="true" @endif>
{{ $slot }}
</div>
</div>