diff --git a/resources/views/components/scaffold.blade.php b/resources/views/components/scaffold.blade.php index b91574a2..889fda5a 100644 --- a/resources/views/components/scaffold.blade.php +++ b/resources/views/components/scaffold.blade.php @@ -101,7 +101,8 @@ window never clips what overhangs on purpose. Nothing application-specific belongs in here: an app's destinations and chrome come in through - the props and slots. --}} + the props and slots. The caller's `class` and `style` land on the root, `data-md-scaffold` + itself — the element `style="--material-banner: 4rem"` above sets a custom property on. --}} @props([ 'destinations' => [], @@ -137,7 +138,7 @@ $groups = $items->chunkWhile(fn (array $item, int $key, $chunk): bool => $item['section'] === $chunk->last()['section']); @endphp -
+
only(['class', 'style']) }}> {{ __('Skip to content') }} @isset($banner) diff --git a/resources/views/components/tooltip.blade.php b/resources/views/components/tooltip.blade.php index 8038f1b8..31c3ab8e 100644 --- a/resources/views/components/tooltip.blade.php +++ b/resources/views/components/tooltip.blade.php @@ -14,7 +14,14 @@ Drawn by resources/css/components/tooltip.css. It is aria-hidden: an icon button takes the same words as its aria-label, and a labelled - control would otherwise read them twice. --}} + control would otherwise read them twice. + + The caller's `class` and `style` land on the root — standalone, that is the wrapper this + component draws around the trigger (`data-md-tooltip-anchor`), merged with its own + `anchor-name`. Passed an `anchor` instead, the component renders no wrapper of its own: only + the popover bubble, a fragment beside another component's root (`` and + friends never forward a caller's attributes to it), so there is nothing of the caller's to + place. --}} @props([ 'text', @@ -29,7 +36,7 @@ @endphp @if ($standalone) - + merge(['style' => "anchor-name: {$anchor}"]) }}> {{ $slot }} @endif diff --git a/tests/Feature/Components/ScaffoldTest.php b/tests/Feature/Components/ScaffoldTest.php index ad2c12eb..94b7742f 100644 --- a/tests/Feature/Components/ScaffoldTest.php +++ b/tests/Feature/Components/ScaffoldTest.php @@ -48,6 +48,12 @@ it('puts every destination in the rail and only those marked for the bar in the ->and(substr_count($html, 'aria-current="page"'))->toBe(2); }); +it('takes the caller\'s class and style on its own root', function () { + $root = layoutRoot((string) $this->blade('', ['destinations' => scaffoldDestinations()])); + + expect($root)->toMatchArray(['<' => 'div', 'data-md-scaffold' => '', 'class' => 'app-shell', 'style' => '--material-banner: 4rem']); +}); + it('speaks a destination\'s badge in its own words when it has them', function () { $html = (string) $this->blade('', ['destinations' => [ ['title' => 'Get started', 'icon' => 'rocket_launch', 'url' => '/start', 'badge' => '0/3', 'badgeLabel' => '0 of 3 done'], @@ -247,7 +253,7 @@ it('marks the scaffold, and draws the FAB after the page\'s bar and before the p BLADE, ['destinations' => scaffoldDestinations()]); // M3 puts a FAB early in the focus order: after the bar, before the content. - expect($html)->toMatch('/^\s*/') + expect($html)->toMatch('/^\s*/') ->not->toContain('data-app-shell') ->toMatch('/APP BAR.*
')); + + expect($root)->toMatchArray(['<' => 'span', 'data-md-tooltip-anchor' => '', 'class' => 'inline-flex']) + ->and($root['style'])->toStartWith('anchor-name: --material-tooltip-')->toEndWith('; gap: 4px;'); +}); + it('escapes its text', function () { $this->blade('x') ->assertSee('<b>bold</b>', false);