Todos os componentes

Footer 3

Footer 3 é 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 é

Footer 3 é 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.

Footer 3

index.tsx
"use client";

import SmoothButton from "@/components/smoothui/smooth-button";
import { Github, Linkedin, Twitter, Youtube } from "lucide-react";
import { motion, useReducedMotion } from "motion/react";
import type { ReactNode } from "react";

const ANIMATION_DURATION = 0.25;
const DELAY_INCREMENT = 0.05;
const HOVER_SCALE = 1.1;
const TAP_SCALE = 0.95;
const DELAY_NEWSLETTER = 6;
const DELAY_BOTTOM = 7;

export interface FooterMegaProps {
  columns?: Array<{
    title: string;
    links: Array<{ label: string; href: string }>;
  }>;
  copyright?: string;
  description?: string;
  logo?: ReactNode;
  newsletter?: {
    title: string;
    description: string;
    placeholder: string;
    buttonText: string;
  };
  socialLinks?: Array<{
    icon: ReactNode;
    href: string;
    label: string;
  }>;
}

const defaultColumns = [
  {
    links: [
      { href: "#features", label: "Features" },
      { href: "#pricing", label: "Pricing" },
      { href: "#changelog", label: "Changelog" },
      { href: "#docs", label: "Documentation" },
    ],
    title: "Product",
  },
  {
    links: [
      { href: "#about", label: "About" },
      { href: "#blog", label: "Blog" },
      { href: "#careers", label: "Careers" },
      { href: "#contact", label: "Contact" },
    ],
    title: "Company",
  },
  {
    links: [
      { href: "#community", label: "Community" },
      { href: "#github", label: "GitHub" },
      { href: "#discord", label: "Discord" },
      { href: "#help", label: "Help Center" },
    ],
    title: "Resources",
  },
  {
    links: [
      { href: "#privacy", label: "Privacy Policy" },
      { href: "#terms", label: "Terms of Service" },
      { href: "#cookies", label: "Cookie Policy" },
    ],
    title: "Legal",
  },
];

const defaultSocialLinks = [
  {
    href: "https://twitter.com",
    icon: <Twitter className="h-5 w-5" />,
    label: "Twitter",
  },
  {
    href: "https://github.com",
    icon: <Github className="h-5 w-5" />,
    label: "GitHub",
  },
  {
    href: "https://linkedin.com",
    icon: <Linkedin className="h-5 w-5" />,
    label: "LinkedIn",
  },
  {
    href: "https://youtube.com",
    icon: <Youtube className="h-5 w-5" />,
    label: "YouTube",
  },
];

export const FooterMega = ({
  logo = <span className="font-bold text-2xl text-foreground">SmoothUI</span>,
  description = "Beautiful animated React components for building modern user interfaces with smooth animations and delightful interactions.",
  columns = defaultColumns,
  newsletter = {
    buttonText: "Subscribe",
    description: "Get the latest updates and news delivered to your inbox.",
    placeholder: "Enter your email",
    title: "Subscribe to our newsletter",
  },
  socialLinks = defaultSocialLinks,
  copyright = "© 2024 SmoothUI. All rights reserved.",
}: FooterMegaProps) => {
  const shouldReduceMotion = useReducedMotion();

  const getAnimationProps = (delay = 0) => {
    if (shouldReduceMotion) {
      return {
        animate: { opacity: 1 },
        initial: { opacity: 1 },
        transition: { duration: 0 },
      };
    }

    return {
      initial: { opacity: 0, y: 20 },
      transition: {
        bounce: 0.1,
        delay,
        duration: ANIMATION_DURATION,
        type: "spring" as const,
      },
      viewport: { once: true },
      whileInView: { opacity: 1, y: 0 },
    };
  };

  const getHoverProps = () => {
    if (shouldReduceMotion) {
      return {};
    }

    return {
      whileHover: { scale: HOVER_SCALE },
      whileTap: { scale: TAP_SCALE },
    };
  };

  return (
    <footer className="border-border border-t bg-background">
      <div className="mx-auto max-w-7xl px-6 py-16">
        {/* Top Section: Logo, Description, Columns, Newsletter */}
        <motion.div
          {...getAnimationProps()}
          className="grid grid-cols-1 gap-12 lg:grid-cols-12"
        >
          {/* Logo and Description */}
          <motion.div
            {...getAnimationProps(DELAY_INCREMENT)}
            className="lg:col-span-3"
          >
            <div className="mb-4">{logo}</div>
            <p className="text-foreground/70 text-sm leading-relaxed">
              {description}
            </p>
          </motion.div>

          {/* Link Columns */}
          <div className="grid grid-cols-2 gap-8 sm:grid-cols-4 lg:col-span-5">
            {columns.map((column, columnIndex) => (
              <motion.div
                key={column.title}
                {...getAnimationProps(DELAY_INCREMENT * (columnIndex + 2))}
              >
                <h4 className="mb-4 font-semibold text-foreground text-sm uppercase tracking-wide">
                  {column.title}
                </h4>
                <ul className="space-y-3">
                  {column.links.map((link) => (
                    <li key={link.label}>
                      <a
                        className="text-foreground/70 text-sm transition-colors hover:text-brand"
                        href={link.href}
                      >
                        {link.label}
                      </a>
                    </li>
                  ))}
                </ul>
              </motion.div>
            ))}
          </div>

          {/* Newsletter */}
          <motion.div
            {...getAnimationProps(DELAY_INCREMENT * DELAY_NEWSLETTER)}
            className="lg:col-span-4"
          >
            <h4 className="mb-2 font-semibold text-foreground text-lg">
              {newsletter.title}
            </h4>
            <p className="mb-4 text-foreground/70 text-sm">
              {newsletter.description}
            </p>
            <form
              className="flex flex-col gap-3 sm:flex-row"
              onSubmit={(e) => e.preventDefault()}
            >
              <input
                aria-label="Email address"
                className="flex-1 rounded-lg border border-border bg-background px-4 py-2.5 text-sm placeholder:text-foreground/50 focus:border-brand focus:outline-none focus:ring-2 focus:ring-brand/20"
                placeholder={newsletter.placeholder}
                type="email"
              />
              <SmoothButton type="submit" variant="candy">
                {newsletter.buttonText}
              </SmoothButton>
            </form>
          </motion.div>
        </motion.div>

        {/* Bottom Section: Copyright and Social Links */}
        <motion.div
          {...getAnimationProps(DELAY_INCREMENT * DELAY_BOTTOM)}
          className="mt-12 flex flex-col items-center justify-between gap-6 border-border border-t pt-8 sm:flex-row"
        >
          <p className="text-foreground/60 text-sm">{copyright}</p>

          <div className="flex gap-4">
            {socialLinks.map((social) => (
              <motion.a
                aria-label={social.label}
                className="text-foreground/60 transition-colors hover:text-brand"
                href={social.href}
                key={social.label}
                rel="noopener noreferrer"
                target="_blank"
                {...getHoverProps()}
              >
                {social.icon}
                <span className="sr-only">{social.label}</span>
              </motion.a>
            ))}
          </div>
        </motion.div>
      </div>
    </footer>
  );
};

export default FooterMega;

Componentes parecidos