@props([ 'anchor' => 'se', ]) @php use App\Support\Ui\Pulse; $seed = Pulse::pending(); $anchorClass = match ($anchor) { 'nw' => 'top-4 left-4 items-start', 'n' => 'top-4 inset-x-0 items-center', 'ne' => 'top-4 right-4 items-end', 'sw' => 'bottom-4 left-4 items-start', 's' => 'bottom-4 inset-x-0 items-center', default => 'bottom-4 right-4 items-end', }; @endphp
class(['pointer-events-none fixed z-[80] flex max-w-md flex-col gap-2', $anchorClass]) }} aria-live="polite" x-data="{ stack: [], boot: @js($seed), init() { if (this.boot) this.ingest(this.boot) }, ingest(raw) { const packet = Array.isArray(raw) ? raw[0] : raw if (! packet || typeof packet !== 'object') return const copy = packet.copy ?? packet.body ?? packet.message ?? packet.text ?? null if (! copy) return const uid = packet.uid || packet.id || (Date.now() + '-' + Math.random().toString(16).slice(2)) const row = { uid, copy, eyebrow: packet.eyebrow ?? packet.title ?? packet.heading ?? null, tone: packet.tone ?? packet.variant ?? 'note', linger: Number(packet.linger ?? packet.duration ?? 4500), open: true, } this.stack = [...this.stack, row] if (row.linger > 0) { setTimeout(() => this.retire(uid), row.linger) } }, retire(uid) { this.stack = this.stack.map((item) => item.uid === uid ? { ...item, open: false } : item ) setTimeout(() => { this.stack = this.stack.filter((item) => item.uid !== uid) }, 180) }, toneOf(tone) { if (tone === 'ok' || tone === 'success') return 'ok' if (tone === 'fail' || tone === 'danger') return 'fail' if (tone === 'warn' || tone === 'warning') return 'warn' return 'note' }, }" x-on:krikkit-pulse.window="ingest($event.detail)" >