K
KoreUI

Overlay - Primeros pasos

Overlay

Sistema unificado Livewire para modals, drawers, confirms, bottom sheets y fullscreen overlays.

Demo en vivo

Prueba los overlays directamente. Haz click en los botones para ver el sistema en accion.

Que es el sistema Overlay

Un sistema unificado basado en Livewire para renderizar diferentes tipos de overlays.

El sistema overlay de kore-ui maneja modals, drawers, confirm dialogs, bottom sheets y fullscreen overlays desde una unica infraestructura. Usa un solo manager component que gestiona renderizado, stacking, animaciones y ciclo de vida para todos los tipos.

Modal
Centrado
Drawer
Lateral
Confirm
Compacto
Bottom Sheet
Desde abajo
Fullscreen
Pantalla completa

Requisitos

  1. El paquete kore-ui debe estar instalado y su service provider registrado.
  2. Importar el CSS de kore-ui (incluye el theme de tokens semanticos).
  3. Importar el JavaScript de kore-ui (registra el componente Alpine).
  4. Livewire y Alpine.js deben estar cargados (Livewire 4 incluye Alpine por defecto).

Agregar el Overlay Manager

Coloca el manager en tu layout principal, antes del cierre de body. Solo necesitas uno por pagina.

resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html>
<head>
    @livewireStyles
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
    {{ $slot }}

    <livewire:kore-overlay-manager />

    @livewireScripts
</body>
</html>
<!DOCTYPE html>
<html>
<head>
    @livewireStyles
    @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
    {{ $slot }}

    <livewire:kore-overlay-manager />

    @livewireScripts
</body>
</html>

El manager renderiza un contenedor fijo con backdrop y maneja el montaje/desmontaje de los componentes overlay automaticamente.

Crear tu primer overlay

Crea un componente Livewire que extienda OverlayComponent.

app/Livewire/Overlays/EditProfile.php
&lt;?php

namespace App\Livewire\Overlays;

use KoreUi\Overlay\OverlayComponent;

class EditProfile extends OverlayComponent
{
    public string $name = '';
    public string $email = '';

    public function mount(int $userId): void
    {
        $user = User::findOrFail($userId);
        $this->name = $user->name;
        $this->email = $user->email;
    }

    public function save(): void
    {
        // Logica de guardado...
        $this->close();
    }

    public function render()
    {
        return view('livewire.overlays.edit-profile');
    }
}
&lt;?php

namespace App\Livewire\Overlays;

use KoreUi\Overlay\OverlayComponent;

class EditProfile extends OverlayComponent
{
    public string $name = '';
    public string $email = '';

    public function mount(int $userId): void
    {
        $user = User::findOrFail($userId);
        $this->name = $user->name;
        $this->email = $user->email;
    }

    public function save(): void
    {
        // Logica de guardado...
        $this->close();
    }

    public function render()
    {
        return view('livewire.overlays.edit-profile');
    }
}
resources/views/livewire/overlays/edit-profile.blade.php
<div class="p-6">
    <h2 class="text-lg font-semibold">Editar perfil</h2>

    <form wire:submit="save" class="mt-4 space-y-4">
        <input type="text" wire:model="name"
               class="w-full border rounded px-3 py-2" />
        <input type="email" wire:model="email"
               class="w-full border rounded px-3 py-2" />

        <div class="flex justify-end gap-2">
            <button type="button" wire:click="close"
                    class="px-4 py-2 text-sm">
                Cancelar
            </button>
            <button type="submit"
                    class="px-4 py-2 text-sm bg-kore-primary text-kore-primary-fg rounded">
                Guardar
            </button>
        </div>
    </form>
</div>
<div class="p-6">
    <h2 class="text-lg font-semibold">Editar perfil</h2>

    <form wire:submit="save" class="mt-4 space-y-4">
        <input type="text" wire:model="name"
               class="w-full border rounded px-3 py-2" />
        <input type="email" wire:model="email"
               class="w-full border rounded px-3 py-2" />

        <div class="flex justify-end gap-2">
            <button type="button" wire:click="close"
                    class="px-4 py-2 text-sm">
                Cancelar
            </button>
            <button type="submit"
                    class="px-4 py-2 text-sm bg-kore-primary text-kore-primary-fg rounded">
                Guardar
            </button>
        </div>
    </form>
