Todos os componentes

Team 1

Team 1 é um componente para React e Tailwind CSS, da biblioteca SmoothUI, com licença MIT. Copia e cola no teu projeto.

SmoothUI MIT other

O que é

Team 1 é um componente 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 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.

Team 1

index.tsx
"use client";

import { getAllPeople, getAvatarUrl, type Person } from "@/lib/smoothui-data";
import { motion, useInView, useReducedMotion } from "motion/react";
import { useRef } from "react";

const DEFAULT_MEMBER_COUNT = 4;
const AVATAR_SIZE = 400;
const STAGGER_DELAY = 0.1;

interface TeamGridProps {
  description?: string;
  members?: Person[];
  title?: string;
}

export function TeamGrid({
  title = "Our team",
  description = "We're a dynamic group of individuals who are passionate about what we do and dedicated to delivering the best results for our clients.",
  members = getAllPeople().slice(0, DEFAULT_MEMBER_COUNT),
}: TeamGridProps) {
  const shouldReduceMotion = useReducedMotion();
  const ref = useRef(null);
  const isInView = useInView(ref, { once: true });

  return (
    <section className="bg-primary py-24 sm:py-32">
      <div className="mx-auto max-w-7xl px-6 lg:px-8">
        <motion.div
          className="mx-auto max-w-2xl lg:mx-0"
          initial={shouldReduceMotion ? { opacity: 1 } : { opacity: 0, y: 20 }}
          transition={shouldReduceMotion ? { duration: 0 } : { duration: 0.6 }}
          viewport={{ once: true }}
          whileInView={
            shouldReduceMotion ? { opacity: 1 } : { opacity: 1, y: 0 }
          }
        >
          <h2 className="text-pretty font-semibold text-4xl text-foreground tracking-tight sm:text-5xl">
            {title}
          </h2>
          <p className="mt-6 text-foreground/70 text-lg/8">{description}</p>
        </motion.div>
        <motion.ul
          className="mx-auto mt-20 grid max-w-2xl grid-cols-1 gap-x-8 gap-y-14 sm:grid-cols-2 lg:mx-0 lg:max-w-none lg:grid-cols-3 xl:grid-cols-4"
          ref={ref}
        >
          {members.map((member, index) => (
            <motion.li
              animate={(() => {
                if (shouldReduceMotion) {
                  return { opacity: 1 };
                }
                return isInView ? { opacity: 1, y: 0 } : { opacity: 0, y: 30 };
              })()}
              initial={
                shouldReduceMotion ? { opacity: 1 } : { opacity: 0, y: 30 }
              }
              key={member.name}
              transition={
                shouldReduceMotion
                  ? { duration: 0 }
                  : { delay: index * STAGGER_DELAY, duration: 0.6 }
              }
            >
              <motion.div
                className="group"
                transition={
                  shouldReduceMotion
                    ? { duration: 0 }
                    : { damping: 20, stiffness: 300, type: "spring" as const }
                }
                whileHover={shouldReduceMotion ? {} : { scale: 1.02 }}
              >
                {/* Avatar */}
                <motion.div
                  className="relative overflow-hidden rounded-2xl"
                  transition={
                    shouldReduceMotion
                      ? { duration: 0 }
                      : { damping: 20, stiffness: 300, type: "spring" as const }
                  }
                  whileHover={shouldReduceMotion ? {} : { scale: 1.05 }}
                >
                  <img
                    alt={`Photo of ${member.name}`}
                    className="aspect-14/13 w-full rounded-2xl object-cover outline-1 outline-black/5 -outline-offset-1 transition-all duration-300 group-hover:outline-black/10 dark:outline-white/10 dark:group-hover:outline-white/20"
                    draggable={false}
                    height={AVATAR_SIZE}
                    src={getAvatarUrl(member.avatar, AVATAR_SIZE)}
                    width={AVATAR_SIZE}
                  />
                  <motion.div
                    className="absolute inset-0 bg-gradient-to-br from-black/5 to-transparent opacity-0 group-hover:opacity-100"
                    initial={{ opacity: 0 }}
                    transition={
                      shouldReduceMotion ? { duration: 0 } : { duration: 0.3 }
                    }
                    whileHover={shouldReduceMotion ? {} : { opacity: 1 }}
                  />
                </motion.div>
                {/* Name */}
                <h3 className="mt-6 font-semibold text-foreground text-lg/8 tracking-tight">
                  {member.name}
                </h3>
                {/* Role */}
                <p className="text-base/7 text-foreground/70">{member.role}</p>
                {/* Location */}
                {member.location ? (
                  <p className="text-foreground/70 text-sm/6">
                    {member.location}
                  </p>
                ) : null}
                {/* Bio */}
                {member.bio ? (
                  <p className="mt-2 text-foreground/70 text-sm">
                    {member.bio}
                  </p>
                ) : null}
              </motion.div>
            </motion.li>
          ))}
        </motion.ul>
      </div>
    </section>
  );
}

export default TeamGrid;

Componentes parecidos