Files
livewire-material/tests/Feature/Components/OverlayTest.php
T
Andreas Reinhold / reiniandClaude Opus 5 fef20a9178
tests / lint (push) Failing after 2m6s
tests / feature (8.4) (push) Successful in 1m3s
tests / feature (8.5) (push) Successful in 1m7s
tests / browser (safari, webkit) (push) Successful in 3m14s
tests / browser (chrome, chromium) (push) Successful in 2m9s
tests / browser (firefox, firefox) (push) Successful in 2m29s
Add cards, lists, dialogs, sheets and the rest of M3's containment
<x-card> (filled, elevated, outlined), <x-list> and <x-list-item>
(plain or M3 Expressive's segmented list), <x-divider>, <x-collapse> on
<details>, <x-modal> on the native <dialog>, <x-drawer> as a side sheet or
list-detail pane, and <x-bottom-sheet> with drag to dismiss. Dialogs and
sheets bind to a Livewire flag or id and write back false or null on close,
or use the surrounding Alpine scope. Rows open from anywhere on them through
data-list-row and data-list-open. DesignGuard now also reports Blade
directives written inside a component tag, where they do not compile.

Browser test helpers wait for a complete document with Alpine and Livewire
running: in Firefox, networkidle alone could return before a repeated visit
had loaded.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V9NnLxnPp8vaaurb3Z1MFy
2026-09-13 07:28:05 +02:00

74 lines
3.1 KiB
PHP

<?php
use Livewire\Component;
use Livewire\Livewire;
it('opens a native dialog entangled with a Livewire property, out of the morph\'s reach', function () {
$component = new class extends Component
{
public bool $confirming = false;
public function render(): string
{
return <<<'BLADE'
<div>
<x-modal wire:model="confirming" title="Delete this share?" subtitle="This cannot be undone." icon="delete">
<x-slot:actions><button>Delete</button></x-slot:actions>
</x-modal>
</div>
BLADE;
}
};
Livewire::test($component)
->assertSeeHtml('<dialog')
->assertSeeHtml('wire:ignore.self')
->assertSeeHtml('open: window.Livewire.find(')
->assertSeeHtml("entangle('confirming').live")
->assertSeeHtml('close() { this.open = typeof this.open === \'boolean\' ? false : null }')
->assertSeeHtml('rounded-corner-xl bg-surface-container-high')
->assertSeeHtml('type-headline-sm')
->assertSee('This cannot be undone.')
->assertSeeHtml('text-center')
->assertDontSeeHtml('wire:model="confirming"');
});
it('uses the surrounding Alpine scope without wire:model, and stays open when persistent', function () {
$html = (string) $this->blade('<x-modal title="Help" persistent fullscreen>Text</x-modal>');
expect($html)
->toContain('x-data="{ close() { this.open = false } }"')
->toContain('x-on:cancel.prevent=""')
->not->toContain('x-on:click.self')
->toContain('max-sm:h-dvh')
->toContain('aria-label="Close"');
});
it('slides a side sheet in from either edge, and is a pane from xl when asked', function () {
expect((string) $this->blade('<x-drawer title="Details" with-close-button>Body</x-drawer>'))
->toContain('x-trap.inert.noscroll="open && ! wide"')
->toContain('end-0 sm:rounded-s-corner-lg')
->toContain('bg-surface-container-low')
->toContain('role="dialog"')
->toContain('aria-label="Close"')
->and((string) $this->blade('<x-drawer side="start">Body</x-drawer>'))->toContain('start-0 sm:rounded-e-corner-lg')
->and((string) $this->blade('<x-drawer pane pane-width="28rem">Body</x-drawer>'))
->toContain('data-pane')
->toContain('--pane-width: 28rem')
->toContain("matchMedia('(min-width: 80rem)')");
});
it('draws a modal bottom sheet with a drag handle, or a standard one without a scrim', function () {
expect((string) $this->blade('<x-bottom-sheet title="Share via">Body</x-bottom-sheet>'))
->toContain('...materialBottomSheet(false)')
->toContain('bg-scrim/32')
->toContain('x-trap.inert.noscroll="open"')
->toContain('rounded-t-corner-xl bg-surface-container-low')
->toContain('data-drag-handle')
->toContain('aria-modal="true"')
->and((string) $this->blade('<x-bottom-sheet standard>Body</x-bottom-sheet>'))
->toContain('...materialBottomSheet(true)')
->not->toContain('bg-scrim/32')
->not->toContain('aria-modal');
});