Skip to main content
Version: 1.0.3

Button With Spinner

Overview

The ButtonWithSpinner component is a specialized button that displays a loading spinner and changes its text during loading states. It automatically disables the button during loading and intelligently adjusts spinner colors based on the button variant for optimal visibility.

Preview

Installation

ignix add component button-with-spinner

Usage

Import the component:

import { ButtonWithSpinner } from '@site/src/components/UI/button-with-spinner';

Basic Usage

function BasicButtonWithSpinner() {
const [isLoading, setIsLoading] = useState(false);

const handleClick = async () => {
setIsLoading(true);
try {
await someAsyncOperation();
} finally {
setIsLoading(false);
}
};

return (
<ButtonWithSpinner
isLoading={isLoading}
loadingText="Loading..."
onClick={handleClick}
>
Submit
</ButtonWithSpinner>
);
}

With Custom Loading Text

function SaveButton() {
const [isSaving, setIsSaving] = useState(false);

const handleSave = async () => {
setIsSaving(true);
try {
await saveData();
} finally {
setIsSaving(false);
}
};

return (
<ButtonWithSpinner
isLoading={isSaving}
loadingText="Saving..."
onClick={handleSave}
>
Save Changes
</ButtonWithSpinner>
);
}

With Different Spinner Variants

function CustomSpinnerButton() {
const [isLoading, setIsLoading] = useState(false);

return (
<div className="flex gap-4">
<ButtonWithSpinner
isLoading={isLoading}
spinnerVariant="default"
onClick={() => setIsLoading(!isLoading)}
>
Default Spinner
</ButtonWithSpinner>
<ButtonWithSpinner
isLoading={isLoading}
spinnerVariant="bars"
onClick={() => setIsLoading(!isLoading)}
>
Bars Spinner
</ButtonWithSpinner>
<ButtonWithSpinner
isLoading={isLoading}
spinnerVariant="dots-bounce"
onClick={() => setIsLoading(!isLoading)}
>
Dots Bounce
</ButtonWithSpinner>
</div>
);
}

Examples

Button Variants

Use the variant prop to control the button style. Spinner colors are automatically adjusted for optimal visibility.

Spinner Variants

Use the spinnerVariant prop to control the spinner animation type.

Sizes

Use the size prop to control the button size. Spinner size is automatically adjusted proportionally.

Loading Text

Use the loadingText prop to customize the message displayed during loading state.

Props

PropTypeDefaultDescription
isLoadingbooleanfalseWhether the button is in a loading state. When true, the button is disabled and shows a spinner.
loadingTextstring'Loading...'Text to display when the button is in loading state.
spinnerSizenumber16Size of the spinner in pixels. Should be adjusted based on button size.
spinnerVariant'default' | 'bars' | 'dots-bounce''default'Variant of the spinner animation.
spinnerColorstring-Tailwind CSS class for spinner color (e.g., "bg-white", "border-white"). Auto-determined based on button variant if not provided.
variant'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'outline' | 'ghost' | 'subtle' | 'elevated' | 'glass' | 'neon' | 'pill''default'The visual style of the button.
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'The size of the button.
childrenReact.ReactNode-The button text/content to display when not loading.

Features

  • Automatic Color Adjustment: Spinner colors are automatically adjusted based on button variant for optimal visibility
  • Smooth Animations: Three spinner animation variants (default, bars, dots-bounce) with smooth transitions
  • Disabled State: Button is automatically disabled during loading to prevent multiple submissions
  • Customizable Loading Text: Change the loading message to match your use case (e.g., "Loading...", "Saving...", "Processing...")
  • Flexible Sizing: Supports all button sizes with proportional spinner sizing
  • TypeScript Support: Fully typed with comprehensive TypeScript definitions

Best Practices

  1. Loading State Management: Always use state management to control the isLoading prop based on your async operations
  2. Error Handling: Make sure to set isLoading to false in both success and error cases
  3. Spinner Size: Adjust spinnerSize proportionally to button size for better visual balance
  4. Loading Text: Use contextually appropriate loading text (e.g., "Saving..." for save buttons, "Submitting..." for forms)
  5. Accessibility: The button is automatically disabled during loading, which helps prevent accidental multiple submissions

Examples in Action

Form Submission

function FormExample() {
const [isSubmitting, setIsSubmitting] = useState(false);

const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsSubmitting(true);
try {
await submitForm();
// Show success message
} catch (error) {
// Handle error
} finally {
setIsSubmitting(false);
}
};

return (
<form onSubmit={handleSubmit}>
{/* form fields */}
<ButtonWithSpinner
type="submit"
isLoading={isSubmitting}
loadingText="Submitting..."
>
Submit Form
</ButtonWithSpinner>
</form>
);
}

API Call

function ApiCallExample() {
const [isLoading, setIsLoading] = useState(false);

const handleApiCall = async () => {
setIsLoading(true);
try {
const response = await fetch('/api/data');
const data = await response.json();
// Handle data
} finally {
setIsLoading(false);
}
};

return (
<ButtonWithSpinner
isLoading={isLoading}
loadingText="Loading data..."
onClick={handleApiCall}
>
Load Data
</ButtonWithSpinner>
);
}