HextaUI

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

Date picker

Vercel UI SDK üzerinde, tarihi kendi dilinde yazıp ya da seçerek girilen; aralık, hazır seçim ve ISO değerleri sunan bir tarih seçici.

Bağımlılıklar
  • @tabler/icons-react
  • @ui-sdk/core
  • @ui-sdk/react
MM/DD/YYYY
import {
  DatePicker,
  DatePickerClear,
  DatePickerContent,
  DatePickerControl,
  DatePickerHint,
  DatePickerInput,
  DatePickerTrigger,
} from "@/components/ui/ui-sdk-date-picker"

function UiSdkDatePickerDemo() {
  return (
    <DatePicker defaultValue="2026-11-20" className="max-w-56">
      <DatePickerControl>
        <DatePickerInput aria-label="Due date" />
        <DatePickerClear />
        <DatePickerTrigger />
      </DatePickerControl>
      <DatePickerHint />
      <DatePickerContent />
    </DatePicker>
  )
}

export { UiSdkDatePickerDemo }
pnpm dlx shadcn@latest add https://hextaui.com/r/ui-sdk-date-picker.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 {
  DatePicker,
  DatePickerContent,
  DatePickerControl,
  DatePickerHint,
  DatePickerInput,
  DatePickerTrigger,
} from "@/components/ui/ui-sdk-date-picker"
<DatePicker defaultValue="2026-11-20">
  <DatePickerControl>
    <DatePickerInput aria-label="Due date" />
    <DatePickerTrigger />
  </DatePickerControl>
  <DatePickerHint />
  <DatePickerContent />
</DatePicker>

Değerler 2026-11-20 gibi saat ve saat dilimi içermeyen ISO tarih dizeleridir, bu yüzden bir tarih kütüphanesine gerek yoktur. Kişiler 11/20/2026 veya 20.11.2026 gibi kendi tarih sıralarıyla yazar; alan, Enter’a basıldığında veya alandan çıkıldığında tarihi biçimlendirir. Çocuksuz DatePickerContent stilli bir takvim gösterir.

DatePicker
├── DatePickerControl
│   ├── DatePickerInput
│   ├── DatePickerSeparator
│   ├── DatePickerClear
│   └── DatePickerTrigger
├── DatePickerHint
└── DatePickerContent
    ├── DatePickerPreset
    └── DatePickerCalendar
        ├── CalendarPrevious
        ├── CalendarHeading
        ├── CalendarNext
        └── CalendarGrid
            ├── CalendarWeekdays
            │   └── CalendarWeekday
            └── CalendarWeeks
                └── CalendarDay

mode="range" ile end içeren ikinci bir input ekleyin. Takvim ilk tarihten sonra açık kalır, ikinciden sonra kapanır. months={2} iki ayı yan yana, küçük ekranlarda alt alta gösterir.

import {
  DatePicker,
  DatePickerCalendar,
  DatePickerContent,
  DatePickerControl,
  DatePickerInput,
  DatePickerSeparator,
  DatePickerTrigger,
} from "@/components/ui/ui-sdk-date-picker"

function UiSdkDatePickerRange() {
  return (
    <DatePicker
      mode="range"
      months={2}
      pageBy="page"
      defaultValue={["2026-11-18", "2026-11-24"]}
      className="max-w-72"
    >
      <DatePickerControl>
        <DatePickerInput aria-label="Check-in" />
        <DatePickerSeparator />
        <DatePickerInput end aria-label="Check-out" />
        <DatePickerTrigger />
      </DatePickerControl>
      <DatePickerContent>
        <DatePickerCalendar months={2} />
      </DatePickerContent>
    </DatePicker>
  )
}

export { UiSdkDatePickerRange }

Bir DatePickerPreset kendi value değerini seçer ve popup’ı kapatır. Değeri seçili olduğu sürece basılı görünür.

"use client"

import * as React from "react"

import {
  DatePicker,
  DatePickerCalendar,
  DatePickerContent,
  DatePickerControl,
  DatePickerInput,
  DatePickerPreset,
  DatePickerSeparator,
  DatePickerTrigger,
} from "@/components/ui/ui-sdk-date-picker"

