Skip to content
W WRNexusJS
core component

PageHeader

Reusable page header component.

@wrnexus/ui 0.2.6716 props0 slots0 events

Usage

Components are auto-discovered. Use the component directly in any .wrn view:

<PageHeader
  eyebrow="eyebrow"
  title="title"
  description="description"
  primaryLabel="primaryLabel"
  primaryHref="primaryHref"
/>

Legacy mount name: data-component="PageHeader".

Props and attributes

PropTypeRequirementDefault
classstringOptional""
eyebrowstringOptional""
titlestringOptional""
descriptionstringOptional""
primaryLabelstringOptional""
primaryHrefstringOptional""
secondaryLabelstringOptional""
secondaryHrefstringOptional""
iconstringOptional"sparkles"
centeredbooleanOptionalfalse
compactbooleanOptionalfalse
showBreadcrumbsbooleanOptionalfalse
breadcrumbParentstringOptional""
breadcrumbParentHrefstringOptional""
breadcrumbCurrentstringOptional""
highlightsstringOptional[]

Slots

This component does not declare a slot.

Events

This component does not declare a custom event.

Source contract

Installed source: components/PageHeader.wrn

component PageHeader {
    props {
        class: string = ""
        eyebrow = ""
        title = ""
        description = ""

        primaryLabel = ""
        primaryHref = ""

        secondaryLabel = ""
        secondaryHref = ""

        icon = "sparkles"

        centered = false
        compact = false

        showBreadcrumbs = false
        breadcrumbParent = ""
        breadcrumbParentHref = ""
        breadcrumbCurrent = ""

        highlights = []
    }

    view {
        <section
            aria-labelledby="public-page-title"
            class="relative overflow-hidden border-b border-slate-200 bg-white dark:border-white/10 dark:bg-slate-950 {class}"
        >
        <!-- Background decoration -->
        <div
                aria-hidden="true"
                class="pointer-events-none absolute inset-0 overflow-hidden"
            >
        <div class="absolute -right-40 -top-48 h-96 w-96 rounded-full bg-indigo-300/20 blur-3xl dark:bg-indigo-500/10" >
        </div>
        <div class="absolute -left-40 top-20 h-80 w-80 rounded-full bg-violet-300/15 blur-3xl dark:bg-violet-500/5" >
        </div>
        <div class="absolute left-1/2 top-0 h-px w-2/3 -translate-x-1/2 bg-linear-to-r from-transparent via-indigo-300/60 to-transparent dark:via-indigo-500/20" >
        </div>
        </div>
        <div class="relative w-full px-5 sm:px-8 lg:px-10 xl:px-12">
        <!-- Breadcrumbs -->
        <div
                    class="border-b border-slate-200/80 py-3 dark:border-white/10"
                    class:hidden="!showBreadcrumbs"
                >
        <Breadcrumbs
                        centered="{centered}"
                        compact="{false}"
                        items="{[ ...(breadcrumbParent !== '' ? [{ label: breadcrumbParent, href: breadcrumbParentHref, current: false }] : []), ...(breadcrumbCurrent !== '' ? [{ label: breadcrumbCurrent, href: '', current: true }] : []) ]}"
                    />
        </div>
        <!-- Header body -->
        <div
                    class=" {compact ? 'py-9 sm:py-10 lg:py-12' : 'py-12 sm:py-14 lg:py-16' }  {centered ? 'mx-auto flex max-w-5xl flex-col items-center text-center' : 'grid gap-8 lg:grid-cols-[minmax(0,1fr)_auto] lg:items-start lg:gap-12' } "
                >
        <!-- Content -->
        <div class=" min-w-0 {centered ? 'w-full max-w-4xl' : 'max-w-4xl'} " >
        <!-- Eyebrow -->
        <div
                            class="flex"
                            class:hidden="eyebrow === ''"
                            class:justify-center="centered"
                            class:justify-start="!centered"
                        >
        <span
                                class="inline-flex items-center gap-2 rounded-full border border-indigo-200 bg-indigo-50 px-3 py-1.5 text-xs font-semibold text-indigo-700 shadow-sm dark:border-indigo-500/20 dark:bg-indigo-500/10 dark:text-indigo-300"
                            >
        <span class="grid h-5 w-5 place-items-center rounded-full bg-indigo-100 dark:bg-indigo-500/15" >
        <span class="icon-[lucide--{icon}] h-3 w-3" aria-hidden="true" >
        </span>
        </span>

                                {eyebrow}
                            </span>
        </div>
        <!-- Title -->
        <h1
                            id="public-page-title"
                            class=" font-bold tracking-tight text-slate-950 dark:text-white {eyebrow !== '' ? 'mt-6' : ''} {compact ? 'text-3xl leading-tight sm:text-4xl lg:text-5xl' : 'text-4xl leading-[1.08] sm:text-5xl lg:text-[3.25rem]' } "
                        >
                            {title}
                        </h1>
        <!-- Description -->
        <p
                            class=" mt-5 text-base text-slate-600 dark:text-slate-400 {compact ? 'leading-7' : 'leading-8 sm:text-lg'} {centered ? 'mx-auto max-w-3xl' : 'max-w-2xl'} "
                            class:hidden="description === ''"
                        >
                            {description}
                        </p>
        </div>
        <!-- Single dynamic action group -->
        <div
                        class=" flex flex-col gap-3 sm:flex-row {centered ? 'mt-8 justify-center' : 'lg:pt-1' } "
                        class:hidden="primaryLabel === '' && secondaryLabel === ''"
                    >
        <!-- Secondary action -->
        <a
                            href="{secondaryHref}"
                            class="h-12 items-center justify-center rounded-xl border border-slate-200 bg-white px-5 text-sm font-semibold text-slate-700 shadow-sm transition hover:-translate-y-0.5 hover:border-indigo-300 hover:bg-slate-50 hover:text-indigo-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 dark:border-white/10 dark:bg-white/5 dark:text-slate-200 dark:hover:border-indigo-500/30 dark:hover:bg-white/10 dark:hover:text-indigo-300"
                            class:hidden="secondaryLabel === ''"
                            class:inline-flex="secondaryLabel !== ''"
                        >
                            {secondaryLabel}
                        </a>
        <!-- Primary action -->
        <a
                            href="{primaryHref}"
                            class="group h-12 items-center justify-center gap-2 rounded-xl bg-indigo-600 px-5 text-sm font-bold text-white shadow-lg shadow-indigo-600/20 transition hover:-translate-y-0.5 hover:bg-indigo-500 hover:shadow-xl focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 focus-visible:ring-offset-2 dark:focus-visible:ring-offset-slate-950"
                            class:hidden="primaryLabel === ''"
                            class:inline-flex="primaryLabel !== ''"
                        >
                            {primaryLabel}

                            <span class="icon-[lucide--arrow-right] h-4 w-4 transition-transform group-hover:translate-x-1" aria-hidden="true" >
        </span>
        </a>
        </div>
        </div>
        <!-- Dynamic highlight strip -->
        <div
                    class="border-t border-slate-200 py-5 dark:border-white/10"
                    class:hidden="compact || highlights.length === 0"
                    class:block="!compact && highlights.length > 0"
                >
        <div class="flex gap-y-5">
                        {#each highlights as highlight}
                        <div
                            class="w-full min-w-0 pr-6"
                            class:w-full="highlights.length === 1"
                            class:sm:w-1/2="highlights.length >= 2"
                            class:lg:w-1/2="highlights.length === 2"
                            class:lg:w-1/3="highlights.length === 3"
                            class:lg:w-1/4="highlights.length >= 4"
                        >
        <div
                                class="flex min-w-0 items-center gap-3"
                                class:justify-center="centered"
                            >
        <span class="grid h-10 w-10 shrink-0 place-items-center rounded-xl {highlight.iconBoxClass}" >
        <span class="{highlight.iconClass} h-5 w-5" aria-hidden="true" >
        </span>
        </span>
        <div class="min-w-0">
        <p class="text-sm font-semibold text-slate-950 dark:text-white">
                                        {highlight.title}
                                    </p>
        <p
                                        class="mt-0.5 text-xs leading-5 text-slate-500 dark:text-slate-400"
                                        class:hidden="highlight.description === ''"
                                    >
                                        {highlight.description}
                                    </p>
        </div>
        </div>
        </div>
                        {/each}
                    </div>
        </div>
        </div>
        </section>
    }
}