Unified UI

Modal

A dialog overlay that requires user interaction before returning to the parent view.

Overview

The Modal component provides an accessible dialog overlay for confirmations, forms, and important user interactions. Built on top of Alpine.js for reactivity with smooth transitions out of the box.

Installation

The Modal component is included in the base Unified UI Laravel package:

composer require work-rjkashyap/unified-ui-laravel

Copy the Blade component to your project:

php artisan vendor:publish --tag=unified-ui-components --force

The component will be published to resources/views/components/unified-ui/modal.blade.php.

Usage

Basic Modal

<x-unified-ui::modal>
    <x-slot:trigger>
        <x-unified-ui::button>Open Modal</x-unified-ui::button>
    </x-slot:trigger>

    <x-slot:title>Confirm Action</x-slot:title>

    <p>Are you sure you want to proceed with this action?</p>

    <x-slot:footer>
        <x-unified-ui::button variant="ghost" x-on:click="close()">Cancel</x-unified-ui::button>
        <x-unified-ui::button variant="primary">Confirm</x-unified-ui::button>
    </x-slot:footer>
</x-unified-ui::modal>

Sizes

Control the maximum width of the modal using the size prop.

{{-- Small modal --}}
<x-unified-ui::modal size="sm">
    <x-slot:trigger>
        <x-unified-ui::button>Small</x-unified-ui::button>
    </x-slot:trigger>
    <p>Small modal content.</p>
</x-unified-ui::modal>

{{-- Medium (default) --}}
<x-unified-ui::modal size="md">
    <x-slot:trigger>
        <x-unified-ui::button>Medium</x-unified-ui::button>
    </x-slot:trigger>
    <p>Medium modal content.</p>
</x-unified-ui::modal>

{{-- Large --}}
<x-unified-ui::modal size="lg">
    <x-slot:trigger>
        <x-unified-ui::button>Large</x-unified-ui::button>
    </x-slot:trigger>
    <p>Large modal content.</p>
</x-unified-ui::modal>

{{-- Extra large --}}
<x-unified-ui::modal size="xl">
    <x-slot:trigger>
        <x-unified-ui::button>Extra Large</x-unified-ui::button>
    </x-slot:trigger>
    <p>Extra large modal content.</p>
</x-unified-ui::modal>

With Form

Modals work seamlessly with Laravel forms:

<x-unified-ui::modal>
    <x-slot:trigger>
        <x-unified-ui::button>Edit Profile</x-unified-ui::button>
    </x-slot:trigger>

    <x-slot:title>Edit Profile</x-slot:title>
    <x-slot:description>Update your account information below.</x-slot:description>

    <form method="POST" action="{{ route('profile.update') }}">
        @csrf
        @method('PATCH')

        <div class="space-y-4">
            <x-unified-ui::input
                label="Name"
                name="name"
                :value="old('name', $user->name)"
            />

            <x-unified-ui::input
                label="Email"
                type="email"
                name="email"
                :value="old('email', $user->email)"
            />
        </div>

        <x-slot:footer>
            <x-unified-ui::button variant="ghost" x-on:click="close()">Cancel</x-unified-ui::button>
            <x-unified-ui::button type="submit" variant="primary">Save Changes</x-unified-ui::button>
        </x-slot:footer>
    </form>
</x-unified-ui::modal>

Livewire Integration

Use the modal with Livewire for dynamic interactions:

{{-- In your Livewire component view --}}
<x-unified-ui::modal wire:model="showDeleteConfirmation">
    <x-slot:title>Delete Item</x-slot:title>
    <x-slot:description>This action cannot be undone.</x-slot:description>

    <p>Are you sure you want to delete <strong>{{ $itemName }}</strong>?</p>

    <x-slot:footer>
        <x-unified-ui::button variant="ghost" wire:click="$set('showDeleteConfirmation', false)">
            Cancel
        </x-unified-ui::button>
        <x-unified-ui::button variant="destructive" wire:click="deleteItem">
            Delete
        </x-unified-ui::button>
    </x-slot:footer>
</x-unified-ui::modal>

Preventing Close on Overlay Click

<x-unified-ui::modal :close-on-overlay="false">
    <x-slot:trigger>
        <x-unified-ui::button>Persistent Modal</x-unified-ui::button>
    </x-slot:trigger>

    <x-slot:title>Important Notice</x-slot:title>

    <p>You must acknowledge this message before continuing.</p>

    <x-slot:footer>
        <x-unified-ui::button variant="primary" x-on:click="close()">I Understand</x-unified-ui::button>
    </x-slot:footer>
</x-unified-ui::modal>

Props

PropTypeDefaultDescription
sizestring"md"Maximum width of the modal. One of sm, md, lg, xl, full.
closeOnOverlaybooltrueWhether clicking the overlay backdrop closes the modal.
closeOnEscapebooltrueWhether pressing Escape closes the modal.
wire:modelstringLivewire property binding for programmatic open/close.

Slots

SlotDescription
triggerThe element that opens the modal on click.
titleThe modal header title text.
descriptionOptional description text below the title.
defaultThe main body content of the modal.
footerFooter area, typically used for action buttons.

Accessibility

  • Focus is trapped within the modal while open.
  • Pressing Escape closes the modal (configurable).
  • The overlay provides a visible backdrop and can be clicked to dismiss.
  • role="dialog" and aria-modal="true" are applied automatically.
  • Title slot is linked via aria-labelledby.
  • Description slot is linked via aria-describedby.

The modal manages focus restoration — when the modal closes, focus returns to the trigger element that opened it.

On this page