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 / wirekit-command-palette-close { name } ESC and item-click close it too. This row said show-only while the component page shipped a Close button dispatching the second event — the listener is registered now, so the pair matches the rest of the table.
<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.

Was this page helpful?

Voting requires cookies or local storage. What we store