</div>

Abrir un overlay

Despacha el evento kore:open con el nombre del componente Livewire.

Abrir desde un boton
<button
    x-on:click="$dispatch('kore:open', { name: 'overlays.edit-profile' })"
>
    Editar perfil
</button>
<button
    x-on:click="$dispatch('kore:open', { name: 'overlays.edit-profile' })"
>
    Editar perfil
</button>

El valor de name es el nombre estandar del componente Livewire (dot-notation o kebab-case). El ComponentResolver valida que la clase implemente la interfaz Overlayable.

Pasar argumentos

Usa el objeto arguments para pasar datos al metodo mount() del componente.

Con argumentos
<button
    x-on:click="$dispatch('kore:open', {
        name: 'overlays.edit-profile',
        arguments: { userId: {{ $user->id }} }
    })"
>
    Editar perfil
</button>
<button
    x-on:click="$dispatch('kore:open', {
        name: 'overlays.edit-profile',
        arguments: { userId: {{ $user->id }} }
    })"
>
    Editar perfil
</button>

Los argumentos se pasan directamente al componente Livewire: arguments: { userId: 5 } llama a mount(int $userId) con 5.

Cerrar un overlay

Se puede cerrar desde PHP o desde Blade.

Desde PHP (dentro del componente overlay)
// Cerrar el overlay actual
$this->close();
// Cerrar el overlay actual
$this->close();
Desde Blade (boton en el template del overlay)
<button wire:click="close">Cancelar</button>
<button wire:click="close">Cancelar</button>

El metodo close() despacha kore:close, que el componente Alpine maneja retornando al overlay previo en el stack o ocultando todo.

Ejemplo completo

Un ejemplo minimo con las tres piezas: componente, vista y trigger.

1. Crear el componente — app/Livewire/Overlays/Welcome.php
&lt;?php

namespace App\Livewire\Overlays;

use KoreUi\Overlay\OverlayComponent;

class Welcome extends OverlayComponent
{
    public string $message;

    public function mount(string $message = 'Hola!'): void
    {
        $this->message = $message;
    }

    public function render()
    {
        return view('livewire.overlays.welcome');
    }
}
&lt;?php

namespace App\Livewire\Overlays;

use KoreUi\Overlay\OverlayComponent;

class Welcome extends OverlayComponent
{
    public string $message;

    public function mount(string $message = 'Hola!'): void
    {
        $this->message = $message;
    }

    public function render()
    {
        return view('livewire.overlays.welcome');
    }
}
2. Crear la vista — resources/views/livewire/overlays/welcome.blade.php
<div class="p-6 text-center">
    <p class="text-lg">{{ $message }}</p>
    <button wire:click="close"
            class="mt-4 px-4 py-2 bg-kore-primary text-kore-primary-fg rounded">
        Entendido
    </button>
</div>
<div class="p-6 text-center">
    <p class="text-lg">{{ $message }}</p>
    <button wire:click="close"
            class="mt-4 px-4 py-2 bg-kore-primary text-kore-primary-fg rounded">
        Entendido
    </button>
</div>
3. Abrirlo desde cualquier pagina
<button
    x-on:click="$dispatch('kore:open', {
        name: 'overlays.welcome',
        arguments: { message: 'Bienvenido a kore-ui!' }
    })"
>
    Mostrar bienvenida
</button>
<button
    x-on:click="$dispatch('kore:open', {
        name: 'overlays.welcome',
        arguments: { message: 'Bienvenido a kore-ui!' }
    })"
>
    Mostrar bienvenida
</button>

Eso es todo lo que necesitas. El overlay manager gestiona renderizado, animacion, backdrop, tecla Escape, click-away y limpieza automaticamente.