Open a bottom sheet at half the screen, and colour its handle
Plan step 19, containment.md C-19 and C-09. A modal sheet opened at 90% of the viewport where M3 caps the initial position at 50% and lets the person pull it up; `height` now defaults to `50dvh` and whatever is passed is held under a ceiling of the screen less M3's 72dp top margin. The drag handle is `on-surface-variant` undiluted, as SheetBottomTokens' DockedDragHandleColor and the component's own header comment already said. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Opus 5
parent
675cfc806a
commit
256d4f0603
@@ -485,7 +485,7 @@ An M3 side sheet, bound like `<x-modal>`; `close()` in scope. Props: `title`, `s
|
|||||||
|
|
||||||
### `<x-bottom-sheet>`
|
### `<x-bottom-sheet>`
|
||||||
|
|
||||||
An M3 bottom sheet, bound like `<x-modal>`: modal by default (scrim, inert page, drag the handle down or press Escape to close), `standard` for one that is part of the page. Props: `title`, `height` (`90dvh`), `actions` slot.
|
An M3 bottom sheet, bound like `<x-modal>`: modal by default (scrim, inert page, drag the handle down or press Escape to close), `standard` for one that is part of the page. Props: `title`, `height` (`50dvh` — M3 caps a modal sheet's initial position at half the screen; whatever you pass is held under a ceiling of the screen less M3's 72dp top margin), `actions` slot.
|
||||||
|
|
||||||
### `<x-carousel>`, `<x-carousel-item>`
|
### `<x-carousel>`, `<x-carousel-item>`
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,11 @@
|
|||||||
SheetBottomTokens (androidx Compose Material 3, Apache-2.0): surface-container-low, extra-large
|
SheetBottomTokens (androidx Compose Material 3, Apache-2.0): surface-container-low, extra-large
|
||||||
top corners, elevation 1, a 32×4px drag handle in on-surface-variant; 640px wide at most, centred
|
top corners, elevation 1, a 32×4px drag handle in on-surface-variant; 640px wide at most, centred
|
||||||
on a wide screen; it rises on emphasized decelerate. `title` and `actions` as on a dialog.
|
on a wide screen; it rises on emphasized decelerate. `title` and `actions` as on a dialog.
|
||||||
`height` caps it (default: 90% of the screen); content scrolls inside.
|
|
||||||
|
`height` is where it opens, and M3 caps a modal sheet's initial position at half the screen —
|
||||||
|
"if content exceeds that, it can be pulled to full screen and scrolled internally" — so the
|
||||||
|
default is `50dvh`, under a ceiling of the screen less M3's 72dp top margin. Content scrolls
|
||||||
|
inside.
|
||||||
|
|
||||||
The handle is drawn 32×4px and pressed 48×48: `touch-target` on the button and 22px above and
|
The handle is drawn 32×4px and pressed 48×48: `touch-target` on the button and 22px above and
|
||||||
below it, which is M3's "drag handle has an accessible 48dp hit target" and SheetDefaults.kt's
|
below it, which is M3's "drag handle has an accessible 48dp hit target" and SheetDefaults.kt's
|
||||||
@@ -18,7 +22,7 @@
|
|||||||
@props([
|
@props([
|
||||||
'title' => null,
|
'title' => null,
|
||||||
'standard' => false,
|
'standard' => false,
|
||||||
'height' => '90dvh',
|
'height' => '50dvh',
|
||||||
])
|
])
|
||||||
|
|
||||||
@php
|
@php
|
||||||
@@ -54,14 +58,14 @@
|
|||||||
role="dialog"
|
role="dialog"
|
||||||
@unless ($standard) aria-modal="true" @endunless
|
@unless ($standard) aria-modal="true" @endunless
|
||||||
@if (filled($title)) aria-labelledby="{{ $id }}-title" @endif
|
@if (filled($title)) aria-labelledby="{{ $id }}-title" @endif
|
||||||
style="--sheet-max-height: {{ $height }}"
|
style="--sheet-max-height: min({{ $height }}, calc(100dvh - 72px))"
|
||||||
{{ $attributes->whereDoesntStartWith('wire:model')->except(['id', 'class'])->class([
|
{{ $attributes->whereDoesntStartWith('wire:model')->except(['id', 'class'])->class([
|
||||||
'fixed inset-x-0 bottom-0 z-50 mx-auto flex max-h-(--sheet-max-height) w-full max-w-160 touch-pan-y flex-col rounded-t-corner-xl bg-surface-container-low pb-[var(--material-safe-bottom,env(safe-area-inset-bottom))] text-on-surface shadow-elevation-1',
|
'fixed inset-x-0 bottom-0 z-50 mx-auto flex max-h-(--sheet-max-height) w-full max-w-160 touch-pan-y flex-col rounded-t-corner-xl bg-surface-container-low pb-[var(--material-safe-bottom,env(safe-area-inset-bottom))] text-on-surface shadow-elevation-1',
|
||||||
$attributes->get('class'),
|
$attributes->get('class'),
|
||||||
]) }}
|
]) }}
|
||||||
>
|
>
|
||||||
<div class="flex shrink-0 cursor-grab justify-center py-5.5 active:cursor-grabbing" data-drag-handle>
|
<div class="flex shrink-0 cursor-grab justify-center py-5.5 active:cursor-grabbing" data-drag-handle>
|
||||||
<button type="button" class="touch-target h-1 w-8 rounded-corner-full bg-on-surface-variant/40 outline-offset-4 focus-visible:outline-3 focus-visible:outline-secondary" aria-label="{{ __('Close') }}" x-on:click="close()"></button>
|
<button type="button" class="touch-target h-1 w-8 rounded-corner-full bg-on-surface-variant outline-offset-4 focus-visible:outline-3 focus-visible:outline-secondary" aria-label="{{ __('Close') }}" x-on:click="close()"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div x-ref="body" class="min-h-0 flex-1 overflow-y-auto px-6 pb-6">
|
<div x-ref="body" class="min-h-0 flex-1 overflow-y-auto px-6 pb-6">
|
||||||
|
|||||||
@@ -129,9 +129,12 @@ it('draws a modal bottom sheet with a drag handle, or a standard one without a s
|
|||||||
->toContain('data-drag-handle')
|
->toContain('data-drag-handle')
|
||||||
->toContain('aria-modal="true"')
|
->toContain('aria-modal="true"')
|
||||||
->toContain('py-5.5')
|
->toContain('py-5.5')
|
||||||
->toContain('touch-target h-1 w-8')
|
->toContain('touch-target h-1 w-8 rounded-corner-full bg-on-surface-variant ')
|
||||||
|
->toContain('--sheet-max-height: min(50dvh, calc(100dvh - 72px))')
|
||||||
->and((string) $this->blade('<x-bottom-sheet standard>Body</x-bottom-sheet>'))
|
->and((string) $this->blade('<x-bottom-sheet standard>Body</x-bottom-sheet>'))
|
||||||
->toContain('...materialBottomSheet(true)')
|
->toContain('...materialBottomSheet(true)')
|
||||||
->not->toContain('bg-scrim/32')
|
->not->toContain('bg-scrim/32')
|
||||||
->not->toContain('aria-modal');
|
->not->toContain('aria-modal')
|
||||||
|
->and((string) $this->blade('<x-bottom-sheet height="90dvh">Body</x-bottom-sheet>'))
|
||||||
|
->toContain('--sheet-max-height: min(90dvh, calc(100dvh - 72px))');
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user