Give a closing standard side sheet's room back as it leaves
From `expanded` a standard side sheet sits in the layout beside the content, and the view took it out of the layout the moment it closed: `data-md-drawer-collapsed` (`display: none` on the root) followed `! open` at once, so its fade was never seen and the content beside it took the sheet's width, and the gap, in one jump — in every engine. M3's side sheets: opening a standard sheet shrinks the body beside it, and closing gives the room back. drawer.css: the standard root is a clipping flex box whose `inline-size` springs between none and the sheet's width, with a negative margin as wide as its flex parent's gap (`--md-drawer-gap`), on the sheet's own exit and entry timings; the sheet keeps its width at the root's far edge, so it is uncovered from its inner edge while it fades. drawer.blade.php: `settle()`, from `x-effect`, measures the gap on each change and holds the collapse (`closing`) for the root's and the sheet's closing durations, read a frame on; reopening lets a pending end go by. The binding reads `collapsed`, which only `settle()` and the window's width write: a binding reading `open` ran before `settle()` in the same flush and, already queued, did not run again once `closing` changed. ContainmentTest closes the showcase's sheet at 1000px and samples, in the page, for the root part-way to none while the column beside it has grown part of the way, then checks the collapse, the column at the row's full width, and a reopen part-way through the exit ending fully open; it fails on the previous code in Chrome, Firefox and Safari. OverlayTest pins the root's declarations and the view's bindings. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
db6023bf80
commit
99c18e01d8
@@ -509,6 +509,62 @@ it('is a standard side sheet from 840px, without a scrim or a focus trap, and th
|
||||
->assertScript("document.querySelector('header').closest('[aria-hidden=\"true\"]') !== null");
|
||||
});
|
||||
|
||||
it('gives a closing standard side sheet\'s room back to the content beside it as it leaves, from 840px', function () {
|
||||
$sheet = "document.querySelector('#containment aside[data-md-side]')";
|
||||
$root = "{$sheet}.parentElement";
|
||||
$column = "{$root}.previousElementSibling";
|
||||
$toggle = "Array.from(document.querySelectorAll('#containment button')).find((button) => button.textContent.trim() === 'Show or hide the filters')";
|
||||
|
||||
// The example starts open, and grows in once Alpine opens it: its entry has run when the sheet
|
||||
// stands at its full 400px and fully shown, with nothing on it still animating.
|
||||
$page = containment()->resize(1000, 800)
|
||||
->assertScript("{$root}.hasAttribute('data-md-open') && Math.round({$root}.getBoundingClientRect().width) === 400 && getComputedStyle({$sheet}).opacity === '1' && {$root}.getAnimations({ subtree: true }).length === 0");
|
||||
|
||||
// Closed and sampled in one round trip: the sheet's root caught part-way between its width
|
||||
// and none, still in the layout, while the column beside it has grown part of the way — not
|
||||
// the whole sheet and its gap handed back in one jump at the end.
|
||||
$midExit = $page->script(<<<JS
|
||||
(async () => {
|
||||
const root = {$root}
|
||||
const column = {$column}
|
||||
const open = { root: root.getBoundingClientRect().width, column: column.getBoundingClientRect().width, row: root.parentElement.getBoundingClientRect().width }
|
||||
{$toggle}.click()
|
||||
|
||||
for (let i = 0; i < 80; i++) {
|
||||
const width = root.getBoundingClientRect().width
|
||||
const columnWidth = column.getBoundingClientRect().width
|
||||
|
||||
if (! root.hasAttribute('data-md-drawer-collapsed') && getComputedStyle(root).display !== 'none' && width > 1 && width < open.root - 1 && columnWidth > open.column + 1 && columnWidth < open.row - 1) return true
|
||||
await new Promise((resolve) => setTimeout(resolve, 5))
|
||||
}
|
||||
return false
|
||||
})()
|
||||
JS);
|
||||
|
||||
expect($midExit)->toBeTrue();
|
||||
|
||||
// Settled: out of the layout, and the column is the whole row, gap included.
|
||||
$page->assertScript("{$root}.hasAttribute('data-md-drawer-collapsed') && getComputedStyle({$root}).display === 'none'")
|
||||
->assertScript("Math.abs({$column}.getBoundingClientRect().width - {$root}.parentElement.getBoundingClientRect().width) < 1");
|
||||
|
||||
// Reopened part-way through its exit, it ends open, not collapsed. Each script stays well under
|
||||
// the browser plugin's one-second call timeout, past which it runs the script a second time.
|
||||
$page->script("{$toggle}.click()");
|
||||
$page->wait(0.6)
|
||||
->assertScript("{$root}.hasAttribute('data-md-open') && {$root}.getAnimations({ subtree: true }).length === 0");
|
||||
|
||||
$page->script(<<<JS
|
||||
(async () => {
|
||||
{$toggle}.click()
|
||||
await new Promise((resolve) => setTimeout(resolve, 60))
|
||||
{$toggle}.click()
|
||||
})()
|
||||
JS);
|
||||
|
||||
$page->wait(0.9)
|
||||
->assertScript("{$root}.hasAttribute('data-md-open') && ! {$root}.hasAttribute('data-md-drawer-collapsed') && Math.abs({$root}.getBoundingClientRect().width - 400) < 1 && getComputedStyle({$sheet}).opacity === '1'");
|
||||
});
|
||||
|
||||
it('opens a row\'s opener from a press anywhere on the row, but not from its own buttons', function () {
|
||||
$page = containment();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user