Page Hero

Standard page header with eyebrow, title, and description. Handles nav clearance automatically.

API Reference

PropTypeDefault
titlestring
descriptionstring
eyebrow{ label, variant?, color?, size? }
align"start" | "center""start"
childrenReactNode

Centered

Services

What We Do

A brief description of our services.

<PageHero
  eyebrow={{ label: "Services" }}
  title="What We Do"
  description="A brief description of our services."
  align="center"
/>

With CTA

Contact

Get in Touch

We'd love to hear from you.

<PageHero
  eyebrow={{ label: "Contact" }}
  title="Get in Touch"
  description="We'd love to hear from you."
>
  <Button>Contact Us</Button>
  <Button variant="ghost">Learn More</Button>
</PageHero>

Basic Usage

import { PageHero } from "@/bonk/components";

<PageHero title="About" description="Subtitle text" />

Source

src/bonk/components/PageHero.tsx
import { Badge, Container, Heading, Text } from "@/bonk/ui";
import type { ComponentProps } from "react";
import { cn } from "@/bonk/utils";

interface EyebrowProps {
  label: string;
  variant?: ComponentProps<typeof Badge>["variant"];
  color?: ComponentProps<typeof Badge>["color"];
  size?: ComponentProps<typeof Badge>["size"];
}

interface PageHeroProps {
  eyebrow?: EyebrowProps;
  title: string;
  description?: string;
  align?: "center" | "start";
  children?: React.ReactNode;
}

export function PageHero({
  eyebrow,
  title,
  description,
  align = "start",
  children,
}: PageHeroProps) {
  const isCenter = align === "center";

  return (
    <Container>
      <div
        className={cn(
          "flex flex-col gap-3 pb-16 py-20",
          isCenter && "items-center text-center",
        )}
      >
        {eyebrow && (
          <Badge
            variant={eyebrow.variant ?? "solid"}
            color={eyebrow.color ?? "primary"}
            size={eyebrow.size}
            className={cn(isCenter ? "self-center" : "self-start")}
          >
            {eyebrow.label}
          </Badge>
        )}
        <Heading as="h1" size="lg" className="max-w-3xl">
          {title}
        </Heading>
        {description && (
          <Text size="md" color="root-contrast" subtle className="max-w-3xl">
            {description}
          </Text>
        )}
        {children && (
          <div
            className={cn(
              "mt-4 flex flex-wrap gap-2",
              isCenter && "justify-center",
            )}
          >
            {children}
          </div>
        )}
      </div>
    </Container>
  );
}