# Alert Dialog

A modal dialog that interrupts the user with important content and expects a response.

- Install: `php artisan blatui:add alert-dialog`
- Source: https://blatui.remix-it.com/r/alert-dialog.json
- Composer: `composer require gehrisandro/tailwind-merge-laravel`
- npm: `npm install -D @alpinejs/focus`

## resources/views/components/ui/alert-dialog.blade.php

```blade
{{--
    Alert-dialog root (confirm). Holds the open state.
      open  initial open state
      id    optional — enables "dispatchable" mode: opens/closes from anywhere via
            $dispatch('open-alert-dialog-{id}') / $dispatch('close-alert-dialog-{id}').
            Ideal for a single shared confirm driven by per-row delete buttons in a
            @foreach (use <x-ui.alert-dialog-trigger for="{id}">). Pass row context in the
            event detail and read it from $event.detail in the dialog scope.
--}}
@props(['open' => false, 'id' => null])

<div
    data-slot="alert-dialog"
    x-data="{ open: @js((bool) $open) }"
    @if ($id)
        @open-alert-dialog-{{ $id }}.window="open = true"
        @close-alert-dialog-{{ $id }}.window="open = false"
    @endif
    x-id="['blat-alert-dialog']"
    {{ $attributes }}
>
    {{ $slot }}
</div>
```

## resources/views/components/ui/alert-dialog-action.blade.php

```blade
@php
    $userClick = $attributes->get('@click') ?? $attributes->get('x-on:click');
    $attributes = $attributes->except(['@click', 'x-on:click']);
    $clickExpr = collect([$userClick, 'open = false'])->filter()->implode('; ');
@endphp

<button
    type="button"
    @click="{{ $clickExpr }}"
    data-slot="alert-dialog-action"
    {{ $attributes->twMerge("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] bg-primary text-primary-foreground shadow-xs hover:bg-primary/90 h-9 px-4 py-2 has-[>svg]:px-3") }}
>
    {{ $slot }}
</button>
```

## resources/views/components/ui/alert-dialog-cancel.blade.php

```blade
@php
    $userClick = $attributes->get('@click') ?? $attributes->get('x-on:click');
    $attributes = $attributes->except(['@click', 'x-on:click']);
    $clickExpr = collect([$userClick, 'open = false'])->filter()->implode('; ');
@endphp

<button
    type="button"
    @click="{{ $clickExpr }}"
    data-slot="alert-dialog-cancel"
    {{ $attributes->twMerge("inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 h-9 px-4 py-2 has-[>svg]:px-3") }}
>
    {{ $slot }}
</button>
```

## resources/views/components/ui/alert-dialog-content.blade.php

```blade
<template x-teleport="body">
    <div x-show="open" x-cloak class="fixed inset-0 z-50">
        <div
            x-show="open"
            role="presentation"
            aria-hidden="true"
            data-slot="alert-dialog-overlay"
            x-transition:enter="transition ease-out duration-200"
            x-transition:enter-start="opacity-0"
            x-transition:enter-end="opacity-100"
            x-transition:leave="transition ease-in duration-150"
            x-transition:leave-start="opacity-100"
            x-transition:leave-end="opacity-0"
            class="fixed inset-0 z-50 bg-black/50"
        ></div>

        <div
            x-show="open"
            x-trap.noscroll.inert="open"
            @keydown.escape.window="open = false"
            :id="$id('blat-alert-dialog')"
            x-blat-labelledby="{ label: '[data-slot=alert-dialog-title]', description: '[data-slot=alert-dialog-description]' }"
            role="alertdialog"
            aria-modal="true"
            tabindex="-1"
            data-slot="alert-dialog-content"
            x-transition:enter="transition ease-out duration-200"
            x-transition:enter-start="opacity-0 scale-95"
            x-transition:enter-end="opacity-100 scale-100"
            x-transition:leave="transition ease-in duration-150"
            x-transition:leave-start="opacity-100 scale-100"
            x-transition:leave-end="opacity-0 scale-95"
            {{ $attributes->twMerge('bg-background fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg sm:max-w-lg') }}
        >
            {{ $slot }}
        </div>
    </div>
</template>
```

## resources/views/components/ui/alert-dialog-description.blade.php

```blade
<p data-slot="alert-dialog-description" {{ $attributes->twMerge('text-muted-foreground text-sm') }}>{{ $slot }}</p>
```

## resources/views/components/ui/alert-dialog-footer.blade.php

```blade
<div data-slot="alert-dialog-footer" {{ $attributes->twMerge('flex flex-col-reverse gap-2 sm:flex-row sm:justify-end') }}>{{ $slot }}</div>
```

## resources/views/components/ui/alert-dialog-header.blade.php

```blade
<div data-slot="alert-dialog-header" {{ $attributes->twMerge('flex flex-col gap-2 text-center sm:text-left') }}>{{ $slot }}</div>
```

## resources/views/components/ui/alert-dialog-title.blade.php

```blade
<h2 data-slot="alert-dialog-title" {{ $attributes->twMerge('text-lg font-semibold') }}>{{ $slot }}</h2>
```

## resources/views/components/ui/alert-dialog-trigger.blade.php

```blade
{{-- for: when set, opens a dispatchable alert-dialog defined elsewhere via
     $dispatch('open-alert-dialog-{for}'). Pass row context in the event detail:
     x-on:click="$dispatch('open-alert-dialog-{for}', { id: row.id })". Otherwise opens
     the alert-dialog in the same scope. --}}
@props(['for' => null])

<span
    @if ($for)
        x-data
        @click="$dispatch('open-alert-dialog-{{ $for }}')"
        aria-haspopup="dialog"
    @else
        @click="open = true"
        x-blat-trigger="{ haspopup: 'dialog', controls: $id('blat-alert-dialog') }"
    @endif
    data-slot="alert-dialog-trigger"
    {{ $attributes->twMerge('inline-block') }}
>
    {{ $slot }}
</span>
```
