Inspector Date

About this component

Inspector Date

Settings row for a date, a time, or both: the row reads the value the way anyone would write it down and opens a real month calendar, while a time on its own keeps the platform's own field inline, since a time has no month to show.

Usage

The import and the props worth knowing about, in one place.

import { InspectorDate } from "@/components/beste/component/inspector-date";

// Uncontrolled. The value is the format the platform uses, which is also what a
// form submits and what new Date() parses.
<InspectorDate label="Publish on" defaultValue="2026-08-01" />

// Controlled
<InspectorDate label="Publish on" value={date} onValueChange={setDate} />

// A time, or both at once
<InspectorDate label="Opens at" mode="time" value={time} onValueChange={setTime} />
<InspectorDate label="Starts" mode="datetime" value={start} onValueChange={setStart} />

<InspectorDate
  label="Deadline"
  icon={CalendarClockIcon}  // optional leading icon; the mode brings its own
  tone="outline"            // "muted" (default) | "outline" | "ghost"
  size="sm"                 // "sm" | "default" | "lg"
  mode="datetime"
  min="2026-01-01T00:00"    // in the same format as the value
  max="2026-12-31T23:59"
  step={900}                // granularity in seconds
  name="deadline"           // takes part in a form
  required
  value={deadline}
  onValueChange={setDeadline}
/>

// The row's reading is deterministic on purpose, so the server and the browser
// agree on it. Bring your own locale where it can only run in one place:
<InspectorDate
  label="Publish on"
  value={date}
  onValueChange={setDate}
  formatValue={(iso) => new Date(iso).toLocaleDateString("tr-TR", { dateStyle: "long" })}
/>

// A clear button inside the panel, and a week that starts on Monday
<InspectorDate label="Publish on" clearable weekStartsOn={1} value={date} onValueChange={setDate} />

// The value is what a form submits, what `new Date()` parses, and what comes back
// out, and the calendar never turns it into anything else. Parsing is deliberately not
// `new Date("2026-08-01")`: a bare date string is read as UTC midnight, which is the
// evening before anywhere west of Greenwich.

Playground

Turn the props on the right; the snippet under them is what you would write to get what you see.

Usage
import { InspectorDate } from "@/components/beste/component/inspector-date";

<InspectorDate
  label="Publish on"
  className="w-72"
  defaultValue="2026-08-01"
  clearable
/>

Props

Read from the component's own type, so this cannot drift from what it accepts.

PropTypeDefaultDescription
label*stringLabel rendered on the left, inside the row.
iconLucideIconOptional leading icon shown before the label. Defaults to the mode's own.
valuestringControlled value, in the format the platform uses: `2026-07-25` for a date, `14:30` for a time, `2026-07-25T14:30` for both. That is also what a form submits and what `new Date()` parses, so nothing has to be converted twice.
defaultValuestringInitial value in uncontrolled mode.
onValueChange(value: string) => voidFires whenever a day is picked, a time typed, or the value cleared.
onOpenChange(open: boolean) => voidFires when the calendar opens or closes.
mode"date" | "time" | "datetime""date"What is being picked.
minstringEarliest allowed value, in the same format.
maxstringLatest allowed value, in the same format.
stepnumberGranularity in seconds, for the time half.
formatValue(value: string) => stringHow the value reads on the row. Use it to bring your own locale, which is the one thing this cannot do for you without guessing where it is running.
emptyLabelstringWhat the row reads while there is no value.
clearablebooleanOffer a button that clears the value.
weekStartsOn0 | 1 | 2 | 3 | 4 | 5 | 6Which day starts the week: 0 is Sunday, 1 is Monday.
disabledbooleanBlock interaction and dim the row.
readOnlybooleanShow the value but refuse edits.
tone"muted" | "outline" | "ghost""muted"Surface treatment: filled (default), hairline outline, or bare until hover.
size"sm" | "default" | "lg""default"Row height preset.
namestringName of the field, so the row can take part in a form.
idstringId of the field. One is generated when it is left out.
classNamestring
aria-labelstringAccessible name. Falls back to `label`.

More Inspector components

View all Inspector

Inspector Aspect

Settings row for a ratio: the row prints it and draws it, and opens an editor with the ratios worth a name plus both sides always editable. It is kept as two numbers rather than as their quotient, since 16:9 is what a reader recognises.

Inspector Range

Settings row for a span rather than a value: two thumbs on the row itself, the band between them filling it, and both ends of the pair read out on the right. Ticks, tones and thumb states follow inspector-slider exactly, appearing on hover.

Inspector Input

Settings row with a label on the left and a plain text field on the right, sharing the family's pill: the whole row is the label, so pressing anywhere puts the caret in the field.

px

Inspector Dimensions

Width and height on one row, with the lock between them: while it is closed, editing one scales the other by the ratio the pair had when the lock closed. Both fields are as wide as the largest number they can hold, so typing never shifts the row.

Dark Mode

Inspector Segmented

Settings row whose choices sit side by side on the right, with a marker that slides between them: the readable alternative to a switch when the two states deserve names, and the compact one to a select at three or four options.

Inspector Icon

Settings row that names the chosen icon and shows it on the right; pressing the row opens a searchable palette below it, width-matched to the row, with clearing offered at the foot of it. The icon set is passed in, so the row never bundles an icon library of its own.