Skip to content

Date Field

SDateField is a segmented date input: separate editable parts (month, day, year) instead of free text. This rules out ambiguous formats and parsing errors, works from the keyboard (arrows increment, typing digits fills the segment), and is localized. The value is a DateValue from @internationalized/date; the field is built on SFormField (label, hint, error message).

Value and shallowRef

Keep the date in a shallowRef, not a ref. A regular ref unwraps the value through UnwrapRef: the CalendarDate class is turned into a structural type, the private field is lost, and vue-tsc no longer recognizes it as a DateValueTS2322: Type '{ readonly calendar: … }' is not assignable to type 'DateValue'. Narrowing the ref itself (ref<CalendarDate>) does not help: it is unwrapped anyway. shallowRef stores the value as is, and a date does not need deep reactivity anyway, since it is replaced as a whole.

Basic usage

Empty field, hint, and error message

States

disabled locks the field, readonly prevents changing the segments, invalid marks the field as invalid (red border), required adds * to the label.

Sizes

The size prop controls the field height: sm (28px), md (36px, the default), and lg (44px).

Granularity

granularity sets the smallest editable segment. The default is day for a date; for a value with time (CalendarDateTime) you can go down to minute or second.

prepend / append slots

The prepend and append slots insert content inside the field frame, for example a calendar icon.

Leaving the field

The field emits focus and blur events, like SInput. Moving between segments does not count as leaving the field — see the details and a validation example on the SDatePicker page.

API

Props

NameTypeDefaultDescription
idstringundefinedField id. Generated automatically when not set (SSR-safe).
labelstringundefinedField label.
floating-labelbooleantrueFloating label: the label sits inside the border, looks like a placeholder at rest and floats up to the top edge on focus or when filled. On by default; false renders a regular label above the field. The label size is fixed and does not depend on size.
hintstringundefinedHint below the field.
errorstringundefinedError message. When set, the field is marked invalid.
size"md" | "sm" | "lg""md"Field size: sm (32px), md (40px) or lg (48px).
disabledbooleanfalseDisables input and makes the field inactive.
readonlybooleanfalseRead-only: the segments cannot be changed.
requiredbooleanfalseMarks the field as required: adds * to the label.
invalidbooleanfalseExplicitly marks the field invalid (in addition to error).
squarebooleanundefinedSquare corners: removes the field border radius (rounded by default).
localestringundefinedFormatting locale (for example en-GB). Derived from the library locale by default (ConfigProvider/installLocale, in Nuxt the locale option): enen-US.
granularity | "day" | "hour" | "minute" | "second"undefinedGranularity: the smallest segment to display (day/hour/minute/second). Defaults to day for CalendarDate and minute for dates with time.
min-value | CalendarDate | CalendarDateTime | ZonedDateTimeundefinedMinimum allowed date.
max-value | CalendarDate | CalendarDateTime | ZonedDateTimeundefinedMaximum allowed date.
model-value | CalendarDate | CalendarDateTime | ZonedDateTimeundefinedField value (DateValue from @internationalized/date). Two-way bound via v-model.

Events

NameSignatureDescription
update:modelValue( value: | CalendarDate | CalendarDateTime | ZonedDateTime | undefined ) => voidEmitted when modelValue changes. Used for two-way binding (v-model).
focus(event: FocusEvent) => voidFocus entered the field. Moving between segments does not count.
blur(event: FocusEvent) => voidFocus left the field. Moving between segments does not count.

Slots

NameDescription
prependContent at the start of the field, inside the border (icon, button).
appendContent at the end of the field, inside the border (icon, button).