OPERATOR

TimeRange

UTC range and presets

2026-09-23 12:00:00.000 UTC to 13:00:00.000 UTC

Applied: 60 minutes · UTC

Pass value={{ start, end }} in Unix epoch milliseconds and update through onValueChange. Date and time fields use UTC, including millisecond precision. They use OPERATOR's Calendar and Clock icons with native picker and keyboard interaction. Start and end fields retain their visible UTC labels.

function InspectionWindow() {
  const [range, setRange] = useState({
    start: Date.UTC(2026, 8, 23, 12),
    end: Date.UTC(2026, 8, 23, 13),
  });
  return <TimeRange value={range} onValueChange={setRange} />;
}

Edits remain drafts until Apply range or Enter. External value changes replace drafts at once. Presets use { id, label, value } and apply immediately when valid; the preset that matches the applied range is pressed and filled.

Browsers show the native fields in their own clock and date order (a US English browser shows 02:00:00.000 PM). One line under the fields always gives the draft range in 24-hour UTC with milliseconds, for example 2026-10-02 14:00:00.000 UTC to 15:00:00.000 UTC; the end leaves out its date when it is the same day.

While the fields hold an edit the application has not applied, the sentence "The range change has not been applied." says so. Connect onDraftValidityChange to Review and Save: it reports (valid, { pending }) on mount and on every change, and valid is false while the fields hold an error or an unapplied edit, as with DateRangePicker.

Validation and bounds

Start must precede end. Empty fields, invalid dates, and values outside inclusive min/max cannot commit. Supported years are 0001–9999. Invalid supplied bounds block application with an explanation. Invalid or out-of-bounds presets are disabled.

Disabled

2026-09-23 12:00:00.000 UTC to 13:00:00.000 UTC

Applied: 60 minutes · UTC

Props

PROPTYPEDEFAULTREQUIRED
value

TimeRangeValue: { start: number; end: number }, Unix epoch milliseconds. Start must precede end; dates must be in years 0001–9999.

node—yes
onValueChange

(value: TimeRangeValue) => void. Only called on Apply, Enter or a valid preset; never for invalid drafts.

function—yes
onDraftValidityChange

(valid: boolean, details: { pending: boolean }) => void. Reports on mount and on every change whether the range in the fields can be used as it stands; valid is false while they hold an error or an edit not yet applied (pending: true). Connect it to Review and Save, as with DateRangePicker.

function—no
presets

Readonly TimeRangePreset array. Invalid or out-of-bounds presets are disabled.

array—no
min

Inclusive minimum epoch milliseconds. Invalid dates or conflicting bounds prevent commits.

number—no
max

Inclusive maximum epoch milliseconds.

number—no
disabledbooleanfalseno
label

Accessible name of the range group; each input also has a visible UTC label.

string"Time range"no

Accessibility

  • Visible Start/End labels identify UTC date and time fields. The fields pair up or stack by the component's own width, not the window's.
  • The group is described by the 24-hour UTC line and, while an edit is not applied, by the sentence that says so.
  • Validation errors are announced and linked to all four inputs.
  • Apply and preset buttons support keyboard activation and visible focus.

Manifest entry

<TimeRange value={range} onValueChange={setRange} min={windowStart} max={windowEnd} presets={[{ id: "all", label: "Full window", value: { start: windowStart, end: windowEnd } }]} />
View agent manifest
{
  "description": "Controlled UTC range with separate native date and time fields, OPERATOR Calendar/Clock icons, validated drafts, an Apply action, and optional presets. One line under the fields gives the draft range in 24-hour UTC with milliseconds, and an edit not yet applied is said so.",
  "props": {
    "value": {
      "type": "node",
      "required": true,
      "description": "TimeRangeValue: { start: number; end: number }, Unix epoch milliseconds. Start must precede end; dates must be in years 0001–9999."
    },
    "onValueChange": {
      "type": "function",
      "required": true,
      "description": "(value: TimeRangeValue) => void. Only called on Apply, Enter or a valid preset; never for invalid drafts."
    },
    "onDraftValidityChange": {
      "type": "function",
      "description": "(valid: boolean, details: { pending: boolean }) => void. Reports on mount and on every change whether the range in the fields can be used as it stands; valid is false while they hold an error or an edit not yet applied (pending: true). Connect it to Review and Save, as with DateRangePicker."
    },
    "presets": {
      "type": "array",
      "items": {
        "id": "string (required, unique)",
        "label": "string (required)",
        "value": "TimeRangeValue (required)"
      },
      "description": "Readonly TimeRangePreset array. Invalid or out-of-bounds presets are disabled."
    },
    "min": {
      "type": "number",
      "description": "Inclusive minimum epoch milliseconds. Invalid dates or conflicting bounds prevent commits."
    },
    "max": {
      "type": "number",
      "description": "Inclusive maximum epoch milliseconds."
    },
    "disabled": {
      "type": "boolean",
      "default": false
    },
    "label": {
      "type": "string",
      "default": "Time range",
      "description": "Accessible name of the range group; each input also has a visible UTC label."
    }
  },
  "composable_with": [
    "EventTimeline",
    "Chart",
    "DataGrid"
  ],
  "never_inside": [
    "Button"
  ],
  "example": "<TimeRange value={range} onValueChange={setRange} min={windowStart} max={windowEnd} presets={[{ id: \"all\", label: \"Full window\", value: { start: windowStart, end: windowEnd } }]} />"
}

On this page