From 79ca9a28b42676b554893deed7a9ee20c827c266 Mon Sep 17 00:00:00 2001 From: Andreas Reinhold / reini Date: Tue, 15 Sep 2026 06:10:01 +0200 Subject: [PATCH] Stop drawing each section's title twice on its page Plan step 38 review: the frame's structural rule that kept a section's own

for screen readers (Tailwind's [&>section>h2]:sr-only before, a showcase.css rule during the rewrite) was removed as dead weight once every section had a real heading, so each page drew its title twice, the

and an identical headline under it. The

s are md-visually-hidden again, the frame's comment says why, and the section page test asserts it. The Layout section's description said "window size classes"; M3's term is breakpoints. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Qwx5USif3wFFmxtHg5U1g9 --- resources/views/showcase/section.blade.php | 6 +++--- resources/views/showcase/sections/bars.blade.php | 2 +- resources/views/showcase/sections/buttons.blade.php | 2 +- resources/views/showcase/sections/carousel.blade.php | 2 +- resources/views/showcase/sections/chips.blade.php | 2 +- resources/views/showcase/sections/colour.blade.php | 2 +- .../views/showcase/sections/communication.blade.php | 2 +- .../views/showcase/sections/containment.blade.php | 2 +- resources/views/showcase/sections/data.blade.php | 2 +- resources/views/showcase/sections/elevation.blade.php | 2 +- resources/views/showcase/sections/fields.blade.php | 2 +- resources/views/showcase/sections/icons.blade.php | 2 +- resources/views/showcase/sections/layout.blade.php | 2 +- resources/views/showcase/sections/menus.blade.php | 2 +- resources/views/showcase/sections/motion.blade.php | 2 +- .../views/showcase/sections/navigation.blade.php | 2 +- resources/views/showcase/sections/pages.blade.php | 2 +- resources/views/showcase/sections/pickers.blade.php | 2 +- resources/views/showcase/sections/progress.blade.php | 2 +- resources/views/showcase/sections/shape.blade.php | 2 +- resources/views/showcase/sections/sliders.blade.php | 2 +- .../views/showcase/sections/timepickers.blade.php | 2 +- resources/views/showcase/sections/type.blade.php | 2 +- src/Showcase/Sections.php | 2 +- tests/Feature/ShowcaseTest.php | 11 +++++++++-- 25 files changed, 35 insertions(+), 28 deletions(-) diff --git a/resources/views/showcase/section.blade.php b/resources/views/showcase/section.blade.php index e0c4b0a3..8a722249 100644 --- a/resources/views/showcase/section.blade.php +++ b/resources/views/showcase/section.blade.php @@ -1,6 +1,6 @@ {{-- One section of the showcase on a page of its own, with the way on to the next. The page's - heading names the section, so the section's own heading is only for a screen reader - (`data-md-showcase-sections`'s own rule in resources/css/showcase.css). --}} + heading names the section, so the section's own

is `md-visually-hidden`: there for a + screen reader's outline of the
, not drawn a second time under the

. --}} @extends('livewire-material::showcase.layout') @@ -19,7 +19,7 @@

{{ $sections[$section]['title'] }}

- + @include('livewire-material::showcase.sections.'.$section) diff --git a/resources/views/showcase/sections/bars.blade.php b/resources/views/showcase/sections/bars.blade.php index f83528bd..7cff9537 100644 --- a/resources/views/showcase/sections/bars.blade.php +++ b/resources/views/showcase/sections/bars.blade.php @@ -168,7 +168,7 @@ @endphp -

App bars, toolbars and tabs

+

App bars, toolbars and tabs

<x-app-bar>, <x-toolbar>, <x-tabs>, <x-tab>, <x-section-nav>, <x-account-menu> and <x-theme-toggle>. diff --git a/resources/views/showcase/sections/buttons.blade.php b/resources/views/showcase/sections/buttons.blade.php index 86873160..caa95008 100644 --- a/resources/views/showcase/sections/buttons.blade.php +++ b/resources/views/showcase/sections/buttons.blade.php @@ -173,7 +173,7 @@ @endphp -

