@props([
'from' => '',
'to' => '',
'fromName' => 'from',
'toName' => 'to',
'variant' => 'admin', // admin|public
'disabled' => false,
'dialogTitle' => null,
])
@php
$dialogTitleText = $dialogTitle ?: __('messages.date_range_dialog_title');
$isPublic = $variant === 'public';
$buttonClass = $isPublic
? 'w-full rounded-xl border border-white/30 bg-white/10 text-white hover:bg-white/20 focus:ring-white/55 focus:border-white/55 disabled:opacity-60 disabled:cursor-not-allowed'
: 'w-full rounded-lg theme-btn-outline disabled:opacity-60 disabled:cursor-not-allowed';
$summaryClass = $isPublic ? 'text-white/80' : 'theme-inline-muted';
$panelClass = $isPublic
? 'fixed z-[130] rounded-xl border border-white/25 bg-slate-900/95 text-white shadow-2xl p-3'
: 'fixed z-[130] rounded-xl border border-[var(--theme-border)] bg-[var(--theme-surface)] text-[var(--theme-text)] shadow-2xl p-3';
$inputClass = $isPublic
? 'w-full rounded-xl border-white/25 bg-white/15 text-white focus:ring-white/55 focus:border-white/55'
: 'w-full rounded-lg theme-ring-brand';
@endphp
class('relative') }}
x-data="{
open: false,
panelTop: 0,
panelLeft: 0,
panelWidth: 360,
fromValue: @js((string) ($from ?? '')),
toValue: @js((string) ($to ?? '')),
label() {
if (this.fromValue === '' && this.toValue === '') {
return @js(__('messages.date_range_not_set'));
}
if (this.fromValue !== '' && this.toValue !== '') {
return this.fromValue + ' → ' + this.toValue;
}
return (this.fromValue || this.toValue);
},
togglePanel() {
if (this.open) {
this.open = false;
return;
}
this.open = true;
this.$nextTick(() => this.positionPanel());
},
positionPanel() {
const trigger = this.$refs.trigger;
if (!trigger) {
return;
}
const rect = trigger.getBoundingClientRect();
const viewportWidth = window.innerWidth || document.documentElement.clientWidth || 1024;
const viewportHeight = window.innerHeight || document.documentElement.clientHeight || 768;
const sidePadding = 8;
const panelWidth = Math.min(viewportWidth - (sidePadding * 2), 360);
const estimatedPanelHeight = 240;
let left = rect.left;
const maxLeft = viewportWidth - panelWidth - sidePadding;
if (left > maxLeft) {
left = maxLeft;
}
if (left < sidePadding) {
left = sidePadding;
}
let top = rect.bottom + 8;
if (top + estimatedPanelHeight > viewportHeight - sidePadding) {
top = Math.max(sidePadding, rect.top - estimatedPanelHeight - 8);
}
this.panelLeft = Math.round(left);
this.panelTop = Math.round(top);
this.panelWidth = Math.round(panelWidth);
}
}"
@keydown.escape.window="open = false"
@resize.window="open && positionPanel()"
@scroll.window="open && positionPanel()"
>
{{ $dialogTitleText }}