Todos os componentes

Header 4

Header 4 é um componente de layout para React e Tailwind CSS, da biblioteca SmoothUI, com licença MIT. Copia e cola no teu projeto.

SmoothUI MIT layout

O que é

Header 4 é um componente de layout para React e Tailwind CSS, da biblioteca SmoothUI, com licença MIT. Copia e cola no teu projeto.

Como usar

Abre o componente no catálogo, carrega em copiar, e cola no teu projeto. O prompt copiado leva o código e as regras para o teu agente o reproduzir sem alterar nada.

Abrir no catálogo

Cinco cópias grátis por mês. Sem cartão.

Precisa de

npm i lucide-react motion

Licença

Este componente vem de SmoothUI e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.

Header 4

index.tsx
/**
 * Header 4 - Interactive 3D Grid Hero
 *
 * Inspired by the beautiful interactive grid design from rauno.me 2024 website.
 * Features a 3D-perspective grid with customizable hover colors that respond
 * to user interaction, creating an engaging and modern hero section.
 *
 * @see https://rauno.me
 */

"use client";

import { ExternalLink } from "lucide-react";
import { useEffect, useRef } from "react";
import { AnimatedGroup, AnimatedText, Button, HeroHeader } from "@/components/smoothui/shared";
import styles from "./hero-grid.module.css";

interface InteractiveGridProps {
  hoverColors?: string | [string, string, string, string];
}

const TOTAL_TILES = 1600;
const INITIAL_TILE = 1;
const TILES_TO_CLONE = TOTAL_TILES - INITIAL_TILE;

function InteractiveGrid({ hoverColors }: InteractiveGridProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const tileRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!(containerRef.current && tileRef.current)) {
      return;
    }

    // Clone the first tile to create a 40x40 grid (1600 tiles total)
    for (let i = 0; i < TILES_TO_CLONE; i++) {
      const clonedTile = tileRef.current.cloneNode(true);
      containerRef.current.appendChild(clonedTile);
    }
  }, []);

  // Prepare CSS variables for hover colors
  const style = hoverColors
    ? {
        "--hero-grid-hover-color-1": Array.isArray(hoverColors)
          ? hoverColors[0]
          : hoverColors,
        "--hero-grid-hover-color-2": Array.isArray(hoverColors)
          ? (hoverColors[1] ?? hoverColors[0])
          : hoverColors,
        "--hero-grid-hover-color-3": Array.isArray(hoverColors)
          ? (hoverColors[2] ?? hoverColors[0])
          : hoverColors,
        "--hero-grid-hover-color-4": Array.isArray(hoverColors)
          ? (hoverColors[3] ?? hoverColors[0])
          : hoverColors,
      }
    : undefined;

  return (
    <div
      aria-hidden="true"
      className={styles.gridContainer}
      style={style as React.CSSProperties}
    >
      <div className={styles.mainGrid} ref={containerRef}>
        <div className={styles.tile} ref={tileRef} />
      </div>
    </div>
  );
}

interface HeroGridProps {
  hoverColors?: string | [string, string, string, string];
}

export function HeroGrid({ hoverColors }: HeroGridProps) {
  return (
    <div className="relative">
      <HeroHeader />
      <main>
        <section className="relative overflow-hidden py-36">
          {/* Interactive animated grid background */}
          <InteractiveGrid hoverColors={hoverColors} />
          <AnimatedGroup
            className="pointer-events-none flex flex-col items-center gap-6 text-center"
            preset="blur-slide"
          >
            <div>
              <AnimatedText
                as="h1"
                className="mb-6 text-pretty font-bold text-2xl tracking-tight lg:text-5xl"
              >
                Build your next project with{" "}
                <span className="text-brand">Smoothui</span>
              </AnimatedText>
              <AnimatedText
                as="p"
                className="mx-auto max-w-3xl text-muted-foreground lg:text-xl"
                delay={0.15}
              >
                Smoothui gives you the building blocks to create stunning,
                animated interfaces in minutes.
              </AnimatedText>
            </div>
            <AnimatedGroup
              className="pointer-events-auto mt-6 flex justify-center gap-3"
              preset="slide"
            >
              <Button
                className="shadow-sm transition-shadow hover:shadow"
                variant="outline"
              >
                Get Started
              </Button>
              <Button className="group" variant="candy">
                Learn more{" "}
                <ExternalLink className="ml-2 h-4 transition-transform group-hover:translate-x-0.5" />
              </Button>
            </AnimatedGroup>
          </AnimatedGroup>
        </section>
      </main>
    </div>
  );
}

