A thin bar across the top of a whole site. Items can open a full-width menu panel while the page behind blurs.
import { SiteBar } from '@brand-studio/ui';
const shop = [{ label: 'Buy a camera', href: '#buy' }, { label: 'Compare kits', href: '#compare' }, { label: 'Straps and cases', href: '#straps' }];
export default function SiteBarDemo() {
// The transform keeps the menu's page curtain inside this frame instead of the docs page.
return (
<div style={{ position: 'relative', width: '100%', height: 340, overflow: 'hidden', transform: 'translateZ(0)' }}>
<SiteBar
brand={<a href="#">Halden</a>}
items={[
{ label: 'Cameras', href: '#cameras', current: true, menu: [{ label: 'Explore cameras', links: [{ label: 'Halden R', href: '#r' }, { label: 'Halden S', href: '#s' }] }, { label: 'Shop', links: shop }] },
{ label: 'Lenses', href: '#lenses', menu: [{ label: 'Explore lenses', links: [{ label: '35 mm ƒ/2', href: '#35' }, { label: '50 mm ƒ/1.4', href: '#50' }] }, { label: 'Shop', links: shop }] },
{ label: 'Film', href: '#film' },
{ label: 'Service', href: '#service' },
]}
actions={<a href="#bag">Bag</a>}
/>
<p style={{ padding: '3rem 1.5rem', margin: 0, color: 'var(--bs-muted)' }}>Hover Cameras or Lenses, or tab to the arrow beside them and press Enter.</p>
</div>
);
}Installation
pnpm add @brand-studio/uinpm install @brand-studio/uiyarn add @brand-studio/uibun add @brand-studio/uiInstall the peer dependencies
npm install react react-domImport the stylesheet once
import '@brand-studio/ui/styles.css';Wrap your app in a brand theme
import { BrandTheme, SiteBar } from '@brand-studio/ui'; import brand from './brand.json'; <BrandTheme palette={brand.tokens} mode="system"> {/* your app */} </BrandTheme>
Usage
import { SiteBar } from '@brand-studio/ui';<SiteBar
brand={<a href="/">Halden</a>}
items={[
{ label: 'Cameras', href: '/cameras', current: true, menu: [
{ label: 'Explore cameras', links: [{ label: 'Halden R', href: '/r' }] },
{ label: 'Shop', links: [{ label: 'Buy a camera', href: '/buy' }] },
] },
{ label: 'Film', href: '/film' },
]}
/>The first group in each menu is set large, for the products; later groups hold smaller links. The bar scrolls away with the page unless you pass sticky. Stack a Product Bar under it for one product's pages; set --bs-productbar-top: 44px on the Product Bar when the Site Bar is sticky too.
Accessibility
- The item link always goes to its page. A separate arrow button, with
aria-expandedandaria-controls, opens the menu for keyboard and touch. - Escape closes the menu and returns focus to its button. Moving focus out of the bar closes it too.
- Each menu group is a list labelled by its heading.
- When the bar is narrower than 40rem, the items move into Mobile Navigation.
API Reference
| Prop | Type | Default |
|---|---|---|
brand | React.ReactNode | – |
items | SiteBarItem[] | – |
actions? | React.ReactNode | – |
label? | string | 'Site' |
sticky? | boolean | false |
className? | string | '' |