Spinner
Indicate work in progress with theme-timed motion.

use blinc_cn as cn;
use blinc_layout::prelude::*;
pub fn spinner_demo() -> Div {
div()
.class("demo-stack")
.class("demo-stack--center")
.child(cn::spinner().size(cn::SpinnerSize::Large))
.child(text("Preparing your workspace").class("demo-caption"))
}
@layer components {
.cn-spinner {
color: var(--cn-spinner-color, var(--primary));
}
.cn-spinner__track {
border-color: var(--cn-spinner-track, var(--border));
}
.cn-spinner__arc {
border-color: var(--cn-spinner-color, var(--primary));
animation: cn-spinner-turn 1000ms linear infinite;
}
@keyframes cn-spinner-turn {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
}
Usage and properties
The Preview records the spinner turning, without a cursor. Live uses the native animation.
Use the installation guide to add blinc_cn and its component stylesheet. Create the fixture bindings once, and return the demo from your UI builder. Values marked Bound accept Signal/Computed sources where the API supports them; structural options configure the component at construction.
| Property | Type | Update model | This example |
|---|---|---|---|
size | SpinnerSize | Construction | Large |
Keyboard and interaction
Informational content; no activation or Tab stop is required.
Customizing it
Add application CSS after the default component layer. These selectors are the restyling surface for this component:
.cn-spinner.cn-spinner__track.cn-spinner__arc
Theme and component variables: --primary, --text-primary, --text-secondary, --surface, --border, --radius-default, --duration-fast, --ease-state.
Built-in themes
The Live theme control installs Blinc's own theme bundles, including their colours, focus rings, corner shapes and motion tokens.
pub fn theme_bundle_for(name: &str) -> blinc_theme::ThemeBundle {
match name {
"restrained" => blinc_theme::RestrainedTheme::bundle(),
"expressive" => blinc_theme::ExpressiveTheme::bundle(),
_ => blinc_theme::HybridTheme::bundle(),
}
.with_css(blinc_cn::cn_styles::CN_STYLES)
}Download the default widget and component stylesheets. Sample assets and licenses are available in the asset guide.
Documentation
From the canonical component guide.
spinner().size(SpinnerSize::Medium)
Sizes are Small (16px), Medium (24px, the default) and Large (32px).
The track is .cn-spinner__track; .cn-spinner__arc turns by the
cn-spinner-turn keyframes. Set speed through CSS:
.slow-spinner .cn-spinner__arc { animation-duration: 2000ms; }
Beside a Busy Button
A button binds its label and disabled prop. Compose a spinner while it is busy:
use blinc::core::reactive::computed;
let busy = ctx.use_signal(false);
let caption = computed(move |graph| {
if graph.get(busy).unwrap_or(false) { "Saving" } else { "Save" }.to_string()
});
div().flex_row().items_center().gap(2.0)
.child(button(caption).disabled(busy).on_click(move |_| busy.set(true)))
.show(busy, || div().child(spinner().size(SpinnerSize::Small)))
.child(button("Finish").on_click(move |_| busy.set(false)))
In an application, the request completion callback clears busy; the Finish
button makes that completion explicit in this example. There is no button
.loading(...) prop.
Platforms and version
The component API is available in Blinc 0.6.0. The Live example runs in a dedicated worker and requires a compatible GPU surface. Preview and Code remain available when Live cannot start. The canvas has a descriptive label; a full screen-reader DOM mirror is not provided. The gallery integration is based on revision e2e55c24e078.
Recordings and live demos use the default Hybrid theme with bundled Noto Sans. The recording uses a 560 × 320 logical viewport at twice that resolution. Live follows its container and actual display density. Source base revision · Exact build source · Artifact versions and checksums · Font license.