New components library - Native UI

Spinner

An indicator that can be used to show a loading state.

Note: The Spinner component is a fully custom implementation using in-line svg with no external dependencies.

Installation

Copy the following code into your app directory.

uv

uv run buridan add component spinner
from components.ui.spinner import spinner

Anatomy

Use the following composition to build a Spinner component.

spinner()

Examples

Size

Use the size-* utility class to change the size of the spinner.

import reflex as rx

from components.ui.spinner import spinner


def spinner_size():
    return rx.el.div(
        spinner(class_name="size-3"),
        spinner(class_name="size-4"),
        spinner(class_name="size-6"),
        spinner(class_name="size-8"),
        class_name="flex items-center gap-6",
    )

Button

Add a spinner to a button to indicate a loading state. Place it before the label for a start position.

import reflex as rx

from components.ui.button import button
from components.ui.spinner import spinner


def spinner_button():
    return rx.el.div(
        button(spinner(), "Loading...", disabled=True, size="sm"),
        button(spinner(), "Please wait", disabled=True, size="sm", variant="outline"),
        button(spinner(), "Processing", disabled=True, size="sm", variant="secondary"),
        class_name="flex flex-col items-center gap-4",
    )

Badge

Add a spinner to a badge to indicate a loading or syncing state.

SyncingUpdatingProcessing
import reflex as rx

from components.ui.badge import badge
from components.ui.spinner import spinner


def spinner_badge():
    return rx.el.div(
        badge(spinner(), "Syncing"),
        badge(spinner(), "Updating", variant="secondary"),
        badge(spinner(), "Processing", variant="outline"),
        class_name="flex items-center gap-4",
    )

Marker

Combine Spinner with Marker and the shimmer utility for animated streaming status indicators. Set role="status" so assistive technology announces the update.

Thinking…
Generating response…
Processing
import reflex as rx

from components.ui.marker import marker
from components.ui.spinner import spinner


def spinner_marker():
    return rx.el.div(
        marker.root(
            marker.icon(spinner()),
            marker.content("Thinking…", class_name="shimmer w-fit"),
            role="status",
        ),
        marker.root(
            marker.icon(spinner()),
            marker.content("Generating response…", class_name="shimmer w-fit"),
            variant="border",
            role="status",
        ),
        marker.root(
            marker.icon(spinner()),
            marker.content("Processing"),
            variant="separator",
            role="status",
        ),
        class_name="flex w-full max-w-sm flex-col gap-6",
    )

API Reference

PropTypeDefaultDescription
class_namestr""Additional Tailwind classes applied to the icon.
**propsdictAny valid HTML attribute forwarded to the element (role, aria_label, etc.).