Baktiyar Ablaikhan

Stateful Button

Source
Aceternity UI ↗
Author
Aceternity UI
Licence
Aceternity UI licence (free component)

Loading…

Click it: a spinner grows in, then a check mark, while the button reflows its width.

Code

"use client";

import React, { useEffect, useRef } from "react";
import { Button } from "@/lab/aceternity/ui/stateful-button";

export default function StatefulButtonDemo() {
  const timers = useRef<Set<ReturnType<typeof setTimeout>>>(new Set());

  useEffect(() => {
    const pending = timers.current;
    return () => pending.forEach(clearTimeout);
  }, []);

  // dummy API call
  const handleClick = () => {
    return new Promise((resolve) => {
      const t = setTimeout(() => {
        timers.current.delete(t);
        resolve(undefined);
      }, 4000);
      timers.current.add(t);
    });
  };

  return (
    <div className="relative flex h-full w-full items-center justify-center">
      <Button onClick={handleClick}>Send message</Button>
    </div>
  );
}
Prompt

Build "Stateful Button", a button animation. What it does: Click it: a spinner grows in, then a check mark, while the button reflows its width. Write it as a single self-contained React component in TypeScript that fills its parent (w-full h-full), styled with Tailwind CSS, using motion. Technique: the Motion library. It sits on a light background, in a 16:10 frame. Respect prefers-reduced-motion with a still state, pause work when the element is off screen, and keep it accessible. Original: https://ui.aceternity.com/components/stateful-button (Aceternity UI, Aceternity UI licence (free component)).