AlpineJs modal component

Published Nov 30 2024

<div 
		 x-data="{show: true}" 
		 x-show="show" 
		 class="relative z-20" 
		 aria-labelledby="modal-title" 
		 role="dialog" aria-modal="true" id="{{ $id }}">
    <template x-teleport="#{{$id}}-trigger">
        <div x-on:click="show = !show">
            {{ $trigger }}
        </div>
    </template>
    <div class="fixed inset-0 bg-gray-900/75 transition-opacity" aria-hidden="true"></div>

    <div class="fixed inset-0 z-10 w-screen overflow-y-auto">
        <div class="flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
            <div
                x-on:click.away="show = false"
                class="w-full max-w-2xl relative transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left shadow-xl transition-all">
                @if (isset($header))
                    <div class="border-b border-gray-300 pb-2 mb-2">
                        {{ $header }}
                    </div>
                @endif
                <div>
                    {{ $slot }}
                </div>
                <div class="mt-5 sm:mt-6">
                    @if (isset($footer))
                    <div class="border-b border-gray-300 pb-2 mb-2">
                        {{ $footer }}
                    </div>
                    @endif
                </div>
            </div>
        </div>
    </div>
</div>

Example

<x-ui.modal id="new-resource-modal">
		<x-slot name="trigger">
				<x-button>New Resource</x-button>
		</x-slot>
		<x-slot name="header">
				<h2 class="text-md font-bold">New Resource</h2>
		</x-slot>
		<livewire:forms.resource-form />
</x-ui.modal>

And you can just add a div with the ID new-resource-modal-trigger wherever you want in the document and the trigger will show up there.