Buttons

+

Buttons

<x-button>: label buttons, icon buttons and toggles in M3 Expressive's five sizes. diff --git a/resources/views/showcase/sections/carousel.blade.php b/resources/views/showcase/sections/carousel.blade.php index a0167dcc..8d6a3348 100644 --- a/resources/views/showcase/sections/carousel.blade.php +++ b/resources/views/showcase/sections/carousel.blade.php @@ -92,7 +92,7 @@ @endphp -

Carousel

+

Carousel

<x-carousel> and <x-carousel-item>: items that change size between M3's keylines as they scroll. diff --git a/resources/views/showcase/sections/chips.blade.php b/resources/views/showcase/sections/chips.blade.php index e9a21946..2cddedbd 100644 --- a/resources/views/showcase/sections/chips.blade.php +++ b/resources/views/showcase/sections/chips.blade.php @@ -68,7 +68,7 @@ @endphp -

Chips

+

Chips

<x-chip> — assist, filter, input and suggestion — and <x-chip-set>. diff --git a/resources/views/showcase/sections/colour.blade.php b/resources/views/showcase/sections/colour.blade.php index d441c608..62004f2f 100644 --- a/resources/views/showcase/sections/colour.blade.php +++ b/resources/views/showcase/sections/colour.blade.php @@ -29,7 +29,7 @@ @endphp -

Colour

+

Colour

Every role as a --md-sys-color-* token, generated by diff --git a/resources/views/showcase/sections/communication.blade.php b/resources/views/showcase/sections/communication.blade.php index e5c4a31a..1f9ee0a4 100644 --- a/resources/views/showcase/sections/communication.blade.php +++ b/resources/views/showcase/sections/communication.blade.php @@ -106,7 +106,7 @@ @endphp -

Communication

+

Communication

<x-badge>, <x-toast> (the snackbar host, fed by the Toasts concern or materialToast()), diff --git a/resources/views/showcase/sections/containment.blade.php b/resources/views/showcase/sections/containment.blade.php index 9b7834e7..fa423845 100644 --- a/resources/views/showcase/sections/containment.blade.php +++ b/resources/views/showcase/sections/containment.blade.php @@ -246,7 +246,7 @@ @endphp -

Containment

+

Containment

<x-card>, <x-list> and <x-list-item>, <x-divider>, <x-collapse>, diff --git a/resources/views/showcase/sections/data.blade.php b/resources/views/showcase/sections/data.blade.php index eedf2a88..cd4169f2 100644 --- a/resources/views/showcase/sections/data.blade.php +++ b/resources/views/showcase/sections/data.blade.php @@ -44,7 +44,7 @@ @endphp -

Data

+

Data

<x-table>, <x-sort-header>, and Laravel's and Livewire's paginators. diff --git a/resources/views/showcase/sections/elevation.blade.php b/resources/views/showcase/sections/elevation.blade.php index 78f82a8e..999259f7 100644 --- a/resources/views/showcase/sections/elevation.blade.php +++ b/resources/views/showcase/sections/elevation.blade.php @@ -1,5 +1,5 @@ -

Elevation

+

Elevation

Five shadow levels as --md-sys-elevation-*, for what floats over content. diff --git a/resources/views/showcase/sections/fields.blade.php b/resources/views/showcase/sections/fields.blade.php index cf258a95..48201b3f 100644 --- a/resources/views/showcase/sections/fields.blade.php +++ b/resources/views/showcase/sections/fields.blade.php @@ -222,7 +222,7 @@ @endphp -

Text fields and selection

+

Text fields and selection

<x-input>, <x-password>, <x-textarea>, <x-select>, <x-file> diff --git a/resources/views/showcase/sections/icons.blade.php b/resources/views/showcase/sections/icons.blade.php index 6d94aae3..440f2f94 100644 --- a/resources/views/showcase/sections/icons.blade.php +++ b/resources/views/showcase/sections/icons.blade.php @@ -18,7 +18,7 @@ }" x-intersect.once="load()" > -

Icons

+

Icons

