Skip to content
weftGitHub

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/warp

Usage

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 const

Limits 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

Accessibility

Up/Down
Steps the unit and carries into the next one
Shift+Up/Down
Takes three steps
Digits
Fill the unit

API Reference

PropTypeDefaultDescription
labelstring—The accessible name, drawn as the floating border label (or above, classic). Required.
hintunknown—One line of help under the control.
errorunknown—Shown instead of the hint; marks the field invalid.
iconIconRef—Leading icon: it sweeps with the border.
prefixunknown—Text or an element inside the field before the value, such as $.
suffixunknown—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.
clearablebooleanfalseA clear button (shown once there is a value).
counternumber—Maximum length, shown as a counter.
idstring—The element id. One is made for you if you leave it out.
disabledbooleanfalseTurns it off, and takes it out of the tab order.
readonlybooleanfalseShows the value and lets it be selected and copied, but not changed.
requiredbooleanfalseThe form will not submit without it.
namestring—The name it posts under in a form.
localestring—The language and region used to format values.
todaystring—Pins "today" (server render, tests); the browser's clock otherwise.
presentationPresentation—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.
unitsUnit[]['h', 'm']Any of d, h, m, s.
max`P${string}`—The highest allowed value.
stepPartial<Record<"h" | "m" | "s", number>>—Arrow key steps by unit.
balancebooleantrueRolls 90 minutes into 1 hour 30. Set to false to keep what was typed.
EventTypeDefaultDescription
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