Skip to main content
WireKit
Copy for LLM

Overlay Events

Every WireKit overlay component is event-controlled — you open it, close it, or scope it via $dispatch from Alpine OR $this->dispatch(...) from a Livewire component. There's no programmatic JS API to import; the event vocabulary IS the API.

This page is the canonical reference for every overlay event the components listen for, including the payload shape and Livewire-side dispatch examples. Each component's own docs page links here for the cross-reference.

Event matrix

Component Event name Payload shape Notes
<x-wirekit::modal> wirekit-modal-show / wirekit-modal-close { name } Dismissible by default — backdrop click + ESC both close.
<x-wirekit::drawer> wirekit-drawer-show / wirekit-drawer-close { name } Same shape as modal.
<x-wirekit::alert-dialog> wirekit-alert-dialog-show / wirekit-alert-dialog-close { name } Non-dismissible by default (safety); ESC always closes; backdrop stays inert without explicit dismissible="true".
<x-wirekit::command-palette> wirekit-command-palette-show { name } Show-only event. Close via the palette's own controls (ESC, item-click).
<x-wirekit::tour> wirekit-tour-start-<name> (name suffixed into the event name) — (no detail) The tour's name prop is appended to the event with a hyphen separator. Example: <x-wirekit::tour name="onboarding"> listens for wirekit-tour-start-onboarding.
<x-wirekit::toast-region> wirekit-toast (global) OR wirekit-toast-<name> (scoped) { title, message, variant, duration? } Different payload from the show/close family — toasts carry their own content.

Shape detail

Most overlays take { name: 'unique-id' } where name matches the component's name="..." prop. Multiple overlays on the same page each listen for their own name; events targeted at a different name are ignored.

Tour is the odd one out — instead of a payload, the tour's name is part of the event NAME itself. $dispatch('wirekit-tour-start-onboarding') starts the tour named onboarding; no payload object needed. This shape is historical; it's documented but kept stable for back-compat.

Toast is also irregular — instead of { name }, the payload carries the toast's CONTENT: { title, message, variant, duration? }. The variant value mirrors the canonical 4-state semantic enum (info / success / warning / danger). The scoping mechanism (which <x-wirekit::toast-region> instance picks up the event) is event-NAME-based: regions with name="..." listen on wirekit-toast-<name>, regions without a name listen on the global wirekit-toast.

Examples — opening from Alpine (client-side)

Trigger a modal from a custom button outside the dialog markup:

<button x-on:click="$dispatch('wirekit-modal-show', { name: 'settings' })">
    Open settings
</button>

<x-wirekit::modal name="settings">
    <x-wirekit::modal.header>Settings</x-wirekit::modal.header>
    <x-wirekit::modal.body>
        ...
    </x-wirekit::modal.body>
</x-wirekit::modal>

Close from inside the modal (Cancel button):

<button x-on:click="$dispatch('wirekit-modal-close', { name: 'settings' })">
    Cancel
</button>

Open a tour by name:

<button x-on:click="$dispatch('wirekit-tour-start-onboarding')">
    Start tour
</button>

Show a toast — global region (single <x-wirekit::toast-region /> on the page):

<button x-on:click="$dispatch('wirekit-toast', {
    title: 'Saved',
    message: 'Your changes are live.',
    variant: 'success',
    duration: 4000
})">
    Save
</button>

Show a toast — scoped region (when multiple regions exist with different name="..." props):

<x-wirekit::toast-region name="critical" />
<x-wirekit::toast-region name="info" />

<button x-on:click="$dispatch('wirekit-toast-critical', {
    title: 'Connection lost',
    message: 'Retrying in 5s...',
    variant: 'danger'
})">
    Simulate connection loss
</button>

Examples — dispatching from Livewire (server-side)

Every Alpine $dispatch call has a 1:1 Livewire equivalent via $this->dispatch(...). Same event name; payload becomes named arguments.

Open a modal from a Livewire method:

public function openSettings(): void
{
    $this->dispatch('wirekit-modal-show', name: 'settings');
}

Show a toast as a flash after a server-side action:

public function save(): void
{
    // ... persist state ...

    $this->dispatch('wirekit-toast',
        title: 'Saved',
        message: 'Your changes are live.',
        variant: 'success',
        duration: 4000,
    );
}

Close an alert-dialog after a destructive confirmation runs:

public function deleteProject(): void
{
    Project::find($this->projectId)->delete();

    $this->dispatch('wirekit-alert-dialog-close', name: 'delete-project');
}

Conventions + footguns

The event vocabulary has a few historical irregularities documented here so AI tooling and LLM-driven scaffolding produce correct code on the first try.

  1. All events use hyphens, not colons. The common Alpine convention namespace:event does NOT apply — WireKit overlays use namespace-action. $dispatch('wirekit:modal-show', ...) silently does nothing. The correct shape is $dispatch('wirekit-modal-show', ...).
  2. <x-wirekit::tour> suffixes the name into the event itself, not the payload. Dispatching wirekit-tour-start-${this.name} rather than wirekit-tour-start with a { name } payload. This was an early-design choice that didn't generalize to the show/close pattern; subsequent overlays standardized on the { name } payload shape.
  3. <x-wirekit::toast-region> uses variant, not intent. The toast payload key is variant: 'info' | 'success' | 'warning' | 'danger' — same value set as badge / alert / callout, but the prop name diverges. See Prop Naming Conventions for the intent / surface / variant / tone family split and the alias matrix.
  4. Show events are fire-and-forget — the dispatcher gets no return value. If you need to act AFTER the overlay opens (e.g. focus a specific input inside the modal once it's mounted), listen for the overlay's own lifecycle event from Alpine inside the panel scope rather than chaining off the dispatch.

Standardization roadmap

A v3.0.0 candidate is to unify the event surface:

  • Standard verb scheme: -show / -close everywhere (toast becomes wirekit-toast-show; tour becomes wirekit-tour-show with { name } payload).
  • Standard payload shape: { name, ...extras } everywhere. Toast carries { name, title, message, intent, duration? }variant migrates to intent for cross-component consistency.

This is intentionally NOT shipping in v2.x — back-compat fence. Until then, the matrix above is the contract, and the event names in it keep working unchanged for the whole of v2.