NumberInput is a compact number-adjustment control.
It renders a minus button, a central text display, and a plus button inside one bordered field. This makes it useful for quantities, counts, and compact settings where stepwise adjustment matters more than free-form typing.
Example
use fission::prelude::*;
let widget: Widget = NumberInput {
value: view.state().quantity as f32,
display_text: Some(view.state().quantity.to_string()),
min: Some(1.0),
max: Some(10.0),
step: 1.0,
on_increment: Some(increment_quantity_action),
on_decrement: Some(decrement_quantity_action),
on_change: Some(change_quantity_text_action),
..Default::default()
}
.into();
The reducer usually owns the real numeric value and decides how to clamp, parse, or reject changes.
Field table
| | | |
|---|
| | Stable identity for the inner text field. | |
| | | |
| | Exact text shown in the field. | If None, the widget formats value with format!("{}", value). |
| | | Present for product meaning, but not enforced by the current widget implementation. |
| | | Present for product meaning, but not enforced by the current widget implementation. |
| | Intended adjustment step. | Defaults to 1.0, but the current widget does not apply it automatically. Your reducer does. |
| | Width of the central text field. | If None, width is estimated from display_text. |
| | Size of the plus and minus buttons. | Defaults to 32.0 with a lower bound of 28.0. |
| | Spacing between the buttons and field. | |
| | Action fired by the plus button. | |
| | Action fired by the minus button. | |
| | Intended text-edit action. | Present in the struct, but not currently wired by the checked-in implementation. |
Current behavior and limitations
The central field is rendered with TextInput, but in the checked-in implementation its on_change hook is not passed through yet. Likewise, min, max, and step are meaningful configuration fields for your product logic, but the widget does not enforce or apply them by itself.
In practice that means NumberInput is best today for stepper-style adjustment through the plus and minus buttons. If you need full free-form numeric typing with validation on every keystroke, compose a TextInput directly and parse inside the reducer.
Specific advice
Keep the canonical number in state as a number, not only as a string. If you also need a draft text representation, store that draft explicitly so validation and formatting stay predictable.
Production checklist
For NumberInput, review the fields that change behavior before treating the widget as finished: id, value, display_text, min, max, step. The goal is to make the product rule visible in state and actions, not hidden inside ad-hoc construction code.
If this widget appears inside an interactive flow, keep the surrounding action binding in the parent component and test that the flow still has one clear reducer path.
Set id only when identity must be stable across filtering, reordering, diagnostics, or tests; otherwise let Fission derive identity from structure.
Check the semantics tree for the user-facing label or role that makes this widget understandable without relying only on pixels.
Add at least one component or harness test that confirms the visible text, semantic role, action dispatch, and layout constraint that matter for this widget in context.
If a screen starts repeating the same NumberInput setup, extract a named component around this widget. That keeps the reference API small while making product code easier to read and safer for generated code to copy.
TextInput, Slider, TimePicker, and FormControl.