diff --git a/resources/views/components/button.blade.php b/resources/views/components/button.blade.php
index d8eb90b3..dd8d75c5 100644
--- a/resources/views/components/button.blade.php
+++ b/resources/views/components/button.blade.php
@@ -24,9 +24,11 @@
Behaviour kept from maryUI: `link` renders an anchor with `wire:navigate` (unless `external`
or `no-wire-navigate`); `disabled` works on a link too, as `aria-disabled`; `spinner` shows
the loading indicator while the button's own `wire:click` runs (or the action named by a
- string); `responsive` hides the label below `lg`; `tooltip`, `tooltip-left`, `tooltip-right`
+ string); `responsive` hides the label below `expanded` (840px, where M3 lets buttons reposition);
+ `tooltip`, `tooltip-left`, `tooltip-right`
and `tooltip-bottom` attach a plain tooltip. `fab` is a page's create action: an extended FAB
- pinned in the thumb zone below `sm`, a filled button above it — one element either way.
+ pinned in the thumb zone on a compact window (below `medium`, 600px), a filled button from
+ there — one element either way.
Never pass `hidden`, a display or a position class: the button is `inline-flex` and
`relative`, and whichever Tailwind emits last wins. Wrap it instead. --}}
@@ -173,8 +175,8 @@
'disabled:cursor-not-allowed disabled:shadow-none aria-disabled:pointer-events-none aria-disabled:shadow-none',
'disabled:bg-on-surface/10 disabled:text-on-surface/38 aria-disabled:bg-on-surface/10 aria-disabled:text-on-surface/38' => $contained,
'disabled:text-on-surface/38 aria-disabled:text-on-surface/38' => ! $contained,
- // The FAB, below sm only: an extended FAB in the thumb zone, clear of a bottom bar the layout declares.
- 'max-sm:fixed max-sm:end-4 max-sm:bottom-[calc(var(--material-bottom-bar,0px)+1rem)] max-sm:z-30 max-sm:h-14 max-sm:gap-2 max-sm:px-4 max-sm:rounded-corner-lg max-sm:type-title-md max-sm:bg-primary-container max-sm:text-on-primary-container max-sm:shadow-elevation-3' => $fab,
+ // The FAB, on a compact window only: an extended FAB in the thumb zone, clear of a bottom bar the layout declares.
+ 'max-medium:fixed max-medium:end-4 max-medium:bottom-[calc(var(--material-bottom-bar,0px)+1rem)] max-medium:z-30 max-medium:h-14 max-medium:gap-2 max-medium:px-4 max-medium:rounded-corner-lg max-medium:type-title-md max-medium:bg-primary-container max-medium:text-on-primary-container max-medium:shadow-elevation-3' => $fab,
];
$tag = $isLink ? 'a' : 'button';
@@ -210,12 +212,12 @@
@if ($icon)
-
+
@endif
@unless ($iconOnly)
- $responsive])>{{ $label ?? $slot }}
+ $responsive])>{{ $label ?? $slot }}
@endunless
@if ($iconRight)
diff --git a/resources/views/components/drawer.blade.php b/resources/views/components/drawer.blade.php
index e83ad5a0..ed7cb436 100644
--- a/resources/views/components/drawer.blade.php
+++ b/resources/views/components/drawer.blade.php
@@ -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"
>
@@ -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'),
]) }}
>
diff --git a/resources/views/components/modal.blade.php b/resources/views/components/modal.blade.php
index 1295cc08..fd9d0d66 100644
--- a/resources/views/components/modal.blade.php
+++ b/resources/views/components/modal.blade.php
@@ -19,7 +19,8 @@
high, extra-large corner, elevation 3, a headline-small `title`, body-medium `subtitle` in
on-surface-variant, and the `actions` slot at the end. `icon` puts a secondary-coloured icon
above a centred title, as M3 draws a dialog with a hero icon. `fullscreen` makes a dialog that
- holds a form take the whole screen below `sm`, with a close button and the title in a top bar
+ holds a form take the whole screen on a compact window (below `medium`, 600px — M3 uses
+ full-screen dialogs "only in compact breakpoints"), with a close button and the title in a top bar
clear of the notch. `persistent` ignores Escape and the scrim, for a dialog that must be
answered. It opens on the fast spatial spring and closes at once, as M3's do. --}}
@@ -58,17 +59,17 @@
'm-auto max-h-[calc(100dvh-3rem)] w-[calc(100vw-3rem)] max-w-[35rem] min-w-70 overflow-visible bg-transparent p-0 text-on-surface',
'backdrop:bg-scrim/32',
'opacity-100 scale-100 starting:opacity-0 starting:scale-95 transition-[opacity,scale] duration-(--md-sys-motion-spatial-fast-duration) ease-spatial-fast',
- 'max-sm:m-0 max-sm:h-dvh max-sm:max-h-none max-sm:w-full max-sm:max-w-none max-sm:min-w-0' => $fullscreen,
+ 'max-medium:m-0 max-medium:h-dvh max-medium:max-h-none max-medium:w-full max-medium:max-w-none max-medium:min-w-0' => $fullscreen,
$attributes->get('class'),
])
>
$fullscreen])>
@if (filled($title) || filled($subtitle) || $icon)
{{-- A full-screen dialog's bar names it on a phone, so only the subtitle stays there. --}}
-
diff --git a/resources/views/components/navigation-bar.blade.php b/resources/views/components/navigation-bar.blade.php
index 874c64af..2e763bca 100644
--- a/resources/views/components/navigation-bar.blade.php
+++ b/resources/views/components/navigation-bar.blade.php
@@ -1,7 +1,7 @@
{{-- M3 Expressive's flexible navigation bar: three to five destinations at the bottom of a
compact window.
-
+
diff --git a/resources/views/components/radio.blade.php b/resources/views/components/radio.blade.php
index 0b7a6652..2162c963 100644
--- a/resources/views/components/radio.blade.php
+++ b/resources/views/components/radio.blade.php
@@ -3,7 +3,8 @@
A `