Open a range picker full screen on a compact window
M3 § Date Pickers, Anatomy describes a 14-element full-screen range picker for compact breakpoints; `<x-datepicker range>` always used the 360px modal dialog, which on a phone is cramped for a two-month scroll (plan step 24, audit docs/audits/m3-alignment/inputs.md § Missing). A third presentation, "full", joins docked and modal: the same dialog grown to the screen, an app bar with a close button and Save, the supporting text and the range as the headline over a divider, the weekday labels held at the top, and the months in one vertically scrolling list, each under its own label. The grid now draws from one `rows` getter, which is this month's weeks everywhere else, so the docked and single-date pickers render exactly as before. The list is a window of months grown by the scroll and by the keyboard, since nothing here is lazy. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
790ef93c6a
commit
2662040c24
@@ -54,6 +54,41 @@ it('makes the field a read-only trigger for the modal and modal input pickers',
|
||||
->and(datepickerConfig($html)['mode'])->toBe($mode);
|
||||
})->with(['modal', 'input']);
|
||||
|
||||
it('gives a range picker M3\'s full-screen presentation, with an app bar and Save', function () {
|
||||
$html = (string) $this->blade('<x-datepicker id="trip" label="Trip" range mode="modal" />');
|
||||
|
||||
expect($html)
|
||||
->toContain('data-datepicker-full')
|
||||
->toContain('x-show="presentation === \'full\'"')
|
||||
->toContain('data-datepicker-app-bar')
|
||||
->toContain('data-datepicker-close')
|
||||
->toContain('data-datepicker-save')
|
||||
->toContain('Save')
|
||||
->toContain('aria-label="Select dates"')
|
||||
// The months come from one list of rows, each headed by its label.
|
||||
->toContain('x-for="row in rows"')
|
||||
->toContain('data-datepicker-month-label')
|
||||
// The action row is the modal's; the full-screen picker confirms from its app bar.
|
||||
->toContain('x-show="presentation !== \'full\' && (view === \'days\' || typing || presentation === \'modal\')"')
|
||||
->toContain('x-on:scroll="extendMonths($event)"');
|
||||
|
||||
expect(datepickerConfig($html))->toMatchArray(['range' => true, 'mode' => 'modal']);
|
||||
});
|
||||
|
||||
it('leaves the docked and single-date pickers as they were', function () {
|
||||
// Only the presentation is new: a single date never reaches it, whatever the window.
|
||||
expect(file_get_contents(__DIR__.'/../../../resources/js/datepicker.js'))
|
||||
->toContain("this.presentation = config.range && this.compact ? 'full' : config.mode === 'docked' && !this.compact ? 'docked' : 'modal'");
|
||||
|
||||
$html = (string) $this->blade('<x-datepicker id="expires" label="Expires on" />');
|
||||
|
||||
expect($html)
|
||||
->toContain('data-datepicker-nav data-docked')
|
||||
->toContain('x-show="presentation === \'docked\'"')
|
||||
->toContain('data-datepicker-menu-button="months"')
|
||||
->toContain('x-show="presentation === \'modal\'"');
|
||||
});
|
||||
|
||||
it('names each dropdown so Shift+M and Shift+Y can reach it', function () {
|
||||
$html = (string) $this->blade('<x-datepicker label="Birthday" />');
|
||||
|
||||
|
||||
Reference in New Issue
Block a user