Loading...
bouncing-dots
Author Cloudapp
E.G.

Next.js 14 - Schicke Animationen in Sekunden mit TailwindCss erstellen

27. September 2024
Inhaltsverzeichnis

Vor einigen Monaten, als ich an einem Projekt arbeitete, kam die Idee auf, die Schaltfläche so zu animieren, dass sie „hüpfende Punkte“ anzeigt, solange der Prozess im Hintergrund (Erstellung von IaC-Ressourcen) nicht abgeschlossen ist. Nach einigem Nachdenken und einer schnellen Suche bei Google war die Lösung klar. Wir sollten Tailwind verwenden, da es für das Projekt bereits vorhanden war.

NPM Pakete

Ich benutze diese Pakete

"tailwindcss": "^3.4.1",
"postcss": "^8",
"autoprefixer": "^10",

Anpassen der Gloabl.css

Bevor wir mit der Codierung beginnen, fügen wir diese Ebene zu unserer global.css-Datei hinzu, die sich unter src/app/ befindet

@layer utilities {
  .animate-bounce {
    animation: bounce 1s infinite;
  }
  .delay-200 {
    animation-delay: 0.2s;
  }
  .delay-400 {
    animation-delay: 0.4s;
  }
  @keyframes bounce {
    0%,
    100% {
      transform: translateY(0);
      opacity: 1;
    }
    50% {
      transform: translateY(-50%);
      opacity: 0.5;
    }
  }
}

Mit dem neuen "Layer" können wir nun mit dem Programmieren beginnen.

Erstellen eines neuen “Loadingbutton”

Ich habe eine neue Komponente erstellt, „loadingbutton.component.tsx“ unter /src/components/tools/loadingbutton

import React from "react";

interface LoadingButtonProps {
  loading: boolean; // Prop to control loading state
  onClick: (e: React.FormEvent) => void; // Prop to handle button click
  startlabel?: string; // Prop to set the button label when not loading
  loadinglabel?: string; // Prop to set the button label when loading is finished
}

const LoadingButton: React.FC<LoadingButtonProps> = ({
  loading,
  onClick,
  startlabel,
  loadinglabel,
}) => {
  return (
    <button
      onClick={onClick}
      className={`w-full px-4 py-2 text-white rounded-md focus:ring-2 focus:ring-blue-500 focus:ring-opacity-50 ${
        loading
          ? "bg-blue-400 cursor-not-allowed" // Lighter color and disabled cursor when loading
          : "bg-blue-600 hover:bg-blue-700" // Normal hover effects
      }`}
      disabled={loading} // Disable button when loading
    >
      {!loading ? (
        <span>{startlabel}</span>
      ) : (
        <span className="flex items-center justify-center space-x-3">
          <span className="flex space-x-1">
            <span className="dot bg-white w-2 h-2 rounded-full animate-bounce delay-100"></span>
            <span className="dot bg-white w-2 h-2 rounded-full animate-bounce delay-200"></span>
            <span className="dot bg-white w-2 h-2 rounded-full animate-bounce delay-300"></span>
            <span className="dot bg-white w-2 h-2 rounded-full animate-bounce delay-400"></span>
          </span>
          <span>{loadinglabel}</span>
        </span>
      )}
    </button>
  );
};

export default LoadingButton;

Definition des Interfaces

Im oberen Bereich definieren wir die Schnittstelle mit vier "Props"

interface LoadingButtonProps {
  loading: boolean; // Prop to control loading state
  onClick: (e: React.FormEvent) => void; // Prop to handle button click
  startlabel?: string; // Prop to set the button label when not loading
  loadinglabel?: string; // Prop to set the button label when loading is finished
}

Wir haben ein „Startlabel“ (das angezeigt wird, bevor wir auf die Schaltfläche klicken) und ein „Loadinglabel“, das wir während der Animation anzeigen.

   <span className="flex items-center justify-center space-x-3">
          <span className="flex space-x-1">
            <span className="dot bg-white w-2 h-2 rounded-full animate-bounce delay-100"></span>
            <span className="dot bg-white w-2 h-2 rounded-full animate-bounce delay-200"></span>
            <span className="dot bg-white w-2 h-2 rounded-full animate-bounce delay-300"></span>
            <span className="dot bg-white w-2 h-2 rounded-full animate-bounce delay-400"></span>
          </span>
          <span>{loadinglabel}</span>
        </span>

Dieses Beispiel zeigt vier hüpfende Punkte. Wenn Sie 5 oder 6 Punkte benötigen, fügen Sie Linien hinzu und passen Sie die Verzögerung am Ende an.

Import loadingbutton in Hauptkomponente

Als nächsten Schritt importieren wir die Ladebutton-Komponente in unsere Hauptkomponente.

import LoadingButton from "@/components/tools/loadingbutton/loadingbutton.component";

Definition der "State Variablen"

Wir definieren zwei Variablen für den Ladezustand und den Zustand „hasStorageAccount“, die wir später für die Visualisierung verwenden.

const [loading, setLoading] = useState(false);
const [hasStorageAccount, setHasStorageAccount] = useState(false); // State to check if user already has a storage account

Ausgabe

Wenn die Zustandsvariable „hasStorageAccount“ wahr ist, wird die Schaltfläche „Löschen“ angezeigt; andernfalls wird die Schaltfläche „Erstellen“ angezeigt.

  return (
    <div className="max-w-lg p-6 mx-auto mt-6 bg-gray-400 rounded-lg shadow-md">
      <h2 className="mb-4 text-2xl font-bold text-center">
        {hasStorageAccount
          ? "You already have a storage account"
          : "Create Storage Account"}
      </h2>
      {/* Delete Storage Account Button */}
      {hasStorageAccount && ( 
        <LoadingButton
          loading={loading}
          onClick={handleDeleteStorageAccount}
          startlabel="Deleting Storage Account"
          loadinglabel="Deleting ..."
        />
      )}
      {!hasStorageAccount && (
        <LoadingButton
          loading={loading}
          onClick={handleSubmit}
          startlabel="Creating Storage Account"
          loadinglabel="Creating ..."
        />
      )}    
    </div>
  );

Das war's. Wie Sie sehen, können wir mit ein paar Codezeilen hübsche Animationen erstellen und sie überall verwenden.

button
button

Cloudapp-dev und bevor Sie uns verlassen

Danke, dass Sie bis zum Ende gelesen haben. Noch eine Bitte bevor Sie gehen:

Wenn Ihnen gefallen hat was Sie gelesen haben oder wenn es Ihnen sogar geholfen hat, dann würden wir uns über einen "Clap" 👏 oder einen neuen Follower auf unseren Medium Account sehr freuen.

Oder folgen Sie uns auf Twitter -> Cloudapp.dev

Verwandte Artikel