function isoDate(date: Date) {
  const month = String(date.getMonth() + 1).padStart(2, "0")
  const day = String(date.getDate()).padStart(2, "0")
  return `${date.getFullYear()}-${month}-${day}`
}

function daysAgo(days: number) {
  const date = new Date()
  date.setDate(date.getDate() - days)
  return isoDate(date)
}

function UiSdkDatePickerPresets() {
  const [today, setToday] = React.useState<string | null>(null)

  React.useEffect(() => {
    setToday(isoDate(new Date()))
  }, [])

  const presets = today
    ? [
        { label: "Today", value: [today, today] as [string, string] },
        {
          label: "Last 7 days",
          value: [daysAgo(6), today] as [string, string],
        },
        {
          label: "Last 30 days",
          value: [daysAgo(29), today] as [string, string],
        },
        {
          label: "Last 90 days",
          value: [daysAgo(89), today] as [string, string],
        },
      ]
    : []

  return (
    <DatePicker mode="range" className="max-w-72">
      <DatePickerControl>
        <DatePickerInput aria-label="From" />
        <DatePickerSeparator />
        <DatePickerInput end aria-label="To" />
        <DatePickerTrigger />
      </DatePickerControl>
      <DatePickerContent>
        <div className="flex flex-wrap gap-0.5 border-b pb-3 sm:w-32 sm:flex-col sm:flex-nowrap sm:border-e sm:border-b-0 sm:pe-3 sm:pb-0">
          {presets.map((preset) => (
            <DatePickerPreset key={preset.label} value={preset.value}>
              {preset.label}
            </DatePickerPreset>
          ))}
        </div>
        <DatePickerCalendar />
      </DatePickerContent>
    </DatePicker>
  )
}

export { UiSdkDatePickerPresets }

min, max ve unavailable hem yazarken hem seçerken geçerlidir. Burada hafta sonları ve iki tatil günü seçilemez; yazılan biri geçersiz olarak işaretlenir.

import {
  DatePicker,
  DatePickerContent,
  DatePickerControl,
  DatePickerHint,
  DatePickerInput,
  DatePickerTrigger,
} from "@/components/ui/ui-sdk-date-picker"

function UiSdkDatePickerLimits() {
  return (
    <DatePicker
      min="2026-11-02"
      max="2026-12-18"
      unavailable={[{ weekday: [0, 6] }, "2026-11-26", "2026-11-27"]}
      defaultMonth="2026-11"
      className="max-w-56"
    >
      <DatePickerControl>
        <DatePickerInput aria-label="Delivery date" />
        <DatePickerTrigger />
      </DatePickerControl>
      <DatePickerHint />
      <DatePickerContent />
    </DatePicker>
  )
}

export { UiSdkDatePickerLimits }

locale yazma biçimini, ipucunu ve takvimdeki adları belirler. Verilmezse seçici sayfanın lang değerini okur. Düğmelerin adları İngilizcedir; çevirmek için aria-label verin.

import {
  DatePicker,
  DatePickerContent,
  DatePickerControl,
  DatePickerHint,
  DatePickerInput,
  DatePickerTrigger,
} from "@/components/ui/ui-sdk-date-picker"

function UiSdkDatePickerLocale() {
  return (
    <DatePicker locale="de" defaultValue="2026-12-03" className="max-w-56">
      <DatePickerControl>
        <DatePickerInput aria-label="Lieferdatum" />
        <DatePickerTrigger aria-label="Datum wählen" />
      </DatePickerControl>
      <DatePickerHint />
      <DatePickerContent aria-label="Datum wählen" />
    </DatePicker>
  )
}

export { UiSdkDatePickerLocale }

