Number Input
Edit a bounded number with typing, step controls or the mouse wheel.

use blinc_cn as cn;
use blinc_core::reactive::{Signal, computed};
use blinc_layout::{binding::IntoReactive, prelude::*};
pub fn number_input_demo(number: Signal<f64>, disabled: Signal<bool>) -> Div {
div()
.class("demo-stack")
.child(cn::label("Quantity"))
.child(cn::number_input(number).min(0.0).max(99.0).step(1.0).disabled(disabled))
.child(
bound_text(computed(move |g| {
format!("{} items", g.get(number).unwrap_or(0.0) as u32)
}))
.class("demo-caption"),
)
}
fn bound_text(value: impl IntoReactive<String>) -> Text {
Text::bound(value.into_reactive())
}
@layer components {
.cn-number-input-group {
box-shadow: var(--shadow-sm);
background: var(--input-bg);
border-color: var(--border);
}
.cn-number-input-group:disabled {
background: var(--input-bg-disabled);
box-shadow: none;
}
.cn-number-input-step {
background: transparent;
color: var(--text-secondary);
transition:
background-color var(--duration-fast) var(--ease-state),
color var(--duration-fast) var(--ease-state);
}
.cn-number-input-step--dec {
border-right: 1px solid var(--border);
}
.cn-number-input-step--inc {
border-left: 1px solid var(--border);
}
.cn-number-input-step:hover:not(:disabled) {
background: color-mix(in srgb, var(--text-primary) 6%, transparent);
color: var(--text-primary);
}
.cn-number-input-step:active:not(:disabled) {
background: color-mix(in srgb, var(--text-primary) 10%, transparent);
}
.cn-number-input-step:disabled {
color: var(--text-tertiary);
}
}
Usage and properties
Edit a bounded number with typing, step controls or the mouse wheel. Apply CSS after the component layer to restyle the documented parts.
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 |
|---|---|---|---|
value | Signal<f64> | Bound | 42 |
min / max / step | f64 | Construction | 0 / 99 / 1 |
disabled | bool or IntoReactive<bool> | Bound | values.disabled |
Keyboard and interaction
Tab focuses the field. Typing, the up and down arrows, the stepper buttons and the mouse wheel all clamp to the minimum and maximum. :focus-visible marks keyboard focus.
Customizing it
Add application CSS after the default component layer. These selectors are the restyling surface for this component:
.cn-number-input-group.cn-number-input-field.cn-number-input-step
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.
A number between a − and a +, bound to a Signal<f64>:
let qty = ctx.use_signal(1.0);
cn::number_input(qty)
.min(0.0)
.max(99.0)
.step(1.0)
.precision(0)
.size(InputSize::Medium)
.on_change(|value| println!("qty: {value}"))
.size(..) picks a scale of its own, a step smaller than a text input's, so
the control sits in a row beside others. The group carries the size as
data-size for rules to key on:
| Size | data-size | Row | Steps | Field (at least) | Text |
|---|---|---|---|---|---|
InputSize::Small | sm | 24px | 24px | 40px | 12px |
InputSize::Medium (default) | md | 32px | 32px | 48px | 13px |
InputSize::Large | lg | 40px | 36px | 52px | 14px |
Typing, the arrow keys, the buttons and the mouse wheel all clamp to min and max. One wheel line is one step and wheel up increases the value; trackpad movement accumulates into steps, and a disabled input ignores the wheel. The
width follows the bounds, not the value, so typing never resizes it.
The group is one bordered element (.cn-number-input-group) with a borderless
field and two steps (.cn-number-input-step--dec and --inc). A step tints on
:hover and :active, and is disabled, so dimmed and inert, where a step
would change nothing. These are rules with a transition; restyle them with
rules of your own.
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.