Sticky Top Navbar
blockmarketingSticky marketing top-bar. Brand mark on the left, five inline anchor links in the centre on desktop, "Sign in" + primary trial CTA on the right. Below the md breakpoint the right side collapses into a hamburger that opens a right-side Sheet with the same links and CTAs stacked. Translucent background uses backdrop-blur so content can scroll behind it.
Installation
$pnpm dlx shadcn@latest add https://uipkge.dev/r/lit/header-01.json$npx shadcn@latest add https://uipkge.dev/r/lit/header-01.json$yarn dlx shadcn@latest add https://uipkge.dev/r/lit/header-01.json$bunx shadcn@latest add https://uipkge.dev/r/lit/header-01.jsonManifest:
https://uipkge.dev/r/lit/header-01.jsonInstalls to:src/uip/blocks/header-01/Variants
Loading interactive previews…
Loading interactive previews…
Schema
Type aliases exported from this item's source. Use these to shape the data you pass in.
HTMLElementTagNameMapinterface HTMLElementTagNameMap {
'uip-header-01': UipHeader01
}
}Files installed (1)
src/uip/blocks/header-01/header-01.ts4.3 kB
import { LitElement, css, html } from 'lit' import { Boxes, Menu } from 'lucide' import { tailwind } from '../../lib/styles' import { ThemeController } from '../../lib/theme' import { icon } from '../../lib/icon' // Side-effect imports: register the composed elements for standalone use // (consumers who install only this block still get working primitives). import '../../components/button/button' import '../../components/sheet/sheet' const links = [ { label: 'Features', href: '#features' }, { label: 'Pricing', href: '#pricing' }, { label: 'Customers', href: '#customers' }, { label: 'Docs', href: '#docs' }, { label: 'Blog', href: '#blog' }, ] /** * <uip-header-01> — the registry Header01 block as a web component. * * Class strings are React's Header01 verbatim. React state (useState) becomes * @state fields; the mobile Sheet becomes <uip-sheet> (open + open-change). * The sheet's built-in header (heading="Acme") replaces React's custom * brand + close-button row; the mobile nav links and footer CTAs keep * React's classes verbatim. */ export class UipHeader01 extends LitElement { static shadowRootOptions = { ...LitElement.shadowRootOptions, delegatesFocus: true } // :host display can't be a utility class (the host has no template of its own). static styles = [tailwind, css`:host { display: block; }`] static properties = { mobileOpen: { state: true }, } private mobileOpen = false constructor() { super() new ThemeController(this) } connectedCallback() { super.connectedCallback() this.setAttribute('data-uipkge', '') this.setAttribute('data-slot', 'header-01') } render() { return html` <header data-slot="header-01" class="bg-background/80 supports-[backdrop-filter]:bg-background/60 sticky top-0 z-40 border-b backdrop-blur" > <div class="mx-auto flex h-16 max-w-6xl items-center justify-between px-6"> <a href="#" class="flex items-center gap-2"> <div class="bg-primary text-primary-foreground flex size-8 items-center justify-center rounded-md"> ${icon(Boxes, 'boxes', 'size-4')} </div> <span class="text-base font-semibold">Acme</span> </a> <nav class="hidden items-center gap-6 md:flex" aria-label="Primary"> ${links.map( (link) => html`<a href=${link.href} class="text-muted-foreground hover:text-foreground text-sm transition-colors" > ${link.label} </a>`, )} </nav> <div class="hidden items-center gap-2 md:flex"> <uip-button variant="ghost" size="sm">Sign in</uip-button> <uip-button size="sm">Start free trial</uip-button> </div> <!-- Plain wrapper carries the responsive class: display utilities can't go on the uip-sheet host (its :host display wins). --> <div class="md:hidden"> <uip-sheet side="right" heading="Acme" .open=${this.mobileOpen} @open-change=${(e: CustomEvent<{ open: boolean }>) => { this.mobileOpen = e.detail.open }} > <uip-button slot="trigger" variant="ghost" size="icon" aria-label="Open menu"> ${icon(Menu, 'menu', 'size-5')} </uip-button> <nav class="flex flex-1 flex-col gap-1 p-4" aria-label="Mobile"> ${links.map( (link) => html`<a href=${link.href} class="hover:bg-muted rounded-md px-3 py-2 text-sm transition-colors" @click=${() => { this.mobileOpen = false }} > ${link.label} </a>`, )} </nav> <div class="flex flex-col gap-2 border-t p-4"> <uip-button variant="outline" class="w-full">Sign in</uip-button> <uip-button class="w-full">Start free trial</uip-button> </div> </uip-sheet> </div> </div> </header> ` } } customElements.get('uip-header-01') || customElements.define('uip-header-01', UipHeader01) declare global { interface HTMLElementTagNameMap { 'uip-header-01': UipHeader01 } }
Raw manifest:https://uipkge.dev/r/lit/header-01.json