Sweep up navigation's last data-navigation-* references
Plan step 36 (navigation group, second batch, cleanup). Every leftover data-navigation-*, data-tall, data-hide-on-scroll, data-hidden, data-width, data-align, data-divider, data-fill and component-level data-open reference outside the rewritten stylesheets and views moves to data-md-*, in the files the two component commits left alone: tests/Feature/Components/ScaffoldTest.php (the scaffold's own rewrite is a later batch, but it renders the bar and the rail today and asserts their hooks); tests/Browser/NavigationTest.php, ShowcaseTest.php and ColourProfilesTest.php (selectors only — document-level attributes, data-rail, data-rail-auto and data-app-shell*, keep their names). NavigationTest.php also gets the browser tests the plan owed this group (docs/plans/material-3-browser-tests.md § Navigation): a tall bar's vertical layout at a width where the short bar would go horizontal; hide-on-scroll never firing while a pinned snackbar is on screen; a narrow rail's 80px width and centred destinations; a rail that hides when collapsed leaving the layout and coming back only through an application's own menu button. resources/css/components/navigation.css and its import in tailwind.css are deleted now that nothing imports the file any more (the previous commit's message said this already happened there; it did not — this is where it actually lands). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
25549374ec
commit
cbd7d01c62
@@ -73,7 +73,7 @@ it('previews a profile from the picker and the showcase menu, and keeps it throu
|
||||
->click('[data-scheme-preview="teal"]')
|
||||
->assertScript("document.documentElement.getAttribute('data-scheme') === 'teal'");
|
||||
|
||||
$page->click('[data-navigation-rail-panel] a[href$="/material/buttons"]')
|
||||
$page->click('[data-md-navigation-rail-panel] a[href$="/material/buttons"]')
|
||||
->assertScript("location.pathname.endsWith('/material/buttons')")
|
||||
->assertScript("document.documentElement.getAttribute('data-scheme') === 'teal'")
|
||||
->assertNoJavaScriptErrors();
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
const RAIL = "document.querySelector('[data-navigation-rail]')";
|
||||
const RAIL_PANEL = "document.querySelector('[data-navigation-rail-panel]')";
|
||||
const RAIL = "document.querySelector('[data-md-navigation-rail]')";
|
||||
const RAIL_PANEL = "document.querySelector('[data-md-navigation-rail-panel]')";
|
||||
const BOTTOM_BAR = "document.querySelector('[data-app-shell-bar]')";
|
||||
|
||||
function navigationReady(mixed $page): mixed
|
||||
@@ -20,7 +20,7 @@ function shellPage(int $width = 1280, int $height = 900, string $path = '/materi
|
||||
// of its queries are M3 window size classes: `expanded` (840px) says the rail is standard
|
||||
// rather than modal, `large` (1200px) that it starts expanded rather than collapsed.
|
||||
return navigationReady(visit($path)->resize($width, $height))
|
||||
->assertScript("window.eval(\"(() => { const rail = document.querySelector('[data-navigation-rail]'); if (! rail || rail.dataset.navigationRail !== 'adaptive') return true; const state = Alpine.\$data(rail); return state.wide === window.matchMedia('(width >= 840px)').matches && state.roomy === window.matchMedia('(width >= 1200px)').matches; })()\")");
|
||||
->assertScript("window.eval(\"(() => { const rail = document.querySelector('[data-md-navigation-rail]'); if (! rail || rail.dataset.mdNavigationRail !== 'adaptive') return true; const state = Alpine.\$data(rail); return state.wide === window.matchMedia('(width >= 840px)').matches && state.roomy === window.matchMedia('(width >= 1200px)').matches; })()\")");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ function firstPaintProbe(): void
|
||||
<script>
|
||||
window.firstPaint = {
|
||||
rail: document.documentElement.getAttribute('data-rail'),
|
||||
width: getComputedStyle(document.querySelector('[data-navigation-rail]')).width,
|
||||
width: getComputedStyle(document.querySelector('[data-md-navigation-rail]')).width,
|
||||
alpine: typeof window.Alpine,
|
||||
};
|
||||
</script>
|
||||
@@ -67,10 +67,10 @@ it('shows the navigation bar on a compact window and marks the current destinati
|
||||
shellPage(599, 860)
|
||||
->assertScript('getComputedStyle('.BOTTOM_BAR.").display !== 'none'")
|
||||
->assertScript('getComputedStyle('.RAIL_PANEL.").display === 'none'")
|
||||
->assertScript(BOTTOM_BAR.".querySelectorAll('[data-navigation-bar-item]').length === 4")
|
||||
->assertScript(BOTTOM_BAR.".querySelectorAll('[data-md-navigation-bar-item]').length === 4")
|
||||
->assertScript(BOTTOM_BAR.".querySelector('[aria-current=\"page\"]').textContent.includes('Inbox')")
|
||||
->assertScript('getComputedStyle('.BOTTOM_BAR.".querySelector('[aria-current=\"page\"] [data-navigation-indicator]')).backgroundImage !== 'none'")
|
||||
->assertScript('getComputedStyle('.BOTTOM_BAR.".querySelector('[data-navigation-bar-item]:not([aria-current]) [data-navigation-indicator]')).backgroundImage === 'none'")
|
||||
->assertScript('getComputedStyle('.BOTTOM_BAR.".querySelector('[aria-current=\"page\"] [data-md-navigation-indicator]')).backgroundImage !== 'none'")
|
||||
->assertScript('getComputedStyle('.BOTTOM_BAR.".querySelector('[data-md-navigation-bar-item]:not([aria-current]) [data-md-navigation-indicator]')).backgroundImage === 'none'")
|
||||
->assertNoJavaScriptErrors();
|
||||
});
|
||||
|
||||
@@ -83,9 +83,9 @@ it('collapses the rail across the medium class, icon over label, from its first
|
||||
shellPage(839)
|
||||
->assertScript(railWidth(96))
|
||||
->assertScript('getComputedStyle('.BOTTOM_BAR.").display === 'none'")
|
||||
->assertScript("getComputedStyle(document.querySelector('[data-navigation-rail-item]')).flexDirection === 'column'")
|
||||
->assertScript("getComputedStyle(document.querySelector('[data-navigation-rail-heading]')).display === 'none'")
|
||||
->assertAttribute('[data-navigation-rail-menu]', 'aria-expanded', 'false');
|
||||
->assertScript("getComputedStyle(document.querySelector('[data-md-navigation-rail-item]')).flexDirection === 'column'")
|
||||
->assertScript("getComputedStyle(document.querySelector('[data-md-navigation-rail-heading]')).display === 'none'")
|
||||
->assertAttribute('[data-md-navigation-rail-menu]', 'aria-expanded', 'false');
|
||||
});
|
||||
|
||||
it('starts the rail collapsed across the expanded class and expands it in the layout', function () {
|
||||
@@ -100,17 +100,17 @@ it('starts the rail collapsed across the expanded class and expands it in the la
|
||||
$page = shellPage(840)
|
||||
->assertScript(railWidth(96))
|
||||
->assertScript('getComputedStyle('.BOTTOM_BAR.").display === 'none'")
|
||||
->assertAttribute('[data-navigation-rail-menu]', 'aria-expanded', 'false');
|
||||
->assertAttribute('[data-md-navigation-rail-menu]', 'aria-expanded', 'false');
|
||||
|
||||
$page->click('[data-navigation-rail-menu]')
|
||||
$page->click('[data-md-navigation-rail-menu]')
|
||||
->assertScript(railWidth(256))
|
||||
->assertScript('! '.RAIL.".hasAttribute('data-open')")
|
||||
->assertScript("getComputedStyle(document.querySelector('[data-navigation-rail-scrim]')).display === 'none'")
|
||||
->assertScript('! '.RAIL.".hasAttribute('data-md-open')")
|
||||
->assertScript("getComputedStyle(document.querySelector('[data-md-navigation-rail-scrim]')).display === 'none'")
|
||||
->assertScript("document.getElementById('content').closest('[aria-hidden=\"true\"]') === null")
|
||||
->assertScript("document.documentElement.getAttribute('data-rail') === 'expanded'")
|
||||
->assertScript("! document.documentElement.hasAttribute('data-rail-auto')")
|
||||
->assertScript("localStorage.getItem('material-rail') === 'expanded'")
|
||||
->assertAttribute('[data-navigation-rail-menu]', 'aria-expanded', 'true')
|
||||
->assertAttribute('[data-md-navigation-rail-menu]', 'aria-expanded', 'true')
|
||||
->assertNoJavaScriptErrors();
|
||||
|
||||
// The choice outlives the reload, and holds to the top of the class.
|
||||
@@ -126,12 +126,12 @@ it('expands the rail from large, and keeps it collapsed across a reload from the
|
||||
$page = shellPage(1200, 900, '/rail-probe')
|
||||
->assertScript(railWidth(256))
|
||||
->assertScript("window.eval('window.firstPaint.width') === '256px'")
|
||||
->assertAttribute('[data-navigation-rail-menu]', 'aria-expanded', 'true');
|
||||
->assertAttribute('[data-md-navigation-rail-menu]', 'aria-expanded', 'true');
|
||||
|
||||
$page->click('[data-navigation-rail-menu]')
|
||||
$page->click('[data-md-navigation-rail-menu]')
|
||||
->assertScript("document.documentElement.getAttribute('data-rail') === 'collapsed'")
|
||||
->assertScript("localStorage.getItem('material-rail') === 'collapsed'")
|
||||
->assertAttribute('[data-navigation-rail-menu]', 'aria-expanded', 'false')
|
||||
->assertAttribute('[data-md-navigation-rail-menu]', 'aria-expanded', 'false')
|
||||
->assertScript(railWidth(96));
|
||||
|
||||
navigationReady($page->refresh())
|
||||
@@ -152,7 +152,7 @@ it('expands the rail by default at extra-large', function () {
|
||||
shellPage(1600, 900)
|
||||
->assertScript(railWidth(256))
|
||||
->assertScript('getComputedStyle('.BOTTOM_BAR.").display === 'none'")
|
||||
->assertAttribute('[data-navigation-rail-menu]', 'aria-expanded', 'true')
|
||||
->assertAttribute('[data-md-navigation-rail-menu]', 'aria-expanded', 'true')
|
||||
->assertNoJavaScriptErrors();
|
||||
});
|
||||
|
||||
@@ -160,26 +160,26 @@ it('opens the modal rail from its menu button below expanded, holding focus unti
|
||||
$page = shellPage(839);
|
||||
|
||||
// From the keyboard: WebKit neither focuses a button on click nor returns focus to one that never had it.
|
||||
$page->script("document.querySelector('[data-navigation-rail-menu]').focus()");
|
||||
$page->keys('[data-navigation-rail-menu]', 'Enter')
|
||||
->assertScript(RAIL.".hasAttribute('data-open')")
|
||||
$page->script("document.querySelector('[data-md-navigation-rail-menu]').focus()");
|
||||
$page->keys('[data-md-navigation-rail-menu]', 'Enter')
|
||||
->assertScript(RAIL.".hasAttribute('data-md-open')")
|
||||
->assertScript('Math.round('.RAIL_PANEL.'.getBoundingClientRect().width) === 256')
|
||||
->assertScript(railWidth(96))
|
||||
->assertScript("getComputedStyle(document.querySelector('[data-navigation-rail-heading]')).display !== 'none'")
|
||||
->assertScript("getComputedStyle(document.querySelector('[data-md-navigation-rail-heading]')).display !== 'none'")
|
||||
->assertScript(RAIL_PANEL.'.contains(document.activeElement)')
|
||||
->assertScript("document.getElementById('content').closest('[aria-hidden=\"true\"]') !== null")
|
||||
->assertAttribute('[data-navigation-rail-menu]', 'aria-expanded', 'true');
|
||||
->assertAttribute('[data-md-navigation-rail-menu]', 'aria-expanded', 'true');
|
||||
|
||||
$page->keys(':focus', 'Escape')
|
||||
->assertScript('! '.RAIL.".hasAttribute('data-open')")
|
||||
->assertScript('! '.RAIL.".hasAttribute('data-md-open')")
|
||||
->assertScript("document.getElementById('content').closest('[aria-hidden=\"true\"]') === null")
|
||||
->assertScript("document.activeElement === document.querySelector('[data-navigation-rail-menu]')");
|
||||
->assertScript("document.activeElement === document.querySelector('[data-md-navigation-rail-menu]')");
|
||||
|
||||
$page->keys('[data-navigation-rail-menu]', 'Enter')
|
||||
->assertScript(RAIL.".hasAttribute('data-open')");
|
||||
$page->keys('[data-md-navigation-rail-menu]', 'Enter')
|
||||
->assertScript(RAIL.".hasAttribute('data-md-open')");
|
||||
|
||||
$page->click('[data-navigation-rail-scrim]')
|
||||
->assertScript('! '.RAIL.".hasAttribute('data-open')")
|
||||
$page->click('[data-md-navigation-rail-scrim]')
|
||||
->assertScript('! '.RAIL.".hasAttribute('data-md-open')")
|
||||
->assertScript("localStorage.getItem('material-rail') === null");
|
||||
});
|
||||
|
||||
@@ -187,32 +187,32 @@ it('slides the modal rail in on a compact window from the app bar\'s menu button
|
||||
$page = shellPage(599, 860);
|
||||
|
||||
$page->click('@shell-menu')
|
||||
->assertScript(RAIL.".hasAttribute('data-open')")
|
||||
->assertScript(RAIL.".hasAttribute('data-md-open')")
|
||||
->assertScript('getComputedStyle('.RAIL_PANEL.").display === 'flex'")
|
||||
->assertScript('Math.round('.RAIL_PANEL.'.getBoundingClientRect().left) === 0')
|
||||
->assertScript(RAIL_PANEL.'.contains(document.activeElement)');
|
||||
|
||||
$page->keys(':focus', 'Escape')
|
||||
->assertScript('! '.RAIL.".hasAttribute('data-open')")
|
||||
->assertScript('! '.RAIL.".hasAttribute('data-md-open')")
|
||||
->assertScript('getComputedStyle('.RAIL_PANEL.").display === 'none'");
|
||||
});
|
||||
|
||||
it('keeps the rail and the theme through wire:navigate and moves aria-current', function () {
|
||||
$page = shellPage(1200);
|
||||
|
||||
$page->click('[data-navigation-rail-menu]')
|
||||
$page->click('[data-md-navigation-rail-menu]')
|
||||
->assertScript("document.documentElement.getAttribute('data-rail') === 'collapsed'");
|
||||
|
||||
$page->script("window.eval(\"Alpine.store('theme').set('dark'); window.samePage = true\")");
|
||||
|
||||
$page->click('[data-navigation-rail-panel] a[href$="/material/shell/starred"]')
|
||||
$page->click('[data-md-navigation-rail-panel] a[href$="/material/shell/starred"]')
|
||||
->assertSeeIn('@shell-page', 'This is the starred page.')
|
||||
->assertScript("window.eval('window.samePage') === true")
|
||||
->assertScript("document.documentElement.getAttribute('data-rail') === 'collapsed'")
|
||||
->assertScript("document.documentElement.getAttribute('data-theme') === 'dark'")
|
||||
->assertScript(railWidth(96))
|
||||
->assertScript("document.querySelector('[data-navigation-rail-panel] [aria-current=\"page\"]').getAttribute('href').endsWith('/material/shell/starred')")
|
||||
->assertScript("document.querySelectorAll('[data-navigation-rail-panel] [aria-current=\"page\"]').length === 1")
|
||||
->assertScript("document.querySelector('[data-md-navigation-rail-panel] [aria-current=\"page\"]').getAttribute('href').endsWith('/material/shell/starred')")
|
||||
->assertScript("document.querySelectorAll('[data-md-navigation-rail-panel] [aria-current=\"page\"]').length === 1")
|
||||
->assertNoJavaScriptErrors();
|
||||
});
|
||||
|
||||
@@ -258,3 +258,114 @@ it('lifts the snackbar and the page above something docked on the phone\'s bar',
|
||||
$page->assertScript("{$snackbarBottom} === 120")
|
||||
->assertScript("{$contentPadding} === 104");
|
||||
});
|
||||
|
||||
/**
|
||||
* A page for the navigation bar and rail props the shell's own adaptive rail never exercises:
|
||||
* `tall`, `hide-on-scroll` (with a pinned snackbar), a narrow centred rail, and a rail that hides
|
||||
* when collapsed. A wide, fixed viewport throughout, so none of M3's breakpoints interfere with
|
||||
* what each example's own props already decide (docs/plans/material-3-browser-tests.md § Navigation).
|
||||
*/
|
||||
function navigationExtrasProbe(): mixed
|
||||
{
|
||||
Route::middleware('web')->get('/navigation-extras-probe', fn () => Blade::render(<<<'BLADE'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<x-theme-script />
|
||||
@vite(config('livewire-material.showcase.vite'))
|
||||
@livewireStyles
|
||||
</head>
|
||||
<body>
|
||||
<div id="tall-bar">
|
||||
<x-navigation-bar tall>
|
||||
<x-navigation-bar-item label="Inbox" icon="inbox" link="#a" no-wire-navigate active />
|
||||
<x-navigation-bar-item label="Sent" icon="send" link="#b" no-wire-navigate />
|
||||
</x-navigation-bar>
|
||||
</div>
|
||||
|
||||
<div id="hide-bar">
|
||||
<x-navigation-bar hide-on-scroll>
|
||||
<x-navigation-bar-item label="Inbox" icon="inbox" link="#a" no-wire-navigate active />
|
||||
<x-navigation-bar-item label="Sent" icon="send" link="#b" no-wire-navigate />
|
||||
</x-navigation-bar>
|
||||
</div>
|
||||
|
||||
<div id="narrow-rail" style="display: flex">
|
||||
<x-navigation-rail mode="collapsed" width="narrow" align="center">
|
||||
<x-navigation-rail-item label="Inbox" icon="inbox" link="#a" no-wire-navigate active />
|
||||
<x-navigation-rail-item label="Starred" icon="star" link="#b" no-wire-navigate />
|
||||
<x-navigation-rail-item label="Sent" icon="send" link="#c" no-wire-navigate />
|
||||
</x-navigation-rail>
|
||||
</div>
|
||||
|
||||
<div id="hiding-rail" style="display: flex">
|
||||
<x-navigation-rail hide-when-collapsed>
|
||||
<x-navigation-rail-item label="Canvas" icon="brush" link="#a" no-wire-navigate active />
|
||||
<x-navigation-rail-item label="Layers" icon="layers" link="#b" no-wire-navigate />
|
||||
</x-navigation-rail>
|
||||
<button type="button" id="open-hiding-rail" x-data x-on:click="$store.rail.show()">Open navigation</button>
|
||||
</div>
|
||||
|
||||
<div style="height: 250vh"></div>
|
||||
|
||||
<x-toast />
|
||||
@livewireScripts
|
||||
</body>
|
||||
</html>
|
||||
BLADE));
|
||||
|
||||
return navigationReady(visit('/navigation-extras-probe')->resize(1000, 900));
|
||||
}
|
||||
|
||||
it('draws the tall navigation bar, icon over label at every width', function () {
|
||||
$page = navigationExtrasProbe();
|
||||
|
||||
$page->assertScript("Math.round(document.querySelector('#tall-bar [data-md-navigation-bar-items]').getBoundingClientRect().height) === 80")
|
||||
->assertScript("getComputedStyle(document.querySelector('#tall-bar [data-md-navigation-pill]')).flexDirection === 'column'")
|
||||
->assertNoJavaScriptErrors();
|
||||
});
|
||||
|
||||
it('hides the bar on a scroll down and never while a pinned snackbar is on screen', function () {
|
||||
$page = navigationExtrasProbe();
|
||||
$hidden = "document.querySelector('#hide-bar [data-md-navigation-bar]').hasAttribute('data-md-hidden')";
|
||||
|
||||
$page->script('window.scrollTo(0, 400)');
|
||||
$page->assertScript("{$hidden} === true")
|
||||
->assertNoJavaScriptErrors();
|
||||
|
||||
// Back to the top brings it back, as a fresh scroll-down would; pin a snackbar first.
|
||||
$page->script('window.scrollTo(0, 0)');
|
||||
$page->assertScript("{$hidden} === false");
|
||||
|
||||
$page->script("materialToast('Pinned', { sticky: true })")
|
||||
->assertScript("document.querySelector('[data-md-toast-snackbar]')?.textContent.includes('Pinned')");
|
||||
|
||||
$page->script('window.scrollTo(0, 400)');
|
||||
$page->assertScript("{$hidden} === false")
|
||||
->assertNoJavaScriptErrors();
|
||||
});
|
||||
|
||||
it('draws the narrow collapsed width and centres the destinations', function () {
|
||||
$page = navigationExtrasProbe();
|
||||
|
||||
$page->assertScript("Math.round(document.querySelector('#narrow-rail [data-md-navigation-rail]').getBoundingClientRect().width) === 80")
|
||||
->assertScript("getComputedStyle(document.querySelector('#narrow-rail [data-md-navigation-rail-destinations]')).justifyContent === 'safe center'")
|
||||
->assertNoJavaScriptErrors();
|
||||
});
|
||||
|
||||
it('takes a rail out of the layout entirely when it hides collapsed, and back over the page', function () {
|
||||
$page = navigationExtrasProbe();
|
||||
$rail = "document.querySelector('#hiding-rail [data-md-navigation-rail]')";
|
||||
$railWidth = "Math.round({$rail}.getBoundingClientRect().width)";
|
||||
|
||||
$page->assertScript("{$railWidth} > 200")
|
||||
->click('#hiding-rail [data-md-navigation-rail-menu]')
|
||||
->assertScript("{$railWidth} === 0")
|
||||
->assertScript("! {$rail}.hasAttribute('data-md-open')");
|
||||
|
||||
// The only way back: an application's own menu button calling $store.rail.show().
|
||||
$page->click('#open-hiding-rail')
|
||||
->assertScript("{$rail}.hasAttribute('data-md-open')")
|
||||
->assertScript("getComputedStyle(document.querySelector('#hiding-rail [data-md-navigation-rail-panel]')).display === 'flex'")
|
||||
->assertNoJavaScriptErrors();
|
||||
});
|
||||
|
||||
@@ -10,9 +10,9 @@ it('moves between sections through the rail and the next-section link, keeping t
|
||||
$page = visit('/material')->waitForEvent('networkidle')
|
||||
->assertScript("document.readyState === 'complete' && typeof window.Alpine !== 'undefined' && typeof window.Livewire !== 'undefined'");
|
||||
|
||||
$page->click('[data-navigation-rail-panel] a[href$="/material/buttons"]')
|
||||
$page->click('[data-md-navigation-rail-panel] a[href$="/material/buttons"]')
|
||||
->assertSee('Variants')
|
||||
->assertScript("document.querySelector('[data-navigation-rail-panel] [aria-current=\"page\"]').getAttribute('href').endsWith('/material/buttons')")
|
||||
->assertScript("document.querySelector('[data-md-navigation-rail-panel] [aria-current=\"page\"]').getAttribute('href').endsWith('/material/buttons')")
|
||||
->assertScript("document.title === 'Buttons · Livewire Material'");
|
||||
|
||||
$page->click('[data-test="next-section"]')
|
||||
|
||||
@@ -19,27 +19,27 @@ it('draws the adaptive rail, the bar, the content region and the snackbar host',
|
||||
$html = (string) $this->blade('<x-scaffold :destinations="$destinations">The page</x-scaffold>', ['destinations' => scaffoldDestinations()]);
|
||||
|
||||
expect($html)
|
||||
->toContain('data-navigation-rail="adaptive"')
|
||||
->toContain('data-navigation-bar')
|
||||
->toContain('data-md-navigation-rail="adaptive"')
|
||||
->toContain('data-md-navigation-bar')
|
||||
->toContain('<main id="content" tabindex="-1" wire:transition.navigate')
|
||||
->toContain('max-expanded:overflow-x-clip')
|
||||
->toContain('The page')
|
||||
->toContain('x-data="materialSnackbar"')
|
||||
->toMatch('/<a\s+href="#content"\s+data-skip-link/')
|
||||
->and(strpos($html, 'data-skip-link'))->toBeLessThan(strpos($html, 'data-navigation-rail='));
|
||||
->and(strpos($html, 'data-skip-link'))->toBeLessThan(strpos($html, 'data-md-navigation-rail='));
|
||||
});
|
||||
|
||||
it('puts every destination in the rail and only those marked for the bar in the bar', function () {
|
||||
$html = (string) $this->blade('<x-scaffold :destinations="$destinations" />', ['destinations' => scaffoldDestinations()]);
|
||||
|
||||
$rail = substr($html, strpos($html, 'data-navigation-rail='), strpos($html, 'data-app-shell-bar') - strpos($html, 'data-navigation-rail='));
|
||||
$rail = substr($html, strpos($html, 'data-md-navigation-rail='), strpos($html, 'data-app-shell-bar') - strpos($html, 'data-md-navigation-rail='));
|
||||
$bar = substr($html, strpos($html, 'data-app-shell-bar'));
|
||||
|
||||
expect(substr_count($rail, '<a data-navigation-rail-item'))->toBe(4)
|
||||
->and(substr_count($bar, '<a data-navigation-bar-item'))->toBe(2)
|
||||
expect(substr_count($rail, '<a data-md-navigation-rail-item'))->toBe(4)
|
||||
->and(substr_count($bar, '<a data-md-navigation-bar-item'))->toBe(2)
|
||||
->and($bar)->toContain('Inbox')->toContain('Sent')->not->toContain('Travel')
|
||||
->and($rail)->toContain('data-navigation-rail-heading>Labels</p>')
|
||||
->and(substr_count($rail, 'data-navigation-rail-section'))->toBe(1)
|
||||
->and($rail)->toContain('data-md-navigation-rail-heading>Labels</p>')
|
||||
->and(substr_count($rail, 'data-md-navigation-rail-section'))->toBe(1)
|
||||
->and($rail)->toMatch('/href="\/receipts"(?![^>]*wire:navigate)/')
|
||||
->and(substr_count($html, 'aria-current="page"'))->toBe(2);
|
||||
});
|
||||
@@ -99,28 +99,28 @@ it('lifts the snackbar above the bar only when there is a bar', function () {
|
||||
|
||||
it('passes M3\'s tall bar through, and the bottom offset grows with it', function () {
|
||||
expect((string) $this->blade('<x-scaffold :destinations="$destinations" tall-bar />', ['destinations' => scaffoldDestinations()]))
|
||||
->toMatch('/data-navigation-bar\s+data-tall\s/')
|
||||
->toMatch('/data-md-navigation-bar\s+data-md-tall\s/')
|
||||
->toContain('max-medium:[--material-bottom-bar:calc(5rem+')
|
||||
->not->toContain('[--material-bottom-bar:calc(4rem+')
|
||||
->and((string) $this->blade('<x-scaffold :destinations="$destinations" />', ['destinations' => scaffoldDestinations()]))
|
||||
->not->toContain('data-tall')
|
||||
->not->toContain('data-md-tall')
|
||||
->toContain('max-medium:[--material-bottom-bar:calc(4rem+');
|
||||
});
|
||||
|
||||
it('lets the bar leave the window while the page scrolls down', function () {
|
||||
expect((string) $this->blade('<x-scaffold :destinations="$destinations" hide-bar-on-scroll />', ['destinations' => scaffoldDestinations()]))
|
||||
->toContain('data-hide-on-scroll')
|
||||
->toContain('data-md-hide-on-scroll')
|
||||
->toContain('x-data="materialNavigationBar"')
|
||||
->and((string) $this->blade('<x-scaffold :destinations="$destinations" />', ['destinations' => scaffoldDestinations()]))
|
||||
->not->toContain('data-hide-on-scroll');
|
||||
->not->toContain('data-md-hide-on-scroll');
|
||||
});
|
||||
|
||||
it('exposes the rail that hides when collapsed', function () {
|
||||
expect((string) $this->blade('<x-scaffold :destinations="$destinations" hide-rail-when-collapsed />', ['destinations' => scaffoldDestinations()]))
|
||||
->toContain('data-hide-when-collapsed')
|
||||
->toContain('data-md-hide-when-collapsed')
|
||||
->toContain("materialNavigationRail('adaptive', true)")
|
||||
->and((string) $this->blade('<x-scaffold :destinations="$destinations" />', ['destinations' => scaffoldDestinations()]))
|
||||
->not->toContain('data-hide-when-collapsed')
|
||||
->not->toContain('data-md-hide-when-collapsed')
|
||||
->toContain("materialNavigationRail('adaptive', false)");
|
||||
});
|
||||
|
||||
@@ -150,7 +150,7 @@ it('places each slot once', function () {
|
||||
expect(substr_count($html, $slot))->toBe(1);
|
||||
}
|
||||
|
||||
expect($html)->toMatch('/data-navigation-rail-header.*BRAND.*FAB.*data-navigation-rail-footer.*FOOTER.*data-app-shell-actions.*ACTIONS.*APP BAR.*<main.*PAGE/s');
|
||||
expect($html)->toMatch('/data-md-navigation-rail-header.*BRAND.*FAB.*data-md-navigation-rail-footer.*FOOTER.*data-app-shell-actions.*ACTIONS.*APP BAR.*<main.*PAGE/s');
|
||||
});
|
||||
|
||||
it('spans the window with a banner, above the rail, and renders none without the slot', function () {
|
||||
@@ -163,7 +163,7 @@ it('spans the window with a banner, above the rail, and renders none without the
|
||||
|
||||
// Bars, then rails, then panes: the banner is outside the row the rail and the page share.
|
||||
expect($html)
|
||||
->toMatch('/data-app-shell-banner.*WINDOW BAR.*data-navigation-rail=.*<main/s')
|
||||
->toMatch('/data-app-shell-banner.*WINDOW BAR.*data-md-navigation-rail=.*<main/s')
|
||||
->and((string) $this->blade('<x-scaffold :destinations="$destinations" />', ['destinations' => scaffoldDestinations()]))
|
||||
->not->toContain('data-app-shell-banner');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user