Every Material Symbol (Rounded, 400, grade 0) as <x-icon name="…" />, outlined or filled, diff --git a/resources/views/showcase/sections/layout.blade.php b/resources/views/showcase/sections/layout.blade.php index 7eafe179..f0c437b7 100644 --- a/resources/views/showcase/sections/layout.blade.php +++ b/resources/views/showcase/sections/layout.blade.php @@ -31,7 +31,7 @@ @endphp -

Layout

+

Layout

Widths are M3's breakpoints and nothing else: compact below 600px, then medium 600, expanded 840, large 1200 diff --git a/resources/views/showcase/sections/menus.blade.php b/resources/views/showcase/sections/menus.blade.php index 88d7285f..bb690b37 100644 --- a/resources/views/showcase/sections/menus.blade.php +++ b/resources/views/showcase/sections/menus.blade.php @@ -140,7 +140,7 @@ @endphp -

Menus

+

Menus

<x-menu> with <x-menu-item>, <x-menu-group> and <x-menu-separator>. diff --git a/resources/views/showcase/sections/motion.blade.php b/resources/views/showcase/sections/motion.blade.php index 04435f1f..c09b52f9 100644 --- a/resources/views/showcase/sections/motion.blade.php +++ b/resources/views/showcase/sections/motion.blade.php @@ -1,5 +1,5 @@ -

Motion

+

Motion

M3 Expressive's springs as --md-sys-motion-spatial-* and --md-sys-motion-effects-*, each with its diff --git a/resources/views/showcase/sections/navigation.blade.php b/resources/views/showcase/sections/navigation.blade.php index 10daca09..3e76b7d0 100644 --- a/resources/views/showcase/sections/navigation.blade.php +++ b/resources/views/showcase/sections/navigation.blade.php @@ -160,7 +160,7 @@ @endphp -

Navigation

+

Navigation

<x-navigation-bar> and <x-navigation-bar-item>, <x-navigation-rail>, <x-navigation-rail-item> and <x-navigation-rail-section>, diff --git a/resources/views/showcase/sections/pages.blade.php b/resources/views/showcase/sections/pages.blade.php index 275f2a2f..c619c95e 100644 --- a/resources/views/showcase/sections/pages.blade.php +++ b/resources/views/showcase/sections/pages.blade.php @@ -1,5 +1,5 @@ -

Pages

+

Pages

The error pages, raised for real so an app's own resources/views/errors still wins, and the Markdown mail theme diff --git a/resources/views/showcase/sections/pickers.blade.php b/resources/views/showcase/sections/pickers.blade.php index d3d53b2f..75945c54 100644 --- a/resources/views/showcase/sections/pickers.blade.php +++ b/resources/views/showcase/sections/pickers.blade.php @@ -73,7 +73,7 @@ @endphp -

Date pickers

+

Date pickers

<x-datepicker> — docked, modal and modal input; single dates and ranges. Month and weekday names, the first day of the week and the typed format follow the application's locale; week-start and format set the last two for someone who chose their own. diff --git a/resources/views/showcase/sections/progress.blade.php b/resources/views/showcase/sections/progress.blade.php index 343a90ad..63bf42bd 100644 --- a/resources/views/showcase/sections/progress.blade.php +++ b/resources/views/showcase/sections/progress.blade.php @@ -48,7 +48,7 @@ @endphp -

Progress

+

Progress

<x-progress>: M3 Expressive's linear and circular progress indicators, flat or wavy, determinate or indeterminate. diff --git a/resources/views/showcase/sections/shape.blade.php b/resources/views/showcase/sections/shape.blade.php index 97748a40..159c1686 100644 --- a/resources/views/showcase/sections/shape.blade.php +++ b/resources/views/showcase/sections/shape.blade.php @@ -3,7 +3,7 @@ @endphp -

Shape

+

Shape

The corner scale as a --md-sys-shape-corner-* token, and M3 Expressive's shapes as <x-shape name="…" />. diff --git a/resources/views/showcase/sections/sliders.blade.php b/resources/views/showcase/sections/sliders.blade.php index 2d730310..96d6065f 100644 --- a/resources/views/showcase/sections/sliders.blade.php +++ b/resources/views/showcase/sections/sliders.blade.php @@ -55,7 +55,7 @@ @endphp -

