Skip to content

NumberField

<caos-number-field>

exact-decimal numeric input honoring the field precision and scale, via min / max / step

May be placed on a record page, a page inside an app and a step of a guided flow.

Name Attribute Description Type Default Required
label label, markup only The field’s name, drawn above the control and pointed at the input, so clicking it focuses the box. Left unset, no label is drawn. text none declared Optional
placeholder placeholder, markup only The greyed hint inside an empty box. text none declared Optional
value value, markup only The current number. It is written back to this attribute on every keystroke, so the attribute and what is on screen stay the same thing. number none declared Optional
min min, markup only The lowest value the browser will accept. Forwarded to the inner input; nothing here clamps. number none declared Optional
max max, markup only The highest value the browser will accept. Forwarded to the inner input; nothing here clamps. number none declared Optional
step step, markup only The increment the stepper moves by, and the precision the browser enforces — 0.25 for a quarter-inch, 0.01 for cents. number none declared Optional
name name, markup only The form name forwarded to the inner input, for a field submitted as part of a form. text none declared Optional
required required, markup only This field has to be filled in. Draws the asterisk beside the label and marks the input required. boolean false Optional
disabled disabled, markup only You may not type in this. Greys the box and refuses focus. boolean false Optional
invalid invalid, markup only What is in the box is wrong. Turns the border and the message red and marks the input invalid for a screen reader. The page decides; the field does not. boolean false Optional
message message, markup only The line under the box — muted helper text on its own, the red reason when invalid is also set. This is where a bound belongs in words: “min” refuses a value, the message explains it. text none declared Optional
presentation presentation, markup only How the same number is drawn: box (the default), or slider, a range control with the chosen value beside it. It is a presentation of this field rather than a different field — min, max, step, required, disabled, invalid and message all mean what they always did. THE SLIDER NEEDS A RANGE: with min or max missing it stays the box, because a range control with no bounds silently spans the platform’s own 0–100, which has nothing to do with the field. The value is drawn beside the control because a range shows a position and never a number. text — one of box, slider box Optional
inline inline, markup only Draw the record-detail variant instead of the boxed form control: no box, an accent underline, inheriting the surrounding type. The label and the message are hidden. boolean false Optional
Name When it fires What it carries
input On every keystroke, after the value attribute has been written back. nothing
change When the control is committed — focus leaves, Enter is pressed, or the stepper is used. nothing

Nothing goes inside this piece.

Design token What it controls
--caos-font The typeface of the label, the box and the message.
--caos-text-body The size of the label and of the typed number.
--caos-space-1 The gap between the label, the box and the message.
--caos-space-3 The vertical padding inside the box.
--caos-radius The corner radius of the box.
--caos-color-border The box outline at rest.
--caos-color-border-strong The box outline while the field has focus.
--caos-color-surface-2 The fill of the box.
--caos-color-text The colour of the typed number.
--caos-color-text-muted The label, the placeholder, the message and disabled text.
--caos-color-accent The hover outline, and the underline of the inline variant.
--caos-accent-wash The tint that fills the box while it has focus, in place of a focus ring.
--caos-color-danger The required asterisk, and the outline and message when invalid.
Name Description Arguments
focus() Put the caret in the box. The shared implementation also tries to select what is there; a number input does not support selection, and the attempt is swallowed rather than thrown. options: FocusOptions

Nothing on this piece can be read back.

Part Which piece of it When it is there
::part(label) the label above the control Always
::part(input) the inner number input — or the range, in the slider presentation; one part name, because it is one control Always
::part(readout) the chosen value drawn beside the range, in the slider presentation only Always
::part(message) the line under the control Always

A quantity, a measurement or an amount the person types, where the precision and the bounds are known up front. Reach for it over TextField whenever the value is genuinely a number, because that is what buys the alignment and the stepper.

  • FieldRenderer — The type is not known until the record is read — hand it the field metadata and it draws the right control, including the currency and percent read formats this piece does not do.
  • TextField — The value only looks numeric — a part number, a phone number, a tag with leading zeros.
  • DateField — The number is a date.
  • ProgressBar — The number is being reported rather than entered.
  • StatTile — It is a headline figure on a page rather than a field on a form.

The control is a real number input with a generated id and a label pointing at it, so it is announced with its name, clicking the label focuses it, and the stepper and up/down keys work without anything being added. required and invalid are forwarded as required and aria-invalid. What is left to the author is the label — including the unit, since “48” announced on its own says nothing — and the message, which is the only place the bound is stated in words.

A measurement that cannot go below zero and moves in quarter-inches — the bounds carried by the control itself.

{
"id": "example",
"section": "A bounded measurement",
"columns": 1,
"items": [
{
"id": "number_field_1",
"type": "component",
"key": "number_field",
"inputs": {
"label": "Diameter (in)",
"value": 48,
"min": 0,
"step": 0.25
}
}
]
}
<caos-number-field label="Diameter (in)" value="48" min="0" step="0.25"></caos-number-field>

The same field with the page refusing the value: red outline, and the bound restated underneath in words rather than left for the person to infer from a rejected keystroke.

{
"id": "example",
"section": "Out of range",
"columns": 1,
"items": [
{
"id": "number_field_1",
"type": "component",
"key": "number_field",
"inputs": {
"label": "Diameter (in)",
"value": -6,
"min": 0,
"step": 0.25,
"invalid": true,
"message": "Diameter is a positive measurement."
}
}
]
}
<caos-number-field label="Diameter (in)" value="-6" min="0" step="0.25" invalid message="Diameter is a positive measurement."></caos-number-field>