Spinner

Spinner element displays an animated loading. Perfect for showing loading states, progress spinners, and other visual feedback during asynchronous operations. Features customizable icons, colors, sizes, and rotation animations.

#Import

use gpui_kit::component::spinner::Spinner;

#Usage

#Basic

// Default loader icon
Spinner::new()

#Spinner with Custom Color

use gpui_kit::component::ActiveTheme;

// Blue spinner
Spinner::new()
    .color(cx.theme().blue)

// Green spinner for success states
Spinner::new()
    .color(cx.theme().green)

// Custom color
Spinner::new()
    .color(cx.theme().cyan)

#Spinner Sizes

// Extra small spinner
Spinner::new().xsmall()

// Small spinner
Spinner::new().small()

// Medium spinner (default)
Spinner::new()

// Large spinner
Spinner::new().large()

// Custom size
Spinner::new().with_size(px(64.))

#Spinner with Custom Icon

use gpui_kit::component::IconName;

// Loading circle icon
Spinner::new()
    .icon(IconName::LoaderCircle)

// Large loading circle with custom color
Spinner::new()
    .icon(IconName::LoaderCircle)
    .large()
    .color(cx.theme().cyan)

// Different loading icons
Spinner::new()
    .icon(IconName::Loader)
    .color(cx.theme().primary)

#Available Icons

The Spinner component supports various loading and progress icons:

#Loading Icons

  • Loader (default) - Rotating line spinner
  • LoaderCircle - Circular loading spinner

#Other Compatible Icons

  • Any icon from the IconName enum can be used, though loading-specific icons work best with the rotation animation

#Animation

The Spinner component features a built-in rotation animation:

  • Duration: 0.8 seconds (configurable via speed parameter)
  • Easing: Ease-in-out transition
  • Repeat: Infinite loop
  • Transform: 360-degree rotation

#Size Reference

SizeMethodApproximate Pixels
Extra Small.xsmall()~12px
Small.small()~14px
Medium(default)~16px
Large.large()~24px
Custom.with_size(px(n))n px

#Examples

#Loading States

// Simple loading spinner
Spinner::new()

// Loading with custom color
Spinner::new()
    .color(cx.theme().blue)

// Large loading spinner
Spinner::new()
    .large()
    .color(cx.theme().primary)

#Different Loading Icons

// Default loader (line spinner)
Spinner::new()
    .color(cx.theme().muted_foreground)

// Circle loader
Spinner::new()
    .icon(IconName::LoaderCircle)
    .color(cx.theme().blue)

// Large circle loader with custom color
Spinner::new()
    .icon(IconName::LoaderCircle)
    .large()
    .color(cx.theme().green)

#Status Spinners

// Loading state
Spinner::new()
    .small()
    .color(cx.theme().muted_foreground)

// Processing state
Spinner::new()
    .icon(IconName::LoaderCircle)
    .color(cx.theme().blue)

// Success processing (still animating)
Spinner::new()
    .icon(IconName::LoaderCircle)
    .color(cx.theme().green)

#Size Variations

// Extra small for inline text
Spinner::new()
    .xsmall()
    .color(cx.theme().muted_foreground)

// Small for buttons
Spinner::new()
    .small()
    .color(cx.theme().primary_foreground)

// Medium for general use (default)
Spinner::new()
    .color(cx.theme().primary)

// Large for prominent loading states
Spinner::new()
    .large()
    .color(cx.theme().blue)

// Custom size for specific requirements
Spinner::new()
    .with_size(px(32.))
    .color(cx.theme().orange)

#In UI Components

// In a button
Button::new("submit-btn")
    .loading(true)
    .icon(
        Spinner::new()
            .small()
            .color(cx.theme().primary_foreground)
    )
    .label("Loading...")

// In a card header
div()
    .flex()
    .items_center()
    .gap_2()
    .child("Processing...")
    .child(
        Spinner::new()
            .small()
            .color(cx.theme().muted_foreground)
    )

// Full-screen loading
div()
    .flex()
    .items_center()
    .justify_center()
    .h_full()
    .w_full()
    .child(
        Spinner::new()
            .large()
            .color(cx.theme().primary)
    )

#Performance Considerations

  • The animation uses CSS transforms for optimal performance
  • Multiple spinners on the same page share the same animation timing
  • The component is lightweight and suitable for frequent updates
  • Consider using smaller sizes for better performance with many spinners

#Common Patterns

#Conditional Loading

// Show spinner only when loading
.when(is_loading, |this| {
    this.child(
        Spinner::new()
            .small()
            .color(cx.theme().muted_foreground)
    )
})

#Loading with Text

// Loading text with spinner
h_flex()
    .items_center()
    .gap_2()
    .child(
        Spinner::new()
            .small()
            .color(cx.theme().primary)
    )
    .child("Loading data...")

#Overlay Loading

// Full overlay with spinner
div()
    .absolute()
    .inset_0()
    .flex()
    .items_center()
    .justify_center()
    .bg(cx.theme().background.alpha(0.8))
    .child(
        v_flex()
            .items_center()
            .gap_3()
            .child(
                Spinner::new()
                    .large()
                    .color(cx.theme().primary)
            )
            .child("Loading...")
    )

CC BY 4.0 · Documentation prose and original illustrations GPUI Kit has rights to license may be copied or adapted with attribution. License. Credit GPUI Kit, link to this source page and the CC BY 4.0 license, and indicate any changes. Code examples and software source remain under Apache-2.0. Existing Apache permissions remain; third-party material retains its own terms.