Sliders

+

Sliders

<x-slider>: M3 Expressive's slider on native range inputs — standard, range and centred, horizontal or vertical, five sizes, ticks, value labels and an inset icon. diff --git a/resources/views/showcase/sections/timepickers.blade.php b/resources/views/showcase/sections/timepickers.blade.php index 6382f447..5f64aaaf 100644 --- a/resources/views/showcase/sections/timepickers.blade.php +++ b/resources/views/showcase/sections/timepickers.blade.php @@ -32,7 +32,7 @@ @endphp -

Time pickers

+

Time pickers

<x-timepicker> — M3's dial and input time picker in a modal dialog, opened from a text field. diff --git a/resources/views/showcase/sections/type.blade.php b/resources/views/showcase/sections/type.blade.php index 16e171f5..f43f8f9a 100644 --- a/resources/views/showcase/sections/type.blade.php +++ b/resources/views/showcase/sections/type.blade.php @@ -19,7 +19,7 @@ @endphp -

Type

+

Type

M3's typescale in Google Sans Flex, each style regular and emphasized: md-type-title-lg, md-type-emphasized-title-lg. diff --git a/src/Showcase/Sections.php b/src/Showcase/Sections.php index 50569d7e..9a12e8b3 100644 --- a/src/Showcase/Sections.php +++ b/src/Showcase/Sections.php @@ -128,7 +128,7 @@ class Sections 'shape' => ['title' => 'Shape', 'icon' => 'interests', 'group' => 'Foundations', 'description' => 'Corner radii and the 35 M3 Expressive shapes.'], 'elevation' => ['title' => 'Elevation', 'icon' => 'layers', 'group' => 'Foundations', 'description' => 'Shadows for what floats over content.'], 'motion' => ['title' => 'Motion', 'icon' => 'animation', 'group' => 'Foundations', 'description' => 'Spatial springs and effects easings.'], - 'layout' => ['title' => 'Layout', 'icon' => 'devices', 'group' => 'Foundations', 'description' => 'M3\'s window size classes, what changes at each, and the scaffold\'s response.'], + 'layout' => ['title' => 'Layout', 'icon' => 'devices', 'group' => 'Foundations', 'description' => 'M3\'s breakpoints, what changes at each, and the scaffold\'s response.'], 'icons' => ['title' => 'Icons', 'icon' => 'emoji_symbols', 'group' => 'Foundations', 'description' => 'Every Material Symbol, searchable, outlined and filled.'], 'buttons' => ['title' => 'Buttons', 'icon' => 'smart_button', 'group' => 'Actions', 'description' => 'Buttons, icon buttons, groups, split buttons and FABs.'], 'menus' => ['title' => 'Menus', 'icon' => 'menu_open', 'group' => 'Actions', 'description' => 'Menus with items, groups, choices and shortcuts.'], diff --git a/tests/Feature/ShowcaseTest.php b/tests/Feature/ShowcaseTest.php index 2e798c79..059a2acd 100644 --- a/tests/Feature/ShowcaseTest.php +++ b/tests/Feature/ShowcaseTest.php @@ -35,11 +35,18 @@ it('gives every section a page of its own, linked from the overview and the rail foreach (Sections::all() as $key => $section) { $overview->assertSee(route('livewire-material.section', $key), false); - $this->withoutVite() + $html = $this->withoutVite() ->get("/material/{$key}") ->assertOk() ->assertSee("{$section['title']} · Livewire Material", false) - ->assertSee('id="'.$key.'"', false); + ->assertSee('id="'.$key.'"', false) + ->getContent(); + + // The page's

names the section; the section's own

is for a screen reader only, + // so the title is not drawn twice. + preg_match_all('/]*>/', $html, $headings); + + expect($headings[0][0] ?? null)->toBe('

', "{$key}'s own

is drawn"); } $this->get('/material/not-a-section')->assertNotFound();