React + MotionButtons

Lade-Pille mit Häkchen

Ein Pillen-Button, der beim Arbeiten einen Spinner zeigt und dann federnd ein Häkchen einblendet.

Einstellungen

1200ms

Code

import { useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { Check, Loader2 } from "lucide-react";

const spring = { type: "spring", stiffness: 300, damping: 30 } as const;

interface LoadingCheckButtonProps {
  text?: string;
  color?: string;
  /** Duración de la carga simulada en ms. */
  delay?: number;
}

export default function LoadingCheckButton({
  text = "Jetzt buchen",
  color = "#0071e3",
  delay = 1200,
}: LoadingCheckButtonProps) {
  const [state, setState] = useState<"idle" | "load" | "done">("idle");

  const go = () => {
    if (state !== "idle") return;
    setState("load");
    setTimeout(() => setState("done"), delay);
    setTimeout(() => setState("idle"), delay + 1600);
  };

  return (
    <motion.button
      type="button"
      whileTap={{ scale: 0.96 }}
      onClick={go}
      className="flex min-w-36 items-center justify-center gap-2 rounded-full px-6 py-3 text-sm font-medium text-white shadow-[0_1px_2px_rgba(0,0,0,0.03),0_8px_28px_rgba(0,0,0,0.05)]"
      style={{ backgroundColor: color }}
    >
      <AnimatePresence mode="wait" initial={false}>
        {state === "idle" ? (
          <motion.span
            key="idle"
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
          >
            {text}
          </motion.span>
        ) : state === "load" ? (
          <motion.span key="load" initial={{ scale: 0.6 }} animate={{ scale: 1 }}>
            <Loader2 className="h-4 w-4 animate-spin" />
          </motion.span>
        ) : (
          <motion.span
            key="done"
            initial={{ scale: 0.4, opacity: 0 }}
            animate={{ scale: 1, opacity: 1 }}
            transition={spring}
            className="flex items-center gap-2"
          >
            <Check className="h-4 w-4" /> Fertig
          </motion.span>
        )}
      </AnimatePresence>
    </motion.button>
  );
}

Prompt für KI

Füg ihn in ChatGPT, Claude oder Cursor ein und der Baustein wird mit diesen Einstellungen an dein Projekt angepasst, auch ohne React.

Mehr aus Buttons

Wofür du ihn nutzen kannst

Manche Aktionen verdienen ein deutliches „Erledigt“: einen Tisch reservieren, eine Bestellung bezahlen, einen Kurs im Fitnessstudio buchen. Diese Pille läuft durch eine kurze Wartezeit und endet mit einem Häkchen, das hineinfedert. So fragt sich niemand, ob es geklappt hat. Erst dieser letzte Hüpfer macht aus einem Lade-Button eine Erfolgsanimation, die man wirklich wahrnimmt.

Stell die Dauer ungefähr so ein, wie deine Anfrage wirklich braucht, meist unter anderthalb Sekunden. Kann es deutlich länger dauern, schreib daneben etwas wie „Wird bestätigt…“, damit das Warten nicht wie ein Hänger wirkt.