Feature Grid Section

PreviousNext

Animated feature grid with staggered card animations and icon reveals (Base UI)

Docs
uitripledpage

Preview

Loading preview…
components/sections/baseui/feature-grid-section-baseui.tsx
"use client";

import { motion, useInView, type Variants } from "framer-motion";
import { Code, Globe, Lock, Shield, Sparkles, Zap } from "lucide-react";
import { useRef } from "react";

const features = [
  {
    icon: Code,
    title: "Developer Friendly",
    description: "Built with TypeScript and modern React patterns",
  },
  {
    icon: Zap,
    title: "Lightning Fast",
    description: "Optimized animations that never lag",
  },
  {
    icon: Shield,
    title: "Production Ready",
    description: "Tested and ready for your next project",
  },
  {
    icon: Globe,
    title: "Responsive",
    description: "Works perfectly on all devices",
  },
  {
    icon: Lock,
    title: "Secure",
    description: "Built with security best practices",
  },
  {
    icon: Sparkles,
    title: "Modern",
    description: "Using the latest web technologies",
  },
];

export function FeatureGridSectionBaseui() {
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true, margin: "-50px" });

  const containerVariants: Variants = {
    hidden: { opacity: 0 },
    visible: {
      opacity: 1,
      transition: {
        staggerChildren: 0.1,
        delayChildren: 0.2,
      },
    },
  };

  const itemVariants: Variants = {
    hidden: { opacity: 0, y: 30, scale: 0.9 },
    visible: {
      opacity: 1,
      y: 0,
      scale: 1,
      transition: {
        type: "spring",
        stiffness: 100,
        damping: 15,
      },
    },
  };

  return (
    <div ref={ref} className="w-full px-4 py-16">
      <div className="mx-auto max-w-6xl">
        <motion.div
          initial={{ opacity: 0, y: 30 }}
          animate={isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 }}
          transition={{ duration: 0.6 }}
          className="mb-12 text-center"
        >
          <h2 className="mb-4 text-3xl font-bold sm:text-4xl md:text-5xl">
            Why Choose Us
          </h2>
          <p className="text-sm text-foreground/70 sm:text-base md:text-lg">
            Everything you need to build amazing applications
          </p>
        </motion.div>

        <motion.div
          variants={containerVariants}
          initial="hidden"
          animate={isInView ? "visible" : "hidden"}
          className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3"
        >
          {features.map((feature, index) => {
            const Icon = feature.icon;
            return (
              <motion.div key={feature.title} variants={itemVariants}>
                <div className="h-full rounded-lg border border-border bg-card text-card-foreground shadow-sm transition-all hover:shadow-lg">
                  <div className="flex flex-col space-y-1.5 p-6">
                    <motion.div
                      initial={{ opacity: 0, scale: 0.8, rotate: -60 }}
                      animate={
                        isInView
                          ? { opacity: 1, scale: 1, rotate: 0 }
                          : { opacity: 0, scale: 0.8, rotate: -60 }
                      }
                      transition={{
                        delay: index * 0.1 + 0.3,
                        type: "spring",
                        stiffness: 120,
                        damping: 18,
                        mass: 0.6,
                      }}
                      className="mb-4 inline-flex"
                    >
                      <Icon
                        className="h-6 w-6 text-muted-foreground"
                        aria-hidden="true"
                      />
                    </motion.div>
                    <h3 className="text-xl font-semibold leading-none tracking-tight">
                      {feature.title}
                    </h3>
                  </div>
                  <div className="p-6 pt-0">
                    <p className="text-base text-muted-foreground">
                      {feature.description}
                    </p>
                  </div>
                </div>
              </motion.div>
            );
          })}
        </motion.div>
      </div>
    </div>
  );
}

Installation

npx shadcn@latest add @uitripled/feature-grid-section-baseui

Usage

Usage varies by registry entry. Refer to the registry docs or source files below for details.