diff --git a/resources/boost/skills/livewire-material-development/SKILL.md b/resources/boost/skills/livewire-material-development/SKILL.md index 679791ad..2103aafb 100644 --- a/resources/boost/skills/livewire-material-development/SKILL.md +++ b/resources/boost/skills/livewire-material-development/SKILL.md @@ -392,6 +392,15 @@ Shows on hover and keyboard focus; `persistent` opens it on press and keeps it u "Nothing here yet": `icon` on an Expressive `shape` (`cookie-9` by default), `title`, `description` or slot, and an `actions` slot. Use it for an empty collection, not for a filter that matched nothing. +The `illustration` slot draws the application's own artwork in place of the shape and icon (`icon` and `shape` are then unused). Size the artwork yourself; the slot's attributes go on the element around it, so its `class` sets the colour `currentColor` takes. Mark decorative SVG `aria-hidden="true"`. A slot holding only whitespace or comments leaves the shape and icon. + +```blade + + + + +``` + ### `` `variant`: `filled` (default, surface-container-highest), `elevated`, `outlined`; medium corner. Props `title`, `subtitle`, `separator`; slots `figure` (full-bleed media), `menu` (top-end), `actions` (end-aligned). Do not pass `bg-*`; use `variant`. diff --git a/resources/views/components/empty-state.blade.php b/resources/views/components/empty-state.blade.php index af3641ec..6c6d28d7 100644 --- a/resources/views/components/empty-state.blade.php +++ b/resources/views/components/empty-state.blade.php @@ -8,7 +8,17 @@ Not an M3 component; built from M3 Expressive's parts — `shape` (any `` name, `cookie-9` by default) in secondary-container behind the `icon` in on-secondary-container, a title-large `title`, body-medium `description` or slot. For "your filter matched nothing" - use a plain line of text instead: a picture there is consolation for a typo. --}} + use a plain line of text instead: a picture there is consolation for a typo. + + An application with its own artwork puts it in the `illustration` slot, which is drawn in place + of the shape and icon (both props are then unused). The slot sizes itself; its attributes go on + the element around it, so `class` can set the colour an SVG's `currentColor` takes: + + + + + + A slot holding only whitespace or comments counts as empty, and the shape and icon stay. --}} @props([ 'icon' => 'inbox', @@ -18,10 +28,14 @@ ])
class('flex flex-col items-center gap-4 px-4 py-10 text-center') }}> -
- - -
+ @if (isset($illustration) && $illustration->hasActualContent()) +
attributes }}>{{ $illustration }}
+ @else +
+ + +
+ @endif @if ($title)

{{ $title }}

diff --git a/resources/views/showcase/sections/communication.blade.php b/resources/views/showcase/sections/communication.blade.php index 8a13f002..5cc7c320 100644 --- a/resources/views/showcase/sections/communication.blade.php +++ b/resources/views/showcase/sections/communication.blade.php @@ -66,6 +66,22 @@ BLADE, + 'Empty state with an illustration' => <<<'BLADE' + + + + + + + + + BLADE, ]; @endphp diff --git a/tests/Feature/Components/EmptyStateTest.php b/tests/Feature/Components/EmptyStateTest.php index 0de9e60a..840e1707 100644 --- a/tests/Feature/Components/EmptyStateTest.php +++ b/tests/Feature/Components/EmptyStateTest.php @@ -15,3 +15,34 @@ it('sets an icon on an Expressive shape above its words and action', function () ->toContain('Upload files') ->and(substr_count($html, 'toBe(2); }); + +it('draws an illustration in place of the shape and icon', function () { + $html = (string) $this->blade(<<<'BLADE' + + + + BLADE); + + expect($html) + ->toContain('
') + ->not->toContain('text-secondary-container') + ->not->toContain('text-on-secondary-container') + ->toContain('No routes yet') + ->and(substr_count($html, 'toBe(1); +}); + +it('keeps the shape and icon while the illustration slot holds nothing but comments', function () { + $html = (string) $this->blade(<<<'BLADE' + + + + + + BLADE); + + expect($html) + ->toContain('text-secondary-container') + ->toContain('text-on-secondary-container') + ->not->toContain('artwork to come') + ->and(substr_count($html, 'toBe(2); +});