Dynamic Spin Morphing
Relevant source files
The following files were used as context for generating this wiki page:
Dynamic Spin Morphing is a feature of the Spin component in HX-UI that allows loading indicators to transition between different visual forms. It leverages 41 distinct loading shapes from the UI Ball LDRS library. The system supports a unique rotate mode that periodically switches the spinner's appearance using cross-fade animations to improve user experience during long-running tasks.
Sources: README.md:92-94, src/primitives/spin.tsx:6-24
Component Architecture
The Spin component functions as a React primitive that manages visual states for loading indicators. It utilizes a layered approach to handle transitions, ensuring that the root container maintains its size while the previous variant fades out and the new variant fades in.
Core Rendering Logic
The component uses two internal layers for morphing:
- Fade-In Layer: The current variant, which participates in the layout and determines the component's dimensions.
- Fade-Out Layer: The previous variant, which uses absolute positioning (
inset: 0) to overlap the new variant without affecting layout.
Sources: src/primitives/spin.tsx:135-171, src/spin-variants.css:50-84
The diagram shows the dual-layer structure used to prevent layout jumps during transitions.
Sources: src/primitives/spin.tsx:162-184, src/spin-variants.css:73-82
Playback Modes
The morphing behavior is governed by the mode prop, which determines how and when the spinner changes its variant.
| Mode | Behavior | Use Case |
|---|---|---|
fixed | Stays on a single variant. | Buttons, inline form feedback. |
rotate | Switches variants randomly at specific intervals. | Full-page loads, long waits. |
random | Picks one variant on mount and stays fixed. | Quick feedback, variety. |
Sources: src/primitives/spin.tsx:16-30
Rotation Logic
When mode="rotate" is active, an internal timer triggers at a set interval (default 2200ms). The logic selects a new variant from a rotatePool while ensuring the same variant is not picked twice in a row.
The sequence illustrates the state transition process in rotate mode.
Sources: src/primitives/spin.tsx:112-131
Visual Styles and Transitions
Visual variants are defined in src/spin-variants.css and imported via ldrs/react. The project includes a whitelist of 41 variants, such as quantum, waveform, helix, and jellyTriangle.
Animation Specifications
- Duration: Both fade-in and fade-out animations last 400ms.
- Easing: Fade-in uses
cubic-bezier(0.2, 0, 0.4, 1)(ease-out) for a fast start. Fade-out usescubic-bezier(0.5, 0, 0.8, 1)(ease-in) to quickly move past semi-transparent states. - Reduced Motion: If
prefers-reduced-motionis detected, the fade duration is reduced to 1ms for instant switching.
Sources: src/spin-variants.css:57-89, src/primitives/spin.tsx:38-56
Configuration Options
The Spin component is exported from src/index.ts and accepts several properties to control its behavior and appearance.
| Property | Type | Default | Description |
|---|---|---|---|
size | SpinSize | "md" | Predefined sizes (sm, md, lg, xl) or a number in pixels. |
variant | SpinVariant | "quantum" | The initial or fixed loading shape. |
mode | SpinMode | "fixed" | Playback mode: fixed, rotate, or random. |
interval | number | 2200 | Milliseconds between morphs in rotate mode. |
rotatePool | SpinVariant[] | DEFAULT_ROTATE_POOL | The set of variants to cycle through. |
color | string | "currentColor" | CSS color for the spinner elements. |
speed | number | - | Multiplier for the internal animation speed of the variant. |
Sources: src/primitives/spin.tsx:75-87, src/index.ts:21
Implementation Example
// Example of a rotating spin with a custom pool
import { Spin } from "@hx/ui";
export function LoadingScreen() {
return (
<Spin
mode="rotate"
size="lg"
interval={3000}
rotatePool={["quantum", "helix", "infinity"]}
/>
);
}
Sources: src/primitives/spin.tsx:90-192
Summary
Dynamic Spin Morphing in HX-UI provides a sophisticated loading experience by alternating between LDRS-based animations. By using a dual-layer React structure and specific CSS cubic-bezier curves, the component ensures smooth transitions that make long waiting periods more engaging for users without causing layout instability.
Sources: README.md:92-94, src/primitives/spin.tsx:6-35