M3 asks a FAB's icon and a default (non-toggle) icon button's icon to be filled, never outlined; the toggle half of that rule was already right, so only the `$selected === null` case changed. Every glyph these components draw at 20px now passes `optical="20"` for the cut M3 draws at that size — button xs/sm, group, menu item, the alert, snackbar and FAB-menu close buttons, the stat's icon. Plan step 18, actions.md ACT-14, ACT-15. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
66 lines
3.0 KiB
PHP
66 lines
3.0 KiB
PHP
{{-- A notice in the page: a state that needs saying — storage is full, the link has expired.
|
|
|
|
Not an M3 component (M3's banner is gone); drawn in M3's terms: the state's container colour
|
|
(tinted, never filled), a medium corner, the state's icon, a title-small `title`, body-medium
|
|
text from `description` or the slot, and an `actions` slot for one or two text buttons.
|
|
`color` (alias `tone`): `info` (the default), `success`, `warning`, `error`, `primary`,
|
|
`secondary`, `tertiary`, or `neutral` for surface-container-high. `icon` replaces the state's
|
|
icon; `:icon="false"` drops it. `dismissible` adds a close button that hides it in the browser.
|
|
|
|
Errors and warnings are `role="alert"` and announced at once; the rest are `role="status"`. --}}
|
|
|
|
@props([
|
|
'title' => null,
|
|
'description' => null,
|
|
'color' => null,
|
|
'tone' => null,
|
|
'icon' => null,
|
|
'dismissible' => false,
|
|
])
|
|
|
|
@php
|
|
$color = in_array($color ?? $tone, ['info', 'success', 'warning', 'error', 'primary', 'secondary', 'tertiary', 'neutral'], true) ? ($color ?? $tone) : 'info';
|
|
|
|
$icon = $icon === false ? null : ($icon ?? [
|
|
'info' => 'info', 'success' => 'check_circle', 'warning' => 'warning', 'error' => 'error',
|
|
'primary' => 'info', 'secondary' => 'info', 'tertiary' => 'info', 'neutral' => 'info',
|
|
][$color]);
|
|
|
|
$colours = [
|
|
'info' => 'bg-info-container text-on-info-container', 'success' => 'bg-success-container text-on-success-container',
|
|
'warning' => 'bg-warning-container text-on-warning-container', 'error' => 'bg-error-container text-on-error-container',
|
|
'primary' => 'bg-primary-container text-on-primary-container', 'secondary' => 'bg-secondary-container text-on-secondary-container',
|
|
'tertiary' => 'bg-tertiary-container text-on-tertiary-container', 'neutral' => 'bg-surface-container-high text-on-surface',
|
|
][$color];
|
|
@endphp
|
|
|
|
<div
|
|
role="{{ in_array($color, ['error', 'warning'], true) ? 'alert' : 'status' }}"
|
|
@if ($dismissible) x-data="{ shown: true }" x-show="shown" x-transition.opacity @endif
|
|
{{ $attributes->class(['flex items-start gap-3 rounded-corner-md p-4', $colours]) }}
|
|
>
|
|
@if ($icon)
|
|
<x-livewire-material::icon :name="$icon" filled class="size-6" />
|
|
@endif
|
|
|
|
<div class="min-w-0 flex-1 space-y-1 self-center">
|
|
@if ($title)
|
|
<p class="type-title-sm">{{ $title }}</p>
|
|
@endif
|
|
|
|
@if ($description || $slot->isNotEmpty())
|
|
<div class="type-body-md">{{ $description ?? $slot }}</div>
|
|
@endif
|
|
|
|
@isset($actions)
|
|
<div class="-ms-3 flex flex-wrap gap-2 pt-1">{{ $actions }}</div>
|
|
@endisset
|
|
</div>
|
|
|
|
@if ($dismissible)
|
|
<button type="button" class="state-layer focus-ring -m-2 inline-flex size-10 shrink-0 items-center justify-center rounded-corner-full" aria-label="{{ __('Dismiss') }}" x-on:click="shown = false">
|
|
<x-livewire-material::icon name="close" optical="20" class="size-5" />
|
|
</button>
|
|
@endif
|
|
</div>
|