busy-office-ui
Menu

Navbar

The application header: brand, environment marker, and the actions that belong to the whole app rather than the current screen. This page's own header is the live demo. Not for the current page's own title or actions — the navbar is suite-level chrome, identical on every screen; the moment it carries "Purchase order PO-88213" or a Save button it stops being a fixed landmark and starts changing under the reader. Page identity belongs in the content area with the breadcrumb and heading, and a screen's actions in its own form actions bar. The boundary is drawn in full on the app frame pattern.

Brand, spacer, actions

busy-office ERP UAT

One spacer element does the layout — everything before it sits at the start, everything after at the end. An environment badge (UAT, SANDBOX) next to the brand is the cheapest guard against someone approving a real invoice in a test system.

Markup

<header class="bo-navbar bo-app-shell__header">
  <span class="bo-navbar__brand">busy-office ERP</span>
  <span class="bo-badge bo-badge--accent">UAT</span>
  <span class="bo-navbar__spacer"></span>   <!-- pushes what follows to the end -->
  <button class="bo-btn bo-btn--ghost bo-btn--icon" aria-label="Notifications">🔔</button>
</header>

Quick reference generated

ClassRole
.bo-navbar block (root)
.bo-navbar__brand part: brand
.bo-navbar__spacer part: spacer

API generated from CSS

Blocks bo-navbar
Parts bo-navbar__brandbo-navbar__spacer
JS required None — CSS-only.
  • Use a real <header>; inside the app shell add .bo-app-shell__header so it takes the shell grid slot.
  • The navbar is app-level. Screen-level actions belong in the page or the data-table toolbar, not up here.
  • Icon-only buttons need an aria-label — the icon is decoration.
Contrast — 15 AA pairs this component uses (generated, CI-gated)
TextonLightDark
text-primary bg-surface 17.74 16.15
text-primary bg-canvas 16.98 18.08
text-secondary bg-surface 10.31 11.46
text-muted bg-surface 7.56 6.65
bg-surface text-primary 17.74 16.15
danger-text bg-surface 6.47 8.89
success-text bg-surface 5.02 12.02
accent bg-surface 5.47 9.07
text-primary bg-hover 16.12 13.75
text-primary bg-selected 17.01 11.86
text-primary bg-surface-raised 17.74 14.51
border-control bg-surface 4.83 6.65
--bo-state-error-color bg-surface 4.83 6.1
warning-strong bg-surface 5.02 7.86
text-primary bg-muted 16.12 13.75

Maturity generated

Introduced
v0.3.0
CSS floor
Chrome/Edge 99 · Firefox 97 · Safari 15.4
Alignment scored
2026-08-23
Assistive-tech evidence
None recorded

Pin this component's first release with npm i @busy-office/ui@0.3.0. The floor is derived from this component's stylesheet alone — set by @layer — so it sits at or below the whole framework's Chrome/Edge 119 · Firefox 129 · Safari 17.5. No assistive-technology runtime result is recorded for any component: it needs a human listening to VoiceOver and NVDA on owner hardware; no gate in this repo can simulate announcement behaviour. What automation covers instead is test:axe across every page at 1440 and 390, and check:forced-colors — see accessibility.

Design-system alignment generated

100% (15/15) — how closely this component follows the design language. Each rule is scored 0-3 against a checkable citation; rules that don't apply leave the denominator. Scored 2026-08-23.

Rule Score Evidence
Typography 3 / 3 no raw font-size; weight via --bo-font-weight-semibold
Colour 3 / 3 zero raw colour — surface/border/text all tokens
Spacing 3 / 3 the 3rem bar height states why it is a FLOOR and not a fixed height — a consistent landmark that must still grow for a taller control, which is also the WCAG 1.4.12 answer (94.6b)
Interaction n/a a container: it holds controls but introduces none of its own
Content 3 / 3 opener carries the wrong-choice clause: "Not for the current page's own title or actions" — suite-level chrome that starts carrying a record title or a Save button stops being a fixed landmark; points at breadcrumb + heading in the content area, a form-actions bar, and app-frame for the full boundary. Blind re-scored 2026-08-23 (Polish round 10), which independently confirmed the demo, the ApiTable note and the docs' own header all hold the same line.
Fit 3 / 3 the app top bar; po-app uses it at 3 sites (examples/po-app/server.mjs)
↑↓ move Enter open Esc close