HextaUI

BetaVercel UI SDK 0.1.0-beta.2 üzerine kurulu. API’si değişebilir.

Date input

Vercel UI SDK üzerinde yerel ayarın sırasıyla parça parça yazılan bir tarih alanı; isteğe bağlı saat, en küçük ve en büyük değer, kullanılamayan günler ve ISO değeri.

Bağımlılıklar
  • @ui-sdk/core
  • @ui-sdk/react
import { IconCalendar } from "@tabler/icons-react"

import { Label } from "@/components/ui/label"
import { DateInput, DateInputSegments } from "@/components/ui/ui-sdk-date-input"

function UiSdkDateInputDemo() {
  return (
    <div className="flex w-full max-w-44 flex-col gap-2">
      <Label id="birthday">Birthday</Label>
      <DateInput aria-labelledby="birthday" name="birthday">
        <IconCalendar aria-hidden="true" />
        <DateInputSegments />
      </DateInput>
    </div>
  )
}

export { UiSdkDateInputDemo }
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-date-input.json

Bileşeni, HextaUI tema token'larını ve bileşenin bağımlı olduğu tüm HextaUI bileşenlerini ekler.

UI SDK, ui-sdk adlı bir cascade katmanında kendi CSS’ini biraz ekler. Sınıflarınızın kazanması için bu katmanı genel stil dosyanızın en üstünde, Tailwind import’unun üzerinde tanımlayın.

@layer ui-sdk;

@import "tailwindcss";
import { DateInput } from "@/components/ui/ui-sdk-date-input"
<Label id="start-date">Start date</Label>
<DateInput aria-labelledby="start-date" defaultValue="2026-11-02" />

Doğum günü gibi ezbere bilinen tarihler için bir tarih alanı kullanın. Değer "2026-11-02" gibi bir ISO tarihidir ve her parça bir şey içerene kadar null kalır. Her parça yazdıkça dolar ve ilerler, gün kendi ayının içinde tutulur ve tam bir tarih herhangi bir parçaya yapıştırılabilir. Takvimden seçmek için Date Picker'ı kullanın.

Alan bir gruptur, bu yüzden onu aria-labelledby veya aria-label ile adlandırın. Kutunun herhangi bir yerine tıklamak en yakın parçaya odaklanır.

DateInput
└── DateInputSegments
    └── DateInputSegment

DateInput parçalarını kendisi çizer. Yanlarına bir simge ya da başka içerik koymak için DateInputSegments öğesini kendiniz ekleyin.

granularity değerini "hour", "minute" veya "second" yapmak saati ekler ve değer "2026-11-02T14:30" gibi yerel bir tarih ve saate dönüşür.

import { Label } from "@/components/ui/label"
import { DateInput } from "@/components/ui/ui-sdk-date-input"

function UiSdkDateInputDateTime() {
  return (
    <div className="flex w-full max-w-60 flex-col gap-2">
      <Label id="departure">Departure</Label>
      <DateInput
        aria-labelledby="departure"
        granularity="minute"
        defaultValue="2026-11-02T14:30"
        locale="en-US"
      />
    </div>
  )
}

export { UiSdkDateInputDateTime }

min öncesindeki veya max sonrasındaki bir tarih alanı geçersiz işaretler ve formu gönderilmez.

"use client"

import * as React from "react"

import { Label } from "@/components/ui/label"
import { DateInput } from "@/components/ui/ui-sdk-date-input"

const min = "2026-01-01"
const max = "2026-12-31"

function UiSdkDateInputMinMax() {
  const [date, setDate] = React.useState<string | null>("2026-06-15")
  const outside = date !== null && (date < min || date > max)

  return (
    <div className="flex w-full max-w-44 flex-col gap-2">
      <Label id="check-in">Check-in</Label>
      <DateInput
        aria-labelledby="check-in"
        aria-describedby="check-in-message"
        min={min}
        max={max}
        defaultValue="2026-06-15"
        onValueChange={(value) => setDate(value)}
      />
      <p
        id="check-in-message"
        className={
          outside
            ? "m-0 text-xs text-destructive"
            : "m-0 text-xs text-muted-foreground"
        }
      >
        {outside ? "Pick a day in 2026." : "Any day in 2026."}
      </p>
    </div>
  )
}

export { UiSdkDateInputMinMax }

unavailable ISO tarihleri, { from, to } aralıkları, hafta günleri veya bir fonksiyon alır; bunlara denk gelen tarih geçersizdir.

"use client"

import * as React from "react"

import { Label } from "@/components/ui/label"
import { DateInput } from "@/components/ui/ui-sdk-date-input"

function isWeekend(date: string) {
  const day = new Date(`${date}T12:00`).getDay()
  return day === 0 || day === 6
}