export default HeroGrid;
hero-grid.module.css
/* @reference "../../../../app/styles/smoothui.css"; */

/**
 * Interactive 3D Grid Styles
 *
 * Inspired by rauno.me 2024 website's interactive grid design.
 * Creates a 3D-perspective grid with customizable hover colors.
 */

.gridContainer {
  --hero-grid-hover-color-1: var(--color-brand);
  --hero-grid-hover-color-2: var(--color-brand);
  --hero-grid-hover-color-3: var(--color-brand);
  --hero-grid-hover-color-4: var(--color-brand);
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  perspective: 2000px;
  perspective-origin: center center;
}

.mainGrid {
  position: absolute;
  top: 50%;
  left: 50%;
  display: grid;
  grid-template-rows: repeat(40, 1fr);
  grid-template-columns: repeat(40, 1fr);
  width: 140rem;
  aspect-ratio: 1;
  transform: translate(-50%, -50%) rotateX(50deg) rotateY(-5deg) rotateZ(20deg)
    scale(1.25);
}

.mainGrid::after {
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  content: "";
  background: radial-gradient(circle, transparent 25%, rgb(255 255 255) 80%);
}

:global(.dark).mainGrid::after {
  background: radial-gradient(
    circle,
    transparent 25%,
    rgb(0 0 0 / 90%) 80%
  ) !important;
}

.tile {
  border: 0.5px solid rgb(0 0 0 / 12%);
  transition: background-color 1500ms;
}

:global(.dark).tile {
  border: 0.5px solid rgb(255 255 255 / 5%);
}

.tile:hover {
  transition-duration: 0ms;
}

.tile:nth-child(4n):hover {
  background-color: var(--hero-grid-hover-color-1);
}

.tile:nth-child(4n + 1):hover {
  background-color: var(--hero-grid-hover-color-2);
}

.tile:nth-child(4n + 2):hover {
  background-color: var(--hero-grid-hover-color-3);
}

.tile:nth-child(4n + 3):hover {
  background-color: var(--hero-grid-hover-color-4);
}

.tile:nth-child(7n):hover {
  background-color: var(--hero-grid-hover-color-2);
}

.tile:nth-child(7n + 3):hover {
  background-color: var(--hero-grid-hover-color-3);
}

.tile:nth-child(7n + 5):hover {
  background-color: var(--hero-grid-hover-color-4);
}

.tile:nth-child(7n + 6):hover {
  background-color: var(--hero-grid-hover-color-1);
}

.tile:nth-child(11n + 1):hover {
  background-color: var(--hero-grid-hover-color-1);
}

.tile:nth-child(11n + 4):hover {
  background-color: var(--hero-grid-hover-color-2);
}

.tile:nth-child(11n + 7):hover {
  background-color: var(--hero-grid-hover-color-3);
}

.tile:nth-child(11n + 10):hover {
  background-color: var(--hero-grid-hover-color-4);
}

@media (prefers-reduced-motion: reduce) {
  .mainGrid {
    transform: translate(-50%, -50%) rotateZ(20deg);
  }

  .tile {
    transition: none;
  }
}

/* Reduce overlay size of hero text/button containers */
.heroContent {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  max-width: 600px;
  padding: 0;
  margin: 0 auto;
  background: none;
  box-shadow: none;
}

.heroButtons {
  display: flex;
  gap: 1rem;
  width: auto;
  padding: 0;
  margin-top: 1.5rem;
  background: none;
  box-shadow: none;
}

Componentes parecidos