Bir name ile tarih ISO dizesi olarak gönderilir. required boş gönderimi engeller, tarih olmayan metin de engeller ve reset defaultValue değerine döner.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import {
  DatePicker,
  DatePickerContent,
  DatePickerControl,
  DatePickerHint,
  DatePickerInput,
  DatePickerTrigger,
} from "@/components/ui/ui-sdk-date-picker"

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

  return (
    <form
      className="flex w-full max-w-56 flex-col gap-3"
      onSubmit={(event) => {
        event.preventDefault()
        const data = new FormData(event.currentTarget)
        setSubmitted(String(data.get("start")))
      }}
    >
      <DatePicker name="start" required>
        <DatePickerControl>
          <DatePickerInput aria-label="Start date" />
          <DatePickerTrigger />
        </DatePickerControl>
        <DatePickerHint />
        <DatePickerContent />
      </DatePicker>
      <div className="flex items-center gap-3">
        <Button type="submit" size="sm">
          Submit
        </Button>
        <Button type="reset" size="sm" variant="ghost">
          Reset
        </Button>
      </div>
      <p className="text-sm text-muted-foreground tabular-nums">
        {submitted ? `Submitted ${submitted}` : "Nothing submitted yet."}
      </p>
    </form>
  )
}

export { UiSdkDatePickerForm }

createDatePickerController() ile oluşturulan bir controller tarihi ayarlar veya takvimi her yerden açar; onValueChange her değişikliği bildirir. Takvimin controller’ın seçtiği aya geçebilmesi için burada value vermeyin.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import {
  createDatePickerController,
  DatePicker,
  DatePickerContent,
  DatePickerControl,
  DatePickerInput,
  DatePickerTrigger,
  type DatePickerValue,
} from "@/components/ui/ui-sdk-date-picker"

function UiSdkDatePickerController() {
  const [picker] = React.useState(createDatePickerController)
  const [value, setValue] = React.useState<DatePickerValue>(null)

  return (
    <div className="flex w-full max-w-56 flex-col gap-3">
      <DatePicker controller={picker} onValueChange={setValue}>
        <DatePickerControl>
          <DatePickerInput aria-label="Party date" />
          <DatePickerTrigger />
        </DatePickerControl>
        <DatePickerContent />
      </DatePicker>
      <div className="flex gap-2">
        <Button
          variant="outline"
          size="sm"
          onClick={() => picker.setValue("2026-12-25")}
        >
          Choose Christmas
        </Button>
        <Button variant="ghost" size="sm" onClick={() => picker.open()}>
          Open
        </Button>
      </div>
      <p className="text-sm text-muted-foreground tabular-nums">
        {typeof value === "string" ? value : "No date"}
      </p>
    </div>
  )
}

export { UiSdkDatePickerController }

disabled yazmayı ve açmayı durdurur. readOnly takvimi bakmak için yine açar ama hiçbir şey değişemez.

import {
  DatePicker,
  DatePickerContent,
  DatePickerControl,
  DatePickerInput,
  DatePickerTrigger,
} from "@/components/ui/ui-sdk-date-picker"

function UiSdkDatePickerDisabled() {
  return (
    <div className="flex w-full max-w-56 flex-col gap-3">
      <DatePicker defaultValue="2026-11-20" disabled>
        <DatePickerControl>
          <DatePickerInput aria-label="Disabled date" />
          <DatePickerTrigger />
        </DatePickerControl>
        <DatePickerContent />
      </DatePicker>
      <DatePicker defaultValue="2026-11-20" readOnly>
        <DatePickerControl>
          <DatePickerInput aria-label="Read-only date" />
          <DatePickerTrigger />
        </DatePickerControl>
        <DatePickerContent />
      </DatePicker>
    </div>
  )
}

export { UiSdkDatePickerDisabled }

dir=rtl içinde Arapça bir yerel ayarla alan, oklar ve takvim sağdan başlar.

import {
  DatePicker,
  DatePickerContent,
  DatePickerControl,
  DatePickerInput,
  DatePickerTrigger,
} from "@/components/ui/ui-sdk-date-picker"

