Complete the showcase and record Phase 10
tests / lint (push) Has been cancelled
tests / feature (8.4) (push) Has been cancelled
tests / feature (8.5) (push) Has been cancelled
tests / browser (chrome, chromium) (push) Has been cancelled
tests / browser (firefox, firefox) (push) Has been cancelled
tests / browser (safari, webkit) (push) Has been cancelled

Shows the plain tooltip on its own, checks that every component appears
in the showcase, and records the namespace change and the fresh
application check in the plan.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
This commit is contained in:
Andreas Reinhold / reini
2026-09-13 09:08:35 +02:00
co-authored by Claude Opus 5
parent 1e580c573e
commit cbf874a5a6
4 changed files with 42 additions and 2 deletions
+18
View File
@@ -578,6 +578,24 @@ pages and the mail theme by an agent in its own worktree. What changed from the
(drift test green); README (install, CSS/JS wiring, scheme, theme, prefix, showcase, (drift test green); README (install, CSS/JS wiring, scheme, theme, prefix, showcase,
guard, Docker ordering note); tag `1.0.0`. guard, Docker ordering note); tag `1.0.0`.
**Phase 10 is done (2026-09-13).** What changed from the step above:
- **The package's own views write `<x-livewire-material::name>`** for the components they use. Blade
spells a configured prefix `<x-m::button>` (not `<x-m-button>`, as the config first claimed), and
an unqualified `<x-button>` inside a package view would have broken under a prefix and been
shadowed by an application's own `components/button.blade.php`. A test scans every package view
(outside comments and the showcase's example heredocs) for unqualified tags, and the showcase
rewrites its examples to the configured prefix. The component path string stays
`__DIR__.'/../resources/views/components'`: Blade names the view namespace after its hash, and
compiled views keep that name.
- **A test checks that every component appears in the showcase.**
- **Verified in a fresh Laravel 13.31 application** (`composer create-project`, the package from a
path repository, the README's CSS, JS and layout, `material:scheme "#4f46e5"`, `npm run build`):
a Livewire page with an app bar, tabs, a card, a form with validation, a date picker, a dialog and
a toast works without console errors; `/material` and the 404 page render in its scheme.
- **Known gap:** `<x-datepicker>` has no clear button (`<x-timepicker clearable>` does); a date can be
emptied through its text input.
### Phase 11 — SealShare 2.0.0 ### Phase 11 — SealShare 2.0.0
Tracked in SealShare's `docs/plans/livewire-material.md`, after `1.0.0`. Tracked in SealShare's `docs/plans/livewire-material.md`, after `1.0.0`.
+1 -1
View File
@@ -3,7 +3,7 @@
@section('content') @section('content')
<main class="mx-auto max-w-6xl space-y-16 px-4 py-10"> <main class="mx-auto max-w-6xl space-y-16 px-4 py-10">
<p class="max-w-3xl type-body-lg text-on-surface-variant"> <p class="max-w-3xl type-body-lg text-on-surface-variant">
Every token and component, in this application's own scheme. Components appear here as they land. Every token and component, in this application's own scheme.
</p> </p>
@include('livewire-material::showcase.sections.colour') @include('livewire-material::showcase.sections.colour')
@@ -15,6 +15,13 @@
<x-button label="With an action" variant="tonal" x-on:click="materialToast('Share deleted', { action: { label: 'Undo', handler: () => materialToast('Share restored', { type: 'info' }) } })" /> <x-button label="With an action" variant="tonal" x-on:click="materialToast('Share deleted', { action: { label: 'Undo', handler: () => materialToast('Share restored', { type: 'info' }) } })" />
<x-button label="Until dismissed" variant="tonal" x-on:click="materialToast('Your storage is almost full', { type: 'warning', timeout: 0 })" /> <x-button label="Until dismissed" variant="tonal" x-on:click="materialToast('Your storage is almost full', { type: 'warning', timeout: 0 })" />
BLADE, BLADE,
'Plain tooltips' => <<<'BLADE'
<x-button icon="content_copy" tooltip="Copy link" />
<x-button icon="qr_code_2" tooltip-bottom="Show QR code" />
<x-tooltip text="Expires in 3 days" side="right">
<span tabindex="0" class="focus-ring rounded-corner-xs type-body-md text-on-surface-variant">holiday-photos.zip</span>
</x-tooltip>
BLADE,
'Rich tooltips' => <<<'BLADE' 'Rich tooltips' => <<<'BLADE'
<x-rich-tooltip title="Expiry" text="Recipients lose access after this time. Admins can change the longest time allowed."> <x-rich-tooltip title="Expiry" text="Recipients lose access after this time. Admins can change the longest time allowed.">
<x-button icon="help" aria-label="About expiry" /> <x-button icon="help" aria-label="About expiry" />
@@ -59,7 +66,7 @@
<p class="max-w-3xl type-body-md text-on-surface-variant"> <p class="max-w-3xl type-body-md text-on-surface-variant">
<code>&lt;x-badge&gt;</code>, <code>&lt;x-toast&gt;</code> (the snackbar host, fed by the <code>Toasts</code> concern or <code>materialToast()</code>), <code>&lt;x-badge&gt;</code>, <code>&lt;x-toast&gt;</code> (the snackbar host, fed by the <code>Toasts</code> concern or <code>materialToast()</code>),
<code>&lt;x-rich-tooltip&gt;</code>, <code>&lt;x-alert&gt;</code>, <code>&lt;x-stat&gt;</code> and <code>&lt;x-empty-state&gt;</code>. <code>&lt;x-tooltip&gt;</code>, <code>&lt;x-rich-tooltip&gt;</code>, <code>&lt;x-alert&gt;</code>, <code>&lt;x-stat&gt;</code> and <code>&lt;x-empty-state&gt;</code>.
</p> </p>
@foreach ($examples as $title => $code) @foreach ($examples as $title => $code)
+15
View File
@@ -1,5 +1,6 @@
<?php <?php
use Illuminate\Support\Facades\File;
use NoNameWeb\LivewireMaterial\Support\SvgFile; use NoNameWeb\LivewireMaterial\Support\SvgFile;
/** /**
@@ -68,3 +69,17 @@ it('previews a sample mail in the package theme', function () {
->assertSee('border-radius: 9999px', false) ->assertSee('border-radius: 9999px', false)
->assertSee('Unsubscribe'); ->assertSee('Unsubscribe');
}); });
it('shows every component somewhere in the showcase', function () {
$showcase = collect(File::allFiles(__DIR__.'/../../resources/views/showcase'))
->map(fn (SplFileInfo $file): string => $file->getContents())
->implode("\n");
$absent = collect(File::files(__DIR__.'/../../resources/views/components'))
->map(fn (SplFileInfo $file): string => $file->getBasename('.blade.php'))
->reject(fn (string $name): bool => preg_match('/<x-(?:livewire-material::)?'.preg_quote($name, '/').'[\s\/>]/', $showcase) === 1)
->values()
->all();
expect($absent)->toBe([]);
});