Gecko UIGecko UI

LoadingButton

Button component with built-in loading state and spinner

LoadingButton

LoadingButton extends the Button component with built-in loading state visualization. Automatically displays a spinner and optional loading text while preventing user interaction during asynchronous operations.

Installation

import { LoadingButton } from '@geckoui/geckoui';

Basic Usage

import { useState } from 'react';

function Example() {
  const [loading, setLoading] = useState(false);

  const handleClick = async () => {
    setLoading(true);
    await someAsyncOperation();
    setLoading(false);
  };

  return (
    <LoadingButton loading={loading} onClick={handleClick}>
      Submit
    </LoadingButton>
  );
}

Props API

PropTypeDefaultDescription
loadingbooleanfalseDisplay loading state with spinner
loadingTextstring-Text to show when loading (replaces children)
spinnerPosition'start' | 'end''start'Position of the spinner
variant'filled' | 'outlined' | 'ghost' | 'icon''filled'Button visual style
size'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Button size
color'primary''primary'Button color scheme
disabledbooleanfalseDisable the button
...restButtonHTMLAttributes-All standard Button props

Examples

Form Submission

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

  const handleSubmit = async () => {
    setIsSubmitting(true);
    await saveFormData();
    setIsSubmitting(false);
  };

  return (
    <LoadingButton
      loading={isSubmitting}
      loadingText="Saving..."
      onClick={handleSubmit}
    >
      Save Changes
    </LoadingButton>
  );
}

Loading State Comparison

<LoadingButton loading={false}>
  Not Loading
</LoadingButton>

<LoadingButton loading={true}>
  Loading State
</LoadingButton>

With Loading Text

<LoadingButton
  loading={isProcessing}
  loadingText="Processing..."
>
  Process Payment
</LoadingButton>

<LoadingButton
  loading={isUploading}
  loadingText="Uploading..."
>
  Upload File
</LoadingButton>

Without Loading Text

When loadingText is not provided, the button keeps its original label:

<LoadingButton loading={isDeleting}>
  Delete Account
</LoadingButton>

Spinner Position

<LoadingButton
  loading={isProcessing}
  spinnerPosition="start"
  loadingText="Processing..."
>
  Process
</LoadingButton>

<LoadingButton
  loading={isProcessing}
  spinnerPosition="end"
  loadingText="Processing..."
>
  Process
</LoadingButton>

Different Variants

<LoadingButton loading={isLoading} variant="filled">
  Filled Loading
</LoadingButton>

<LoadingButton loading={isLoading} variant="outlined">
  Outlined Loading
</LoadingButton>

<LoadingButton loading={isLoading} variant="ghost">
  Ghost Loading
</LoadingButton>

Different Sizes

<LoadingButton loading={isLoading} size="sm">Small</LoadingButton>
<LoadingButton loading={isLoading} size="md">Medium</LoadingButton>
<LoadingButton loading={isLoading} size="lg">Large</LoadingButton>

Async Operation Example

'use client';

import { useState } from 'react';
import { LoadingButton } from '@geckoui/geckoui';

function DownloadReport() {
  const [isDownloading, setIsDownloading] = useState(false);

  const handleDownload = async () => {
    setIsDownloading(true);
    try {
      const data = await fetchReportData();
      downloadFile(data);
    } finally {
      setIsDownloading(false);
    }
  };

  return (
    <LoadingButton
      loading={isDownloading}
      loadingText="Downloading..."
      onClick={handleDownload}
      variant="outlined"
      size="lg"
    >
      Download Report
    </LoadingButton>
  );
}

Behavior

Loading State

When loading={true}:

  • Button becomes disabled automatically
  • Spinner is displayed (at start or end position)
  • Optional loading text replaces the original content
  • User interaction is prevented

Content Display

The button content follows this priority:

  1. If loading={true} and loadingText is provided → shows loadingText
  2. If loading={true} and loadingText is not provided → keeps original children
  3. If loading={false} → shows original children

Accessibility

  • Inherits all accessibility features from Button component
  • Automatically disabled during loading state
  • Spinner provides visual feedback
  • Loading text provides clear status indication
  • Works with screen readers

Styling

The component uses BEM-style class names:

  • GeckoUILoadingButton - Main container class
  • GeckoUILoadingButton--{variant} - Variant modifier
  • GeckoUILoadingButton--{variant}-{color} - Combined variant and color
  • GeckoUILoadingButton--size-{size} - Size modifier
  • GeckoUILoadingButton--loading - Applied during loading state
  • GeckoUILoadingButton--{variant}-loading - Variant-specific loading state

Dependencies

This component uses the internal Spinner component for the loading animation.

  • Button - Base button component
  • Spinner - Loading spinner component