function UiSdkDatePickerRtl() {
  return (
    <div dir="rtl" className="w-full max-w-56">
      <DatePicker locale="ar" defaultValue="2026-11-20">
        <DatePickerControl>
          <DatePickerInput aria-label="تاريخ الاستحقاق" />
          <DatePickerTrigger aria-label="اختر التاريخ" />
        </DatePickerControl>
        <DatePickerContent aria-label="اختر التاريخ" />
      </DatePicker>
    </div>
  )
}

export { UiSdkDatePickerRtl }
TuşAction
EnterInput’ta yazılan tarihi okur. Bir günün üzerinde o günü seçer.
←→↑↓Günler arasında, yukarı ve aşağıda bir hafta ilerler.
Page UpPage DownBir ay geri veya ileri gider.
HomeEndHaftanın başına veya sonuna geçer.
EscBitmemiş bir aralığı iptal eder, yoksa takvimi kapatır.

Takvim, her biri “Friday, November 20, 2026” gibi tam adıyla anılan günlerden oluşan bir ızgarayla diyalog olarak açılır. İpucu input’u tanımlar, böylece ekran okuyucular yazılacak biçimi duyar. Tarih olmayan bir metin aria-invalid ayarlar ve eski değeri korur; kullanılamayan günler odaklanabilir kalır, böylece klavye kullananlar onları yine de duyar.

Tetikleyici, popup ve oklar İngilizce adlara sahiptir. Çevirmek için her birine aria-label verin. Input’lar dokunmatik ekranlarda iOS yakınlaştırmasın diye 16px yazı kullanır ve popup yalnızca harekete izin verildiğinde ölçeklenerek açılı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. DatePickerControl, DatePickerSeparator ve DatePickerCalendar HextaUI düzen parçalarıdır.

PropTürVarsayılan
mode
"single" | "range""single"
value
string | [string, string] | null–
defaultValue
string | [string, string] | null–
onValueChange
(value, details) => void–
min
string–
max
string–
unavailableISO tarihleri, { from, to }, { weekday }, { before }, { after } veya bir fonksiyon.
DateMatchers–
months
number1
pageBy
"month" | "page""month"
locale
string–
weekStartsOn
number–
minDays
number–
maxDays
number–
closeOnSelect
booleantrue
disabled
booleanfalse
readOnly
booleanfalse
name
string–
startName
string–
endName
string–
required
booleanfalse
open
boolean–
onOpenChange
(open, details) => void–
controllercreateDatePickerController() ile oluşturulur.
DatePickerController–
ÖznitelikAçıklama
data-slot="date-picker"CSS’te tarih seçiciyi hedefler.
data-openAçıkken bulunur.
data-invalidBir input tarih olmayan bir metin içerdiği sürece bulunur.
data-disabledDevre dışıyken bulunur.
data-readonlySalt okunur olduğunda bulunur.
PropTürVarsayılan
endOnu bir aralığın sonu yapar.
booleanfalse
PropTürVarsayılan
childrenVarsayılan olarak bir takvim simgesi.
ReactNode–
aria-label
string"Choose date"
PropTürVarsayılan
childrenVarsayılan olarak Clear adlı bir X simgesi. Temizlenecek bir şey yokken gizlenir.
ReactNode–
PropTürVarsayılan
childrenVarsayılan olarak bir DatePickerCalendar.
ReactNode–
align
Align"start"
sideOffset
number6
collisionPadding
number8
ÖznitelikAçıklama
data-slot="date-picker-content"Popup’ı CSS’te hedeflemek için.
--cell-sizeHer günün boyutu; dokunmatik ekranlarda daha büyük.
PropTürVarsayılan
monthsYan yana kaç ızgara gösterileceği.
number1
PropTürVarsayılan
value
string | [string, string]–
render
ReactElement | (props, state) => ReactElement–
ÖznitelikAçıklama
data-slot="calendar-day"CSS’te bir günü hedefler.
data-todayBugünde bulunur.
data-range-startBir aralığın başladığı yerde bulunur.
data-range-endBir aralığın bittiği yerde bulunur.
data-unavailableSeçilemeyen bir günde bulunur.
data-outsideSonraki veya önceki ayın bir gününde bulunur.