GitHub

App Bar

The full-bleed chrome shell shared by top nav bars, sub-bars, and footers. It sets a color context (background + currentColor) from semantic tokens via tone, then exposes start / default / end slots. Children — Icon Link, Icon Button, a brand lockup — inherit the color, so a bar's brand comes entirely from tokens.

Stable .astro import EsaAppBar from '@esa/ecology/esa-app-bar.astro';

Tones

Each tone maps to ecology semantic tokens; a spoke re-themes by re-pointing those tokens (e.g. --color-primary, --color-surface-inverse) — never by touching this component.

<EsaAppBar tone="surface"></EsaAppBar>
<EsaAppBar tone="brand"></EsaAppBar>
<EsaAppBar tone="brand-strong"></EsaAppBar>

Slots: start · main · end

The end slot is pushed right with margin-left:auto. This is the whole anatomy of a top bar.

CB Fish
Dashboard
<EsaAppBar tone="brand" as="header">
  <span slot="start"><strong>CB Fish</strong></span>
  <EsaIconLink icon="trees" trailing="chevron-down">Mitigation work</EsaIconLink>
  <EsaIconLink icon="trending-up" trailing="chevron-down">Reporting</EsaIconLink>
  <EsaIconLink icon="credit-card" trailing="chevron-down">Funding</EsaIconLink>
  <EsaIconButton slot="end" icon="search" label="Search" />
  <EsaIconLink slot="end" href="/dashboard" icon="layout-dashboard">Dashboard</EsaIconLink>
  <EsaIconLink slot="end" icon="circle-user" trailing="chevron-down">Angela Zhao</EsaIconLink>
</EsaAppBar>

API

PropTypeDefaultDescription
tone 'surface' | 'brand' | 'brand-strong' 'surface' Color context. surface → --color-surface/text-primary; brand → --color-primary/text-inverse; brand-strong → --color-surface-inverse/text-inverse. Children inherit the text color.
contained boolean false Constrain the inner row to maxWidth and center it.
maxWidth string '1556px' Inner row max-width when contained.
as 'header' | 'nav' | 'footer' | 'div' 'div' Semantic host element.

Theming surface

Every public token this component reads, extracted from its source at build time. The Resolves to column walks each token's real lineage — component → semantic → primitive → raw value — so you can see exactly where re-pointing it lands. A spoke re-skins by overriding these in its theme-<slug>.css; component internals are never edited. No hook for what you need? File it with /request-lego.

TokenTierResolves to
--app-bar-bg component #fcfcfc via --color-surface--color-gray-1
--app-bar-brand-bg component #46a758 via --color-primary--color-grass-9
--app-bar-brand-strong-bg component #202020 via --color-surface-inverse--color-gray-12
--app-bar-brand-strong-text component #fcfcfc via --color-text-inverse--color-gray-1
--app-bar-brand-text component #fcfcfc via --color-text-inverse--color-gray-1
--app-bar-gap component 2rem via --spacing-600
--app-bar-pad-x component 2rem via --spacing-600
--app-bar-pad-y component 1rem via --spacing-400
--app-bar-text component #202020 via --color-text-primary--color-gray-12