2024-01-31 13:18:59 +00:00
|
|
|
@props([
|
|
|
|
|
'title' => 'Are you sure?',
|
|
|
|
|
'buttonTitle' => 'Open Modal',
|
|
|
|
|
'isErrorButton' => false,
|
2024-10-30 13:54:27 +00:00
|
|
|
'isHighlightedButton' => false,
|
2024-01-31 13:18:59 +00:00
|
|
|
'disabled' => false,
|
|
|
|
|
'action' => 'delete',
|
2024-02-04 13:07:08 +00:00
|
|
|
'content' => null,
|
2024-06-24 12:47:55 +00:00
|
|
|
'closeOutside' => true,
|
2025-10-09 10:53:57 +00:00
|
|
|
'isFullWidth' => false,
|
2026-07-08 11:35:09 +00:00
|
|
|
'wireIgnore' => true,
|
2026-08-03 21:11:54 +00:00
|
|
|
// Optional Livewire bool property to entangle open state (survives Livewire re-renders).
|
|
|
|
|
'wireOpen' => null,
|
2026-08-05 14:24:31 +00:00
|
|
|
'contentClicks' => true,
|
2026-08-07 14:22:11 +00:00
|
|
|
'isLarge' => false,
|
2024-01-31 13:18:59 +00:00
|
|
|
])
|
2025-11-14 09:05:00 +00:00
|
|
|
|
|
|
|
|
@php
|
|
|
|
|
$modalId = 'modal-' . uniqid();
|
|
|
|
|
@endphp
|
|
|
|
|
|
2026-08-03 21:11:54 +00:00
|
|
|
<div x-data="{ modalOpen: @if ($wireOpen) $wire.entangle(@js($wireOpen)) @else false @endif }"
|
2025-10-09 10:53:57 +00:00
|
|
|
x-init="$watch('modalOpen', value => { if (!value) { $wire.dispatch('modalClosed') } })"
|
|
|
|
|
:class="{ 'z-40': modalOpen }" @keydown.window.escape="modalOpen=false"
|
2026-08-03 21:11:54 +00:00
|
|
|
{{ $attributes->class(['relative', $isFullWidth ? 'h-full w-full' : 'h-auto w-auto']) }}
|
|
|
|
|
@close-modal.window="modalOpen=false" @if ($wireIgnore) wire:ignore @endif>
|
2024-02-04 13:07:08 +00:00
|
|
|
@if ($content)
|
2026-08-05 14:24:31 +00:00
|
|
|
<div @if ($contentClicks) @click="modalOpen=true" @endif @class(['h-full w-full' => $isFullWidth])>
|
2024-02-04 13:07:08 +00:00
|
|
|
{{ $content }}
|
|
|
|
|
</div>
|
2024-01-31 13:18:59 +00:00
|
|
|
@else
|
2024-02-04 13:07:08 +00:00
|
|
|
@if ($disabled)
|
2025-10-09 10:53:57 +00:00
|
|
|
<x-forms.button isError disabled @class(['w-full' => $isFullWidth])>{{ $buttonTitle }}</x-forms.button>
|
2024-02-04 13:07:08 +00:00
|
|
|
@elseif ($isErrorButton)
|
2025-10-09 10:53:57 +00:00
|
|
|
<x-forms.button isError @click="modalOpen=true" @class(['w-full' => $isFullWidth])>{{ $buttonTitle }}</x-forms.button>
|
2024-10-30 13:54:27 +00:00
|
|
|
@elseif ($isHighlightedButton)
|
2025-10-09 10:53:57 +00:00
|
|
|
<x-forms.button isHighlighted @click="modalOpen=true" @class(['w-full' => $isFullWidth])>{{ $buttonTitle }}</x-forms.button>
|
2024-02-04 13:07:08 +00:00
|
|
|
@else
|
2025-10-09 10:53:57 +00:00
|
|
|
<x-forms.button @click="modalOpen=true" @class(['w-full' => $isFullWidth])>{{ $buttonTitle }}</x-forms.button>
|
2024-02-04 13:07:08 +00:00
|
|
|
@endif
|
2024-01-31 13:18:59 +00:00
|
|
|
@endif
|
|
|
|
|
<template x-teleport="body">
|
2024-06-24 12:47:55 +00:00
|
|
|
<div x-show="modalOpen"
|
2025-10-01 16:43:32 +00:00
|
|
|
x-init="$watch('modalOpen', value => { if(value) { $nextTick(() => { const firstInput = $el.querySelector('input, textarea, select'); firstInput?.focus(); }) } })"
|
2026-04-17 10:42:22 +00:00
|
|
|
class="fixed inset-0 z-99 overflow-y-auto">
|
2024-05-29 08:43:49 +00:00
|
|
|
<div x-show="modalOpen" x-transition:enter="ease-out duration-100" x-transition:enter-start="opacity-0"
|
2024-01-31 15:14:12 +00:00
|
|
|
x-transition:enter-end="opacity-100" x-transition:leave="ease-in duration-100"
|
2024-03-20 11:54:06 +00:00
|
|
|
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"
|
2026-08-03 21:11:54 +00:00
|
|
|
class="absolute inset-0 w-full h-full bg-black/50 backdrop-blur-[2px]"></div>
|
2026-09-02 08:22:44 +00:00
|
|
|
<div @if ($closeOutside) @click.self="modalOpen=false" @endif class="relative flex min-h-full items-start justify-center p-2 sm:items-center sm:p-4">
|
2026-04-17 10:42:22 +00:00
|
|
|
<div id="{{ $modalId }}" x-show="modalOpen" x-trap.inert.noscroll="modalOpen"
|
|
|
|
|
x-transition:enter="ease-out duration-100"
|
|
|
|
|
x-transition:enter-start="opacity-0 -translate-y-2 sm:scale-95"
|
|
|
|
|
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
|
|
|
|
|
x-transition:leave="ease-in duration-100"
|
|
|
|
|
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
|
|
|
|
|
x-transition:leave-end="opacity-0 -translate-y-2 sm:scale-95"
|
2026-08-07 14:22:11 +00:00
|
|
|
@class([
|
|
|
|
|
'application-settings-form application-settings-section relative flex max-h-[calc(100dvh-2rem)] w-full flex-col overflow-hidden',
|
|
|
|
|
'lg:w-[95vw]! lg:max-w-7xl!' => $isLarge,
|
|
|
|
|
'lg:w-auto lg:min-w-2xl lg:max-w-4xl' => ! $isLarge,
|
|
|
|
|
])
|
2026-08-03 21:11:54 +00:00
|
|
|
style="box-shadow: 0 0 0 1px var(--coollabs-hairline), var(--shadow-modal)">
|
2026-09-02 08:22:44 +00:00
|
|
|
<header class="flex-wrap! sm:flex-nowrap!">
|
2026-08-03 21:11:54 +00:00
|
|
|
<h3 class="min-w-0 flex-1 truncate">{{ $title }}</h3>
|
2026-08-07 14:22:11 +00:00
|
|
|
@isset($headerActions)
|
2026-09-02 08:22:44 +00:00
|
|
|
<div class="order-3 w-full sm:order-none sm:w-auto flex shrink-0 items-center gap-2">
|
2026-08-07 14:22:11 +00:00
|
|
|
{{ $headerActions }}
|
|
|
|
|
</div>
|
|
|
|
|
@endisset
|
2026-08-03 21:11:54 +00:00
|
|
|
<button type="button" @click="modalOpen=false"
|
2026-09-02 08:22:44 +00:00
|
|
|
class="order-2 sm:order-none flex size-7 shrink-0 cursor-pointer items-center justify-center rounded-md text-neutral-500 outline-0 transition-colors hover:bg-neutral-100 hover:text-black focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-accent dark:text-fg-faint dark:hover:bg-white/[0.06] dark:hover:text-fg">
|
2026-08-03 21:11:54 +00:00
|
|
|
<x-reicon name="x" class="size-4" />
|
2026-04-17 10:42:22 +00:00
|
|
|
</button>
|
2026-08-03 21:11:54 +00:00
|
|
|
</header>
|
2026-09-02 08:22:44 +00:00
|
|
|
<div @class([
|
|
|
|
|
'application-settings-section-body min-h-0 flex-1 overflow-y-auto',
|
|
|
|
|
'mt-2 sm:mt-0' => isset($headerActions),
|
|
|
|
|
])
|
2026-06-03 09:39:43 +00:00
|
|
|
style="-webkit-overflow-scrolling: touch;">
|
2026-04-17 10:42:22 +00:00
|
|
|
{{ $slot }}
|
|
|
|
|
</div>
|
2024-01-31 13:18:59 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
</div>
|