{{-- An M3 side sheet: detail or controls that slide in from the edge over a scrim; on a phone it is the whole screen. 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 `wire:model` it reads and writes `open` in the Alpine scope around it. `close()` is in scope for anything inside the sheet, so it can draw its own close button. 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 (NavigationDrawerTokens.kt-adjacent side-sheet sources; docs/reference/m3/components-actions-communication-containment.md § Side sheets): surface- container-low, a large corner on its inner edge, elevation 1; `side` `end` (the default) or `start`; `width` from `medium` (a caller's `class` would race the sheet's own — a compact window gets the full-bleed sheet). As a **standard** side sheet (`standard`, from `expanded`) it is M3's other variant: co-planar with the content rather than over it — no scrim, no focus trap, nothing inert, 0dp elevation (material-components-android's `SideSheet.md`: "standard side sheet elevation = 0dp, coplanar"), `surface` rather than surface-container-low, no corner, and an outline-variant divider down its inner edge in place of the scrim. It sits in the page flow beside the content, spans the window's height and scrolls on its own; below `expanded` (840px) it is the modal sheet — M3 calls the standard sheet "supplementary surfaces mainly for medium to expanded breakpoints" and the modal one "preferred at compact breakpoints", and the switch sits at `expanded` rather than `medium` because M3 also caps a side sheet at 400dp and a 600px window has too little left beside one. For the second pane of a list-detail layout use `` instead (step 35's canonical layout); the two are not the same thing — a pane shows what the list beside it selected, a standard sheet is supplementary content (filters, details, a list of actions) beside the primary content, divided from it by a rule rather than being part of its selection. M3 **requires** a close affordance on a side sheet — without one nobody can predict the sheet's open/close flow or tell whether it is transient or permanent (docs/reference/m3/components-actions-communication-containment.md § Side sheets → Accessibility, C-04) — so `with-close-button` is on by default, and `:with-close-button="false"` is ignored where nothing else closes the sheet: Escape off, the scrim off, or `standard`, which has neither from `expanded`. maryUI's API, kept: `title`, `subtitle`, `separator`, `with-close-button`, `close-on-escape`, `without-backdrop-close`, `right` (ignored; use `side`), and an `actions` slot. The root renders `data-md-drawer`, `data-md-open` and `data-md-standard`; the sheet is `data-md-drawer-sheet` with `data-md-side`, its parts `data-md-drawer-head`/-head-row/ -heading/-title/-subtitle/-close/-body/-actions — drawn by resources/css/components/ drawer.css, which imports button.css and divider.css for what the view renders. --}} @props([ 'title' => null, 'subtitle' => null, 'separator' => false, 'side' => 'end', 'right' => true, 'withCloseButton' => true, 'closeOnEscape' => true, 'withoutBackdropClose' => false, 'width' => '25rem', 'standard' => false, ]) @php $model = $attributes->wire('model')->value() ?: null; $id = $attributes->get('id') ?? 'material-sheet-'.substr(md5($model.'|'.$title), 0, 10); $side = $side === 'start' ? 'start' : 'end'; $standard = (bool) $standard; // The side-sheet specs table caps the sheet at 400dp, which is where `width` already starts; // a wider one is the modal sheet's to take, not the co-planar standard sheet's. $sheetWidth = $standard ? "min({$width}, 25rem)" : $width; // M3 requires a close affordance; the prop can only ever add one, never take away the last // way out of the sheet. A standard sheet keeps no scrim and no trap from `expanded`, and // Escape leaves it open there, so it always draws one. $closeButton = $withCloseButton || ! $closeOnEscape || $withoutBackdropClose || $standard; @endphp