App bar
One bar carrying the shield, the application name, the application navigation, search, the theme switch and the signed-in user.
Preview
Code
The three render the same class names, the same ARIA and the same data attributes. That is checked when this site builds: a class in any of these samples that neither the markup contract nor the shipped stylesheet defines fails the build.
<header class="wsu-app-bar wsu-app-bar--compact">
<div class="wsu-app-bar__inner">
<button class="wsu-btn wsu-btn--icon wsu-app-bar__toggle wsu-app-bar__toggle--nav"
type="button" data-wsu-drawer-toggle="app-sidebar">
<span class="wsu-sr-only">Open navigation menu</span>
<svg class="wsu-icon" aria-hidden="true"><use href="/assets/wayne-ui/icons.svg#wsu-menu"/></svg>
</button>
<a class="wsu-app-bar__mark" href="https://wayne.edu/">
<img src="/assets/wayne-ui/marks/wsu-shield.svg" alt="Wayne State University" width="72" height="65">
</a>
<span class="wsu-app-bar__divider" aria-hidden="true"></span>
<a class="wsu-app-bar__brand" href="/">Course Registration</a>
<nav class="wsu-app-bar__nav" aria-label="Primary">
<a class="wsu-app-bar__item" href="/term" aria-current="page">Term</a>
<a class="wsu-app-bar__item" href="/catalog">Catalog</a>
</nav>
<div class="wsu-app-bar__end">
<button class="wsu-btn wsu-btn--icon wsu-app-bar__toggle" type="button" data-wsu-theme-toggle>
<svg class="wsu-icon" aria-hidden="true" data-wsu-theme-icon="light"><use href="/assets/wayne-ui/icons.svg#wsu-moon"/></svg>
<svg class="wsu-icon" aria-hidden="true" data-wsu-theme-icon="dark" hidden><use href="/assets/wayne-ui/icons.svg#wsu-sun"/></svg>
</button>
<span class="wsu-app-bar__user">
<svg class="wsu-icon" aria-hidden="true"><use href="/assets/wayne-ui/icons.svg#wsu-user"/></svg>
<span>ee6515</span>
</span>
</div>
</div>
</header>{{-- Rendered by <x-wsu::app-shell>. Use it directly only when the
application owns its own document. --}}
<x-wsu::app-bar
brand="Course Registration"
home="/"
:nav="[
['label' => 'Term', 'url' => '/term', 'route' => 'term.*'],
['label' => 'Catalog', 'url' => '/catalog', 'route' => 'catalog.*'],
]" /><AppBar
title="Course Registration"
title-href="/"
mark="/assets/wayne-ui/marks/wsu-shield.svg"
:nav="[
{ label: 'Term', href: '/term', current: true },
{ label: 'Catalog', href: '/catalog' },
]"
search
search-action="/search"
user="ee6515"
/>Why it works this way
- One bar, not three. Stacking a full university masthead, a wayne.edu search box and an application bar spends roughly 140px of vertical space before the user reaches anything they came for. On the internal template the shield establishes Wayne State, the application name establishes the tool, and the rest of the bar belongs to the tool.
- On the public template the official masthead sits above this bar, so the shield and divider are dropped rather than being the second and third WSU marks on the page, and the application search becomes an expanding field rather than a second permanent box next to wayne.edu's.
- The current item is marked with aria-current and styled off that attribute. There is no parallel .active class, so the visible state and the announced state are one fact.
Accessibility
- aria-current="page" on the current item, never a class (1.4.1, 4.1.2).
- The menu button and the search toggle are icon-only and each carries a .wsu-sr-only name. The theme toggle is named by aria-label instead, since its text changes with the theme and wayne-ui-css/theme keeps one attribute in sync rather than swapping a text node; verified live that this is also what a screen reader gets on every path, including Blade, whose markup additionally carries a .wsu-sr-only span that the shared runtime's aria-label supersedes the moment it runs, since aria-label always wins the accessible name over element content (4.1.2).
- nav is labeled "Primary" so a screen reader's landmark list distinguishes it from the sidebar.
Success criteria in brackets refer to WCAG 2.2. Every one of them is checked by axe-core in both themes at three viewport widths before this page can be published. See Accessibility for what the gates are.
Props
Blade
| Attribute | Default | What it does |
|---|---|---|
template | config('wayne-ui.template') | "internal" or "public". Drops the shield and divider on the public template, since the masthead above already carries one. |
brand | application name | The tool's name. Links to `home`. |
home | config('wayne-ui.home') | Where `brand` links to. |
nav | config('wayne-ui.nav') | Array of items. `route` decides which is current, via WSU\WayneUi\Support\Nav. |
search | config('wayne-ui.search.enabled') | Application search, not wayne.edu search. |
user | the signed-in user | Resolved from the auth user using the attribute list in config. |
themeToggle | true | The light and dark switch. |
mark | ! public | Shows the university shield. Hidden by default on the public template, where the masthead above already carries one. |
sidebar | 'app-sidebar' when sidebars are enabled | id of the Sidebar the menu button opens. Pass false or null to hide the button. |
searchId | 'app-search' | id of the built-in search field, and of the row it toggles open on narrow widths. |
Vue
| Prop | Type and default | What it does |
|---|---|---|
variant | String, 'compact' | "compact" for internal, "default" when a masthead sits above. |
title / titleHref | String | The application, not the university. |
mark / markHref / markAlt | String, '' / 'https://wayne.edu/' / 'Wayne State University' | University mark, shown only by the compact bar; elsewhere a masthead already carries one. |
nav / navLabel | Array, [] / 'Primary' | [{ label, href, current }]. |
linkAs | String, 'a' | Inertia Link or RouterLink. |
drawer | String, 'app-sidebar' | id of the Sidebar the menu button opens. Empty hides the button. |
search / searchVariant | Boolean, false / 'inline' | "expandable" where a wayne.edu search box is already on the page. |
searchQuery | String, '' | v-model:search-query for the bar's own search field. |
searchLabel | String, 'Search this application' | Accessible name for the bar's own search field. |
searchPlaceholder | String, 'Search' | Shown in the bar's own search field. |
searchAction | String, '' | Form target for the built-in search; omit for a same-page search that emits search instead of navigating. |
searchHint | String, '' | Spoken description of the search field. Set it where a second search box on the page needs distinguishing. |
themeToggle | Boolean, true | Set false to hide the light/dark switch, for a page that controls theme elsewhere. |
user | String, '' | Shown as a static identity rather than a menu. |
In the markup contract
contract/markup-contract.json is extracted from the two static templates and every package tests against it. This is what it records for .wsu-app-bar.
| Template | Elements | Accessibility attributes | Uses |
|---|---|---|---|
| internal apps/examples/static-html/index.html | header | none recorded | 1 |
| public apps/examples/static-html/public-app.html | header | none recorded | 1 |