function UiSdkDateInputUnavailable() {
  const [date, setDate] = React.useState<string | null>("2026-11-02")
  const weekend = date !== null && isWeekend(date)

  return (
    <div className="flex w-full max-w-44 flex-col gap-2">
      <Label id="delivery-date">Delivery date</Label>
      <DateInput
        aria-labelledby="delivery-date"
        aria-describedby="delivery-date-message"
        defaultValue="2026-11-02"
        unavailable={{ weekday: [0, 6] }}
        onValueChange={(value) => setDate(value)}
      />
      <p
        id="delivery-date-message"
        className={
          weekend
            ? "m-0 text-xs text-destructive"
            : "m-0 text-xs text-muted-foreground"
        }
      >
        {weekend
          ? "We don’t deliver on weekends."
          : "We deliver Monday to Friday."}
      </p>
    </div>
  )
}

export { UiSdkDateInputUnavailable }

locale sırayı ve ayırıcıları belirler. Rakamlar her zaman 0-9, takvim her zaman Gregoryen'dir; böylece değer her yerde aynı tarihi ifade eder.

import { Label } from "@/components/ui/label"
import { DateInput } from "@/components/ui/ui-sdk-date-input"

const locales = [
  { locale: "en-GB", label: "Date (en-GB)" },
  { locale: "de-DE", label: "Datum (de-DE)" },
  { locale: "ja-JP", label: "日付 (ja-JP)" },
]

function UiSdkDateInputLocale() {
  return (
    <div className="flex w-full max-w-44 flex-col gap-4">
      {locales.map(({ locale, label }) => (
        <div key={locale} lang={locale} className="flex flex-col gap-2">
          <Label id={`date-${locale}`}>{label}</Label>
          <DateInput
            aria-labelledby={`date-${locale}`}
            locale={locale}
            defaultValue="2026-11-02"
          />
        </div>
      ))}
    </div>
  )
}

export { UiSdkDateInputLocale }

Gizli bir giriş ISO tarihini name altında gönderir, burada bir Time Input'un yanında. required boş veya yarım yazılmış bir tarihi durdurur, sıfırlama varsayılanı geri getirir.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { Label } from "@/components/ui/label"
import { DateInput } from "@/components/ui/ui-sdk-date-input"
import { TimeInput } from "@/components/ui/ui-sdk-time-input"

function UiSdkDateInputForm() {
  const [submitted, setSubmitted] = React.useState<string | null>(null)

  return (
    <form
      className="flex w-full max-w-72 flex-col gap-3"
      onSubmit={(event) => {
        event.preventDefault()
        const data = new FormData(event.currentTarget)
        setSubmitted(`${data.get("date")} at ${data.get("time")}`)
      }}
    >
      <div className="grid grid-cols-[1fr_auto] gap-2">
        <div className="flex min-w-0 flex-col gap-2">
          <Label id="booking-date">Date</Label>
          <DateInput
            aria-labelledby="booking-date"
            name="date"
            defaultValue="2026-11-02"
            required
          />
        </div>
        <div className="flex flex-col gap-2">
          <Label id="booking-time">Time</Label>
          <TimeInput
            aria-labelledby="booking-time"
            name="time"
            defaultValue="09:30"
            required
          />
        </div>
      </div>
      <div className="flex items-center gap-3">
        <Button type="submit" size="sm">
          Book
        </Button>
        <Button type="reset" size="sm" variant="ghost">
          Reset
        </Button>
      </div>
      <p className="m-0 text-sm text-muted-foreground tabular-nums">
        {submitted ? `Submitted ${submitted}` : "Nothing submitted yet."}
      </p>
    </form>
  )
}

export { UiSdkDateInputForm }

createDateInputController() alanı her yerden ayarlar, temizler veya odaklar. Bir parçaya "year" gibi birimiyle odaklanın.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { Label } from "@/components/ui/label"
import {
  DateInput,
  createDateInputController,
} from "@/components/ui/ui-sdk-date-input"

function UiSdkDateInputController() {
  const [controller] = React.useState(createDateInputController)

  return (
    <div className="flex w-full max-w-60 flex-col gap-2">
      <Label id="publish-on">Publish on</Label>
      <DateInput aria-labelledby="publish-on" controller={controller} />
      <div className="flex items-center gap-2 pt-1">
        <Button
          size="sm"
          variant="outline"
          onClick={() => controller.setValue("2026-12-25")}
        >
          Christmas
        </Button>
        <Button
          size="sm"
          variant="ghost"
          onClick={() => controller.focus("year")}
        >
          Edit year
        </Button>
        <Button size="sm" variant="ghost" onClick={() => controller.clear()}>
          Clear
        </Button>
      </div>
    </div>
  )
}

export { UiSdkDateInputController }

Devre dışı bir alan odakta atlanır ve gönderilmez.

import { Label } from "@/components/ui/label"
import { DateInput } from "@/components/ui/ui-sdk-date-input"

