Field
Text entry in a recess, the label printed above it, and a hint that says how to fix an error.
Kit part · Forms · Inputs · Numbers · Sliders & faders
A number you can type or drag, the way a pro tool’s value field works: an engraved ruler under the numerals slides beneath a fixed index as the value moves.
| Region | Weight |
|---|---|
| eu-west | |
| us-east | |
| ap-south |
Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.
Aluminium
| Part | Rest | Hover | Scrubbing | Focus | At a stop | Error | Disabled |
|---|---|---|---|---|---|---|---|
| Field | |||||||
| Compact |
Graphite
| Part | Rest | Hover | Scrubbing | Focus | At a stop | Error | Disabled |
|---|---|---|---|---|---|---|---|
| Field | |||||||
| Compact |
| Name | Kind | Values | What it does |
|---|---|---|---|
| <tui-scrub> | element | wraps one <input> | The well: the numerals on top, the ruler along its floor. Builds itself around the input it is given. |
| <input> | element | name · value | The form control, kept real: its value posts; it becomes a text spinbutton with inputmode="decimal". |
| min · max | attribute | 0 · 100 | The stops. Values are clamped to them; typed values past them are too, with a knock at the stop. |
| step | attribute | 1 | What an arrow key, the wheel and a detent move by. The ruler ticks once per step. |
| precision | attribute | the step’s decimals | Decimals the value keeps. A drag can land between steps down to this; Alt steps a tenth when it allows. |
| unit · unit-text | attribute | e.g. "ms" · "milliseconds" | Printed after the numerals, and spoken in aria-valuetext. unit-text is the spoken form when the printed one reads badly. |
| px-per-step | attribute | 1.5–8, from the range | Drag rate at slow speed. Faster drags gain up to ×4, smoothly. |
| label | attribute | text | An aria-label for the input when there is no printed label, as in a table cell. |
| data-detent | attribute | — | Drags snap to whole steps; each one moves the ruler a notch and taps the phone’s motor where it has one. |
| data-lock | attribute | — | Pointer lock once a drag passes its dead zone, for endless drags. Refused or unsupported, the drag carries on as usual. |
| data-bound | attribute | "min" · "max" | Set while the value rests on a stop. Read it; the part writes it. |
| data-scrubbing · data-error | attribute | — | Set during a drag, and while typed text is not a number. |
| .tui-scrub--compact | class | — | 26px numerals over a ruler of ticks only: for table cells and dense inspectors. |
| .tui-scrub-row | class | on the .tui-field | The label printed on the left, the field on the right: an inspector row. |
| .tui-scrub__grip | class | added to the label | The field’s printed label becomes a drag handle too. Added by the part. |
| .value · .input | property | number · <input> | Read or set the number (setting fires nothing); reach the input. |
| input · change | event | on the <input> | input while the value moves; change when it settles: drag released, key pressed, text taken. |
| Drag | pointer | 3px dead zone | Press the ruler or the label and drag; right is more. Under 3px it is a click, and you are typing. Esc puts the value back. |
| Shift · Alt | modifier | ×10 · ×0.1 | For drags, arrow keys and the wheel alike. |
| ↑ → · ↓ ← | keyboard | ± step | Step up and down. While you are typing, ← and → move the caret instead. |
| PageUp · PageDown · Home · End | keyboard | ±10 steps · min · max | Big steps and the stops. While typing, Home and End move the caret. |
| Enter · Escape | keyboard | take · revert | Take what was typed, or put back the last good number. |
| Wheel | pointer | while focused | Steps the value only when the field has focus, so scrolling the page never changes it. |
| .is-hover · .is-down · .is-focus | class | on <tui-scrub> | Forced states, for documentation and specimens only. |
<label class="tui-field">
<span class="tui-label">Temperature</span>
<tui-scrub min="0" max="2" step="0.1" precision="2">
<input name="temperature" value="0.70">
</tui-scrub>
<span class="tui-hint">0 repeats itself; 2 wanders.</span>
</label>
<label class="tui-field">
<span class="tui-label">Rate limit</span>
<tui-scrub min="0" max="6000" step="10" unit="/min" unit-text="requests per minute" data-lock>
<input name="rate" value="600">
</tui-scrub>
</label>import '/kit/kit.mjs'; // defines <tui-scrub>
const temp = document.querySelector('tui-scrub input[name="temperature"]');
temp.addEventListener('input', () => preview(Number(temp.value))); // while it moves
temp.addEventListener('change', () => save(Number(temp.value))); // when it settles
// Or read and set the number on the element; setting fires nothing.
const field = temp.closest('tui-scrub');
field.value = 0.2;Needs kit.css and kit.mjs. How to install the kit.
role="spinbutton" with aria-valuenow, aria-valuemin, aria-valuemax and an aria-valuetext that carries the unit (“600 requests per minute”). Its name is the printed label that wraps it.aria-invalid and a custom validity message, and the hint below says the range; nothing typed is thrown away.touch-action: none: on a phone the page scrolls from anywhere else, and a tap on the numerals opens the decimal keypad.aria-hidden). Reduced motion stops the ruler gliding and the stop’s knock; the number, the stop and the lit index still show.One custom element around a real input. The ruler is a single strip whose ticks are three repeating backgrounds (fine every step, a longer one halfway, a long one at each round-numbered major) each an ink line with a lit line beside it, so the cuts read engraved; the numbers are spans placed along it. The strip moves by transform only, under a fixed index: a printed pointer over a hairline that turns amber with a lamp’s glow while you set the value. Past each end a heavy stop and hatching are printed on the strip, so at min or max the stop arrives under the index; a push past it knocks the hairline 1.5px and lets it settle. The window’s ends are masked away, as a tape curls over its drums. Drags use pointer capture, a 3px dead zone and a smoothed speed-to-gain curve capped at ×4; data-lock adds pointer lock.
Type it, or drag the ruler. Keys move by the step, a drag reaches the precision, and the index lights only while you are setting it.
6 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.