Key the views on M3's window size classes, not Tailwind's
Plan step 15. Every `sm:`/`md:`/`lg:`/`xl:` in the components, the showcase (sections, layout, shell) and the pagination and error views becomes the M3 window size class the audits' breakpoint maps prescribe: the full-screen dialog, the FAB, the snackbar's width, `radio inline`, the section picker and the page numbers move from 640px to `medium` (600px, M3's compact boundary, N-07 / C-07 / IN-28); `button responsive` moves from 1024px to `expanded` (840px); `section-nav`'s grid-to-row switch from 1280px to `large` (1200px, N-07); and `drawer pane` from 1280px to `expanded`, where M3 shows two panes for list-detail (C-07). The pane's default width is now 360dp, M3's fixed supporting pane at expanded. Showcase example grids take two columns from `medium` and three or more from `expanded`; the showcase's own theme picker swaps at `expanded`, the nearest class boundary to the 768px it used (no M3 rule applies to it). 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
25ff5a8d71
commit
b1642aed1c
@@ -1,5 +1,8 @@
|
||||
{{-- An M3 side sheet: detail or controls that slide in from the edge over a scrim; on a phone it is
|
||||
the whole screen. With `pane`, from `xl` it is a list-detail pane beside the list instead.
|
||||
the whole screen. With `pane`, from `expanded` (840px) it is a second pane beside the list
|
||||
instead — M3 shows two panes for list-detail from expanded upwards, and puts a supporting pane
|
||||
on the side of the focus pane at expanded, 360dp wide
|
||||
(docs/reference/m3/foundations-supplement.md § Canonical layout examples).
|
||||
|
||||
The open state is the Livewire property in `wire:model` (entangled live, so a detail held in the
|
||||
URL follows a close) — a flag or an id — and closing writes back `false` or `null`. Without
|
||||
@@ -9,13 +12,14 @@
|
||||
As a sheet it is modal: the page inert and still (`x-trap.inert.noscroll`), and it enters on
|
||||
emphasized decelerate rather than a spring — a sheet anchored to the edge that overshot would
|
||||
open a gap. M3's modal side sheet: surface-container-low, a large corner on its inner edge,
|
||||
elevation 1; `side` `end` (the default) or `start`; `width` from `sm` (a caller's `w-*` would
|
||||
race the sheet's own).
|
||||
elevation 1; `side` `end` (the default) or `start`; `width` from `medium` (a caller's `w-*`
|
||||
would race the sheet's own — a compact window gets the full-bleed sheet).
|
||||
|
||||
As a pane (`pane`, from `xl`) nothing is covered: the page renders the drawer after its list in
|
||||
an `xl:flex xl:items-start xl:gap-6` row, the drawer sticks under the top of the viewport, the
|
||||
As a pane (`pane`, from `expanded`) nothing is covered: the page renders the drawer after its
|
||||
list in
|
||||
an `expanded:flex expanded:items-start expanded:gap-6` row, the drawer sticks under the top of the viewport, the
|
||||
list stays usable and another row swaps what it shows — no scrim, no trap, no inert page. While
|
||||
closed it takes no room. `pane-width` sizes the pane (the sheet's width by default). Escape closes
|
||||
closed it takes no room. `pane-width` sizes the pane (`22.5rem`, M3's 360dp fixed pane). Escape closes
|
||||
the sheet but leaves a pane open, since the page beside it is still in use; `pane-close-on-escape`
|
||||
closes the pane on Escape too, for a pane that is a transient detail. The body is
|
||||
a size container, so its contents lay out by the room the sheet or pane actually has (`@md:`),
|
||||
@@ -35,7 +39,7 @@
|
||||
'withoutBackdropClose' => false,
|
||||
'width' => '25rem',
|
||||
'pane' => false,
|
||||
'paneWidth' => null,
|
||||
'paneWidth' => '22.5rem',
|
||||
'paneCloseOnEscape' => false,
|
||||
])
|
||||
|
||||
@@ -52,7 +56,7 @@
|
||||
close() { this.open = typeof this.open === 'boolean' ? false : null; },
|
||||
@if ($pane)
|
||||
init() {
|
||||
const query = window.matchMedia('(min-width: 80rem)');
|
||||
const query = window.matchMedia('(width >= 52.5rem)');
|
||||
this.wide = query.matches;
|
||||
query.addEventListener('change', (event) => this.wide = event.matches);
|
||||
},
|
||||
@@ -61,8 +65,8 @@
|
||||
@if ($closeOnEscape) x-on:keydown.window.escape="{{ $paneCloseOnEscape ? 'if (open) close()' : 'if (open && ! wide) close()' }}" @endif
|
||||
data-sheet="{{ $id }}"
|
||||
@if ($pane)
|
||||
x-bind:class="! open && 'xl:hidden'"
|
||||
class="xl:sticky xl:top-[calc(var(--material-safe-top,env(safe-area-inset-top))+1.25rem)] xl:shrink-0 xl:self-start"
|
||||
x-bind:class="! open && 'expanded:hidden'"
|
||||
class="expanded:sticky expanded:top-[calc(var(--material-safe-top,env(safe-area-inset-top))+1.25rem)] expanded:shrink-0 expanded:self-start"
|
||||
data-pane
|
||||
@endif
|
||||
>
|
||||
@@ -71,7 +75,7 @@
|
||||
x-show="open"
|
||||
x-transition.opacity.duration.200ms
|
||||
@if (! $withoutBackdropClose) x-on:click="close()" @endif
|
||||
@class(['fixed inset-0 z-40 bg-scrim/32', 'xl:hidden' => $pane])
|
||||
@class(['fixed inset-0 z-40 bg-scrim/32', 'expanded:hidden' => $pane])
|
||||
aria-hidden="true"
|
||||
></div>
|
||||
|
||||
@@ -80,24 +84,24 @@
|
||||
x-show="open"
|
||||
x-trap.inert.noscroll="open && ! wide"
|
||||
x-transition:enter="transition-[translate,opacity] duration-(--md-sys-motion-spatial-default-duration) ease-emphasized-decelerate"
|
||||
x-transition:enter-start="{{ $pane ? ($start ? 'max-xl:-translate-x-full xl:opacity-0' : 'max-xl:translate-x-full xl:opacity-0') : ($start ? '-translate-x-full' : 'translate-x-full') }}"
|
||||
x-transition:enter-start="{{ $pane ? ($start ? 'max-expanded:-translate-x-full expanded:opacity-0' : 'max-expanded:translate-x-full expanded:opacity-0') : ($start ? '-translate-x-full' : 'translate-x-full') }}"
|
||||
x-transition:enter-end="translate-x-0 opacity-100"
|
||||
x-transition:leave="transition-[translate,opacity] duration-(--md-sys-motion-effects-default-duration) ease-emphasized-accelerate"
|
||||
x-transition:leave-start="translate-x-0 opacity-100"
|
||||
x-transition:leave-end="{{ $pane ? ($start ? 'max-xl:-translate-x-full xl:opacity-0' : 'max-xl:translate-x-full xl:opacity-0') : ($start ? '-translate-x-full' : 'translate-x-full') }}"
|
||||
x-transition:leave-end="{{ $pane ? ($start ? 'max-expanded:-translate-x-full expanded:opacity-0' : 'max-expanded:translate-x-full expanded:opacity-0') : ($start ? '-translate-x-full' : 'translate-x-full') }}"
|
||||
id="{{ $id }}"
|
||||
x-bind:role="wide ? 'region' : 'dialog'"
|
||||
x-bind:aria-modal="wide ? null : 'true'"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
@if (filled($title)) aria-labelledby="{{ $id }}-title" @endif
|
||||
style="--sheet-width: {{ $width }}; --pane-width: {{ $paneWidth ?? $width }}"
|
||||
style="--sheet-width: {{ $width }}; --pane-width: {{ $paneWidth }}"
|
||||
{{ $attributes->whereDoesntStartWith('wire:model')->except(['id', 'class'])->class([
|
||||
'fixed top-[var(--material-safe-top,env(safe-area-inset-top))] bottom-0 z-50 flex w-full flex-col overflow-y-auto bg-surface-container-low p-6 text-on-surface shadow-elevation-1',
|
||||
'end-0 sm:rounded-s-corner-lg' => ! $start,
|
||||
'start-0 sm:rounded-e-corner-lg' => $start,
|
||||
'sm:w-(--sheet-width) sm:max-w-[calc(100vw-4rem)]',
|
||||
'xl:relative xl:top-0 xl:z-auto xl:max-h-[calc(100dvh-2.5rem-var(--material-safe-top,env(safe-area-inset-top)))] xl:w-(--pane-width) xl:max-w-none xl:rounded-corner-lg xl:bg-surface-container xl:shadow-none' => $pane,
|
||||
'end-0 medium:rounded-s-corner-lg' => ! $start,
|
||||
'start-0 medium:rounded-e-corner-lg' => $start,
|
||||
'medium:w-(--sheet-width) medium:max-w-[calc(100vw-4rem)]',
|
||||
'expanded:relative expanded:top-0 expanded:z-auto expanded:max-h-[calc(100dvh-2.5rem-var(--material-safe-top,env(safe-area-inset-top)))] expanded:w-(--pane-width) expanded:max-w-none expanded:rounded-corner-lg expanded:bg-surface-container expanded:shadow-none' => $pane,
|
||||
$attributes->get('class'),
|
||||
]) }}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user