Package views now write <x-livewire-material::button>, so a configured prefix (which Blade spells <x-m::button>) and an application component of the same name can no longer break or shadow them. The showcase rewrites its examples to the configured prefix. Adds the README, and waits for the adaptive rail to hear a resize before the navigation tests press its menu button. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
75 lines
4.3 KiB
PHP
75 lines
4.3 KiB
PHP
{{-- The snackbar host: shows every toast, one at a time. Put it once in each layout, near the end
|
||
of <body>:
|
||
|
||
<x-toast />
|
||
|
||
It shows every `toast` browser event — what `NoNameWeb\LivewireMaterial\Concerns\Toasts`
|
||
dispatches from a Livewire component — and for `window.materialToast(title, options)` from
|
||
JavaScript (`{ type, description, timeout, action: { label, handler } }`). Toasts queue and
|
||
show in turn, each for its `timeout` (4s by default; M3 asks for 4–10s), paused while the
|
||
pointer or focus is on it. A toast with an action or no timeout gets a close button.
|
||
|
||
`@persist` keeps the host across wire:navigate, so a toast dispatched with `redirectTo` is
|
||
still on screen when the next page arrives.
|
||
|
||
M3's snackbar (SnackbarTokens, androidx Compose Material 3, Apache-2.0): inverse surface,
|
||
body-medium text, a label-large action in inverse-primary, extra-small corners, elevation 3,
|
||
48px for one line. A type draws its state icon in the inverse state colour. `position`:
|
||
`bottom` (centred, the default) or `bottom-start`. It lifts above a bottom bar through
|
||
`--material-bottom-bar`. --}}
|
||
|
||
@props(['position' => 'bottom'])
|
||
|
||
@persist('material-toast')
|
||
<div
|
||
x-data="materialSnackbar"
|
||
{{ $attributes->class([
|
||
'pointer-events-none fixed inset-x-4 z-50 flex bottom-[calc(var(--material-bottom-bar,0px)+1rem)]',
|
||
'justify-center' => $position !== 'bottom-start',
|
||
'justify-start sm:start-6' => $position === 'bottom-start',
|
||
]) }}
|
||
>
|
||
<template x-if="current">
|
||
<div
|
||
x-bind:key="current.id"
|
||
x-bind:role="current.type === 'error' || current.type === 'warning' ? 'alert' : 'status'"
|
||
aria-live="polite"
|
||
x-on:mouseenter="pause()"
|
||
x-on:mouseleave="resume()"
|
||
x-on:focusin="pause()"
|
||
x-on:focusout="resume()"
|
||
class="pointer-events-auto flex min-h-12 w-full max-w-[min(100%,36rem)] items-center gap-3 rounded-corner-xs bg-inverse-surface py-1.5 ps-4 pe-2 text-inverse-on-surface shadow-elevation-3 transition-[translate,opacity] duration-(--md-sys-motion-spatial-fast-duration) ease-spatial-fast starting:translate-y-4 starting:opacity-0 sm:w-auto sm:min-w-86"
|
||
>
|
||
<template x-if="icon(current.type)">
|
||
<span class="flex shrink-0" x-bind:class="{
|
||
'text-inverse-success': current.type === 'success',
|
||
'text-inverse-error': current.type === 'error',
|
||
'text-inverse-warning': current.type === 'warning',
|
||
'text-inverse-info': current.type === 'info',
|
||
}">
|
||
<span x-show="current.type === 'success'"><x-livewire-material::icon name="check_circle" filled class="size-6" /></span>
|
||
<span x-show="current.type === 'error'"><x-livewire-material::icon name="error" filled class="size-6" /></span>
|
||
<span x-show="current.type === 'warning'"><x-livewire-material::icon name="warning" filled class="size-6" /></span>
|
||
<span x-show="current.type === 'info'"><x-livewire-material::icon name="info" filled class="size-6" /></span>
|
||
</span>
|
||
</template>
|
||
|
||
<div class="min-w-0 flex-1 py-1.5">
|
||
<p class="type-body-md" x-text="current.title"></p>
|
||
<p class="type-body-md opacity-80" x-show="current.description" x-text="current.description"></p>
|
||
</div>
|
||
|
||
<template x-if="current.action">
|
||
<button type="button" class="state-layer focus-ring h-10 shrink-0 rounded-corner-full px-3 type-label-lg text-inverse-primary" x-text="current.action.label" x-on:click="act()"></button>
|
||
</template>
|
||
|
||
<template x-if="current.action || ! current.timeout">
|
||
<button type="button" class="state-layer focus-ring inline-flex size-10 shrink-0 items-center justify-center rounded-corner-full" aria-label="{{ __('Dismiss') }}" x-on:click="dismiss()">
|
||
<x-livewire-material::icon name="close" class="size-5" />
|
||
</button>
|
||
</template>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
@endpersist
|