DurationField
Enter a length of time in days, hours, minutes or seconds.
SourcePackage @weft-js/warp
Preview
tsx
import { state } from '@weft-js/core'import { DurationField, Stack, Text } from '@weft-js/warp'import type { IsoDuration } from '@weft-js/warp'export function Timeout() { const timeout = state<IsoDuration | null>('PT1H30M') return ( <Stack gap="related"> <DurationField label="Build timeout" value={timeout} /> <Text subtle role="caption">Saved as {timeout.value ?? 'nothing'}</Text> </Stack> )}Installation
npm install @weft-js/warpUsage
tsx
import { DurationField } from '@weft-js/warp'Other units
units picks the boxes.
tsx
import { DurationField, Stack } from '@weft-js/warp'export function Units() { return ( <Stack gap="group"> <DurationField label="Health check every" units={[...MIN_SEC]} defaultValue="PT30S" /> <DurationField label="Keep previews for" units={[...DAY_HOUR]} defaultValue="P7DT12H" /> </Stack> )}const MIN_SEC = ['m', 's'] as constconst DAY_HOUR = ['d', 'h'] as constLimits and steps
Arrow keys move by step and stop at max.
tsx
import { DurationField } from '@weft-js/warp'export function Limits() { return ( <DurationField label="Canary period" hint="At most 2 hours, in 15-minute steps" defaultValue="PT45M" max="PT2H" step={{ m: 15 }} /> )}When to use
Use it for
- A length of time, not a moment
Reach for something else
- TimeField, when it is a time of day
- NumberField, when there is only one unit
Accessibility
- Up/Down
- Steps the unit and carries into the next one
- Shift+Up/Down
- Takes three steps
- Digits
- Fill the unit
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | The accessible name, drawn as the floating border label (or above, classic). Required. |
hint | unknown | — | One line of help under the control. |
error | unknown | — | Shown instead of the hint; marks the field invalid. |
icon | IconRef | — | Leading icon: it sweeps with the border. |
prefix | unknown | — | Text or an element inside the field before the value, such as $. |
suffix | unknown | — | Text or an element inside the field after the value, such as kg. |
variant | "floating" | "classic" | — | floating (default, or the app's warp({ fields })) · classic: the label above. |
appearance | "line" | — | line: only a bottom line under the value, no box or fill. The boxed field otherwise. |
size | "sm" | "md" | "lg" | 'md' | Control size. md by default. |
clearable | boolean | false | A clear button (shown once there is a value). |
counter | number | — | Maximum length, shown as a counter. |
id | string | — | The element id. One is made for you if you leave it out. |
disabled | boolean | false | Turns it off, and takes it out of the tab order. |
readonly | boolean | false | Shows the value and lets it be selected and copied, but not changed. |
required | boolean | false | The form will not submit without it. |
name | string | — | The name it posts under in a form. |
locale | string | — | The language and region used to format values. |
today | string | — | Pins "today" (server render, tests); the browser's clock otherwise. |
presentation | Presentation | — | auto opens a popover, or a sheet when the viewport is under 600px wide; popover and sheet force one. |
value | `P${string}` | State<`P${string}` | null> | null | — | The current value, when you own the state. |
defaultValue | `P${string}` | null | — | The starting value, when the component owns the state. |
units | Unit[] | ['h', 'm'] | Any of d, h, m, s. |
max | `P${string}` | — | The highest allowed value. |
step | Partial<Record<"h" | "m" | "s", number>> | — | Arrow key steps by unit. |
balance | boolean | true | Rolls 90 minutes into 1 hour 30. Set to false to keep what was typed. |
| Event | Type | Default | Description |
|---|---|---|---|
onInput | ((e: InputEvent & { currentTarget: HTMLInputElement & HTMLTextAreaElemen… | — | Called on each keystroke. |
onValueChange | ((v: `P${string}` | null, reason: ChangeReason) => void) | — | Called with each new value, and whether a pointer, a key or code made the change. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="duration-field"] [data-part="segments"]
segmentssegmentliteral
RelatedTime fieldNumber field