function UiSdkDateInputDisabled() {
  return (
    <div className="flex w-full max-w-44 flex-col gap-2">
      <Label id="start-date-disabled">Start date</Label>
      <DateInput
        aria-labelledby="start-date-disabled"
        defaultValue="2026-11-02"
        disabled
      />
    </div>
  )
}

export { UiSdkDateInputDisabled }

Salt okunur bir alan odak alır ve gönderilir, ancak tuşlar ve yazma onu değiştirmez.

import { Label } from "@/components/ui/label"
import { DateInput } from "@/components/ui/ui-sdk-date-input"

function UiSdkDateInputReadOnly() {
  return (
    <div className="flex w-full max-w-44 flex-col gap-2">
      <Label id="signed-on">Signed on</Label>
      <DateInput
        aria-labelledby="signed-on"
        defaultValue="2026-11-02"
        readOnly
      />
    </div>
  )
}

export { UiSdkDateInputReadOnly }

Parçalar yerel ayarın sırasını korur ve ok tuşları ekrandaki sıralarını izler.

import { IconCalendar } from "@tabler/icons-react"

import { Label } from "@/components/ui/label"
import { DateInput, DateInputSegments } from "@/components/ui/ui-sdk-date-input"

function UiSdkDateInputRtl() {
  return (
    <div dir="rtl" lang="ar" className="flex w-full max-w-44 flex-col gap-2">
      <Label id="rtl-date">تاريخ البدء</Label>
      <DateInput
        aria-labelledby="rtl-date"
        locale="ar-EG"
        defaultValue="2026-11-02"
      >
        <IconCalendar aria-hidden="true" />
        <DateInputSegments />
      </DateInput>
    </div>
  )
}

export { UiSdkDateInputRtl }
TuşAction
0–9Parçayı doldurur, sonra bir sonrakine geçer.
/.Sonraki parçaya geçer.
↑↓Parçayı birer birer değiştirir ve başa döner. Boş bir parça bugünden başlar.
PageUpPageDownDaha büyük adımlarla değiştirir: yıl 5, ay 3, gün 7.
HomeEndParçanın ilk veya son değerine gider.
←→Önceki veya sonraki parçaya geçer.
BackspaceSon rakamı siler, sonra parçayı boşaltır, ardından geri gider.
EnterFormu yazılanla gönderir.

Kök bir gruptur. Her parça, “month” gibi birimiyle adlandırılmış, değeri ve aralığı olan bir spinbutton'dır; boş bir parça “Empty” olarak okunur. Parçalar arasındaki metin ekran okuyuculardan gizlenir.

Parçalar gerçek girişlerdir; bu yüzden telefonlar sayı tuş takımı gösterir ve sayfanın betiği çalışmadan yazılabilir. Telefonlar yakınlaştırmasın diye dokunmatik ekranlarda 16px'e büyürler ve odaktaki parça imleç yerine vurgulanır.

Her parça aynı adlı UI SDK parçasını sarar ve render ile parçanın durumuna bağlı bir fonksiyon olabilen className dahil tüm prop’larını kabul eder.

PropTürVarsayılan
value
string | null–
defaultValue
string | null–
onValueChangeHer parça bir şey içerdiğinde, bir parça boşaltıldığında da null ile çalışır.
(value: string | null, details) => void–
granularity
"day" | "hour" | "minute" | "second""day"
hourCycleVarsayılan olarak yerel ayarın saat düzeni.
12 | 24–
min
string–
max
string–
unavailableISO tarihleri, { from, to } aralıkları, { weekday } veya bir fonksiyon.
DateMatchers–
localeVarsayılan olarak sayfanın dili.
string–
invalid
booleanfalse
disabled
booleanfalse
readOnly
booleanfalse
required
booleanfalse
name
string–
form
string–
controllercreateDateInputController() ile oluşturulur.
DateInputController–
childrenVarsayılan olarak DateInputSegments.
ReactNode | (state) => ReactNode–
render
ReactElement | (props, state) => ReactElement–
ÖznitelikAçıklama
data-slot="date-input"CSS'te tarih alanını hedeflemek için.
data-invalidTarih min ile max dışında olduğunda, kullanılamadığında veya invalid ayarlandığında bulunur.
data-emptyTüm parçalar boşken bulunur.
data-disabledDevre dışıyken bulunur.
data-readonlySalt okunur olduğunda bulunur.
data-requiredZorunlu olduğunda bulunur.

Her parça için yerel ayarın sırasıyla, aralarındaki metinle birlikte bir DateInputSegment çizer.

PropTürVarsayılan
segmentKök durumundaki segments öğelerinden biri.
DateInputSegmentData–
render
ReactElement | (props, state) => ReactElement–
ÖznitelikAçıklama
data-slot="date-input-segment"CSS'te bir parçayı hedeflemek için.
data-typeyear, month, day, hour, minute, second, dayPeriod veya parçalar arasındaki metin için literal.
data-emptyParça boşken bulunur.