Header — Transparent Over Hero
blockmarketingMarketing navbar that starts transparent over the hero and fades in a bordered, blurred surface once the page scrolls, with a nav row, theme-neutral CTA pair, and a mobile sheet.
Installation
$pnpm dlx uipkge-ng@latest add header-transparent-scroll$npx uipkge-ng@latest add header-transparent-scroll$yarn dlx uipkge-ng@latest add header-transparent-scroll$bunx uipkge-ng@latest add header-transparent-scrollManifest:
https://uipkge.dev/r/angular/header-transparent-scroll.jsonInstalls to:src/app/components/blocks/header-transparent-scroll/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.
HeaderTransparentScrollLinkinterface HeaderTransparentScrollLink {
label: string
href: string
}npm dependencies
Files installed (2)
src/app/components/blocks/header-transparent-scroll/header-transparent-scroll.component.ts5.2 kB
// Marketing navbar that starts transparent over the hero and fades in a bordered, // blurred surface once the page scrolls, with a nav row, theme-neutral CTA pair, // and a mobile sheet. Port of the React block 1:1. import { ChangeDetectionStrategy, Component, Input, OnDestroy, OnInit, signal } from '@angular/core' import { Layers, LucideAngularModule, Menu, X } from 'lucide-angular' import { cn } from '@/lib/utils' import { UiButtonComponent } from '@/ui/button/button.component' import { UiSeparatorComponent } from '@/ui/separator/separator.component' import { UiSheetCloseComponent, UiSheetComponent, UiSheetContentComponent } from '@/ui/sheet/sheet.component' export interface HeaderTransparentScrollLink { label: string href: string } const links: HeaderTransparentScrollLink[] = [ { label: 'Product', href: '#product' }, { label: 'Solutions', href: '#solutions' }, { label: 'Pricing', href: '#pricing' }, { label: 'Docs', href: '#docs' }, ] @Component({ changeDetection: ChangeDetectionStrategy.Eager, selector: 'ui-header-transparent-scroll, [ui-header-transparent-scroll]', standalone: true, // React renders the root <header> itself: the host stays out of layout and `class` goes to the root. host: { '[attr.class]': '"contents"' }, imports: [ LucideAngularModule, UiButtonComponent, UiSeparatorComponent, UiSheetCloseComponent, UiSheetComponent, UiSheetContentComponent, ], template: ` <header data-slot="header-transparent-scroll" [class]="rootClass"> <div class="mx-auto flex h-16 max-w-6xl items-center gap-6 px-6"> <a href="#top" class="flex items-center gap-2 font-semibold tracking-tight"> <lucide-icon [img]="Layers" class="text-primary size-5" /> Northwind </a> <nav class="hidden items-center gap-1 md:flex" aria-label="Primary"> @for (link of navLinks; track link.href) { <a [href]="link.href" class="text-muted-foreground hover:text-foreground hover:bg-muted focus-visible:ring-ring rounded-md px-3 py-1.5 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none" > {{ link.label }} </a> } </nav> <div class="ml-auto hidden items-center gap-2 md:flex"> <button ui-button variant="ghost" size="sm">Sign in</button> <button ui-button size="sm">Start free</button> </div> <div ui-sheet [open]="mobileOpen()" (openChange)="mobileOpen.set($event)"> <button ui-button variant="ghost" size="icon" class="ml-auto md:hidden" aria-label="Open navigation menu" (click)="mobileOpen.set(true)" > <lucide-icon [img]="Menu" class="size-5" /> </button> <div ui-sheet-content side="right" class="w-72"> <div class="flex h-full flex-col"> <div class="flex items-center justify-between border-b px-4 py-3"> <span class="text-sm font-semibold">Menu</span> <button ui-button ui-sheet-close variant="ghost" size="icon" class="size-8" aria-label="Close menu"> <lucide-icon [img]="X" class="size-4" /> </button> </div> <nav class="flex flex-1 flex-col gap-1 p-4" aria-label="Mobile"> @for (link of navLinks; track link.href) { <a [href]="link.href" class="hover:bg-muted rounded-md px-3 py-2 text-sm font-medium transition-colors" (click)="mobileOpen.set(false)" > {{ link.label }} </a> } </nav> <div ui-separator class="my-5"></div> <div class="flex flex-col gap-2 p-4 pt-0"> <button ui-button variant="outline" class="w-full">Sign in</button> <button ui-button class="w-full">Start free</button> </div> </div> </div> </div> </div> </header> `, }) export class UiHeaderTransparentScrollComponent implements OnInit, OnDestroy { protected readonly Layers = Layers protected readonly Menu = Menu protected readonly X = X protected readonly navLinks = links @Input('class') className?: string readonly scrolled = signal(false) readonly mobileOpen = signal(false) private readonly onScroll = (): void => { this.scrolled.set(window.scrollY > 24) } ngOnInit(): void { // Starts unscrolled so server and first client paint agree; the listener is // the only thing that swaps in the solid surface. if (typeof window === 'undefined') return this.onScroll() window.addEventListener('scroll', this.onScroll, { passive: true }) } ngOnDestroy(): void { if (typeof window === 'undefined') return window.removeEventListener('scroll', this.onScroll) } get rootClass(): string { return cn( 'fixed inset-x-0 top-0 z-40 transition-colors duration-200', this.scrolled() ? 'border-border bg-background/85 border-b backdrop-blur' : 'border-b border-transparent', this.className, ) } closeMobile(): void { this.mobileOpen.set(false) } }src/app/components/blocks/header-transparent-scroll/index.ts0.1 kB
export { UiHeaderTransparentScrollComponent, type HeaderTransparentScrollLink, } from './header-transparent-scroll.component'
Raw manifest:https://uipkge.dev/r/angular/header-transparent-scroll.json