Keep a date picker's and an app bar's settings on their own component
materialDatepicker set its first day, format, min, max and year range in init() without declaring them, and materialAppBar did the same with its resize observer and scroll handler. Alpine writes an undeclared property to the outermost x-data scope, so two pickers inside one page scope (ReStride's plan setup wraps its form in x-data) shared the last one's min and first day, and a second app bar would have taken the first one's observer. Both now declare them; a browser test puts two pickers in an outer scope. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RHoXZSHc8gGpZjFmA5fPc2
This commit is contained in:
co-authored by
Claude Opus 5
parent
8640d815c8
commit
65788d0c61
@@ -125,6 +125,46 @@ function dateFormatProbe(string $locale = 'en')
|
||||
->assertScript("document.readyState === 'complete' && typeof window.Alpine !== 'undefined' && typeof window.Livewire !== 'undefined'");
|
||||
}
|
||||
|
||||
class ScopedDateProbe extends Component
|
||||
{
|
||||
public ?string $early = '2026-09-13';
|
||||
|
||||
public ?string $late = '2026-09-13';
|
||||
|
||||
public function render(): string
|
||||
{
|
||||
return <<<'BLADE'
|
||||
<div class="grid max-w-md gap-6 p-4" x-data="{ step: 1 }">
|
||||
<x-datepicker id="early-field" label="Early" wire:model.live="early" min="2026-09-10" week-start="0" />
|
||||
<x-datepicker id="late-field" label="Late" wire:model.live="late" week-start="1" />
|
||||
</div>
|
||||
BLADE;
|
||||
}
|
||||
}
|
||||
|
||||
function scopedDateProbe()
|
||||
{
|
||||
Livewire::component('scoped-date-probe', ScopedDateProbe::class);
|
||||
|
||||
Route::middleware('web')->get('/scoped-date-probe', fn () => Blade::render(<<<'BLADE'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<x-theme-script />
|
||||
@vite(config('livewire-material.showcase.vite'))
|
||||
@livewireStyles
|
||||
</head>
|
||||
<body class="bg-surface">
|
||||
<livewire:scoped-date-probe />
|
||||
@livewireScripts
|
||||
</body>
|
||||
</html>
|
||||
BLADE));
|
||||
|
||||
return visit('/scoped-date-probe')->waitForEvent('networkidle')
|
||||
->assertScript("document.readyState === 'complete' && typeof window.Alpine !== 'undefined' && typeof window.Livewire !== 'undefined'");
|
||||
}
|
||||
|
||||
/** A picker's day cell, by its ISO date. */
|
||||
function day(string $picker, string $date): string
|
||||
{
|
||||
@@ -451,3 +491,14 @@ it('lays out and shows a range in the given first day and format', function () {
|
||||
->assertSeeIn('#span', '{"start":"2026-09-20","end":"2026-09-24"}')
|
||||
->assertValue('#span-field', '20/09/2026 – 24/09/2026');
|
||||
});
|
||||
|
||||
it('keeps each picker\'s own settings inside a page\'s outer x-data scope', function () {
|
||||
// Settings assigned in init() without being declared would land on the outermost scope,
|
||||
// where the last picker's null min and Monday start would overwrite the first's.
|
||||
$page = scopedDateProbe()
|
||||
->click('[aria-controls="early-field-picker"][data-datepicker-toggle]')
|
||||
->assertScript(focusedDay('2026-09-13'));
|
||||
|
||||
$page->assertAttribute(day('early-field', '2026-09-09'), 'aria-disabled', 'true')
|
||||
->assertScript('! (\'min\' in Alpine.$data(document.querySelector(\'[x-data="{ step: 1 }"]\')))');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user