HextaUI

Date picker

Tek tarihler ve aralıklar için takvimi bir popover içinde, telefonlarda ise alt sayfa olarak açan bir düğme.

import { DatePicker } from "@/components/ui/date-picker"

export function DatePickerDemo() {
  return <DatePicker />
}
pnpm dlx shadcn@latest add https://hextaui.com/r/date-picker.json

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

import { DatePicker, DateRangePicker } from "@/components/ui/date-picker"
const [date, setDate] = React.useState<Date | null>(null)

<DatePicker value={date} onValueChange={setDate} />

640px'ten dar ekranlarda takvim bir popover yerine alt sheet'te açılır; böylece günler dokunmak için yeterince büyük kalır.

Kontrollü

value ve onValueChange geçin. Temizlenen değerler null'dır. Takvim her zaman seçili tarihin ayında açılır ve bir gün seçmek onu kapatır ve odağı düğmeye geri verir.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { DatePicker } from "@/components/ui/date-picker"

function daysFromToday(days: number) {
  const date = new Date()
  date.setHours(0, 0, 0, 0)
  date.setDate(date.getDate() + days)
  return date
}

const isoDay = new Intl.DateTimeFormat("en-CA", {
  year: "numeric",
  month: "2-digit",
  day: "2-digit",
})

export function DatePickerControlled() {
  const [date, setDate] = React.useState<Date | null>(null)

  return (
    <div className="flex flex-wrap items-center justify-center gap-2">
      <DatePicker value={date} onValueChange={setDate} clearable />
      <Button variant="ghost" onClick={() => setDate(daysFromToday(0))}>
        Today
      </Button>
      <Button variant="ghost" onClick={() => setDate(daysFromToday(7))}>
        In a week
      </Button>
      <output className="text-sm text-muted-foreground tabular-nums">
        {date ? isoDay.format(date) : "null"}
      </output>
    </div>
  )
}

Aralık

<DateRangePicker /> büyük ekranlarda iki ay gösterir. İlk tıklama, bir aralık ayarlı olsa bile her zaman yeni bir aralık başlatır; ikinci tıklama onu her iki sırada da bitirir ve seçiciyi kapatır.

"use client"

import * as React from "react"
import type { DateRange } from "react-day-picker"

import { DateRangePicker } from "@/components/ui/date-picker"

const isoDay = new Intl.DateTimeFormat("en-CA", {
  year: "numeric",
  month: "2-digit",
  day: "2-digit",
})

export function DatePickerRange() {
  const [range, setRange] = React.useState<DateRange | null>(null)

  return (
    <div className="flex flex-col items-center gap-2">
      <DateRangePicker value={range} onValueChange={setRange} clearable />
      <output className="text-sm text-muted-foreground tabular-nums">
        {range?.from && range.to
          ? `${isoDay.format(range.from)} → ${isoDay.format(range.to)}`
          : "null"}
      </output>
    </div>
  )
}

Devre dışı günler

calendarProps.disabled olarak herhangi bir react-day-picker eşleştiricisi geçin. Burada yalnızca gelecekteki hafta içi günler seçilebilir.

"use client"

import * as React from "react"

import { DatePicker } from "@/components/ui/date-picker"

function tomorrow() {
  const date = new Date()
  date.setHours(0, 0, 0, 0)
  date.setDate(date.getDate() + 1)
  return date
}

export function DatePickerDisabledDays() {
  const [firstDay] = React.useState(tomorrow)

  return (
    <DatePicker
      placeholder="Delivery date"
      calendarProps={{
        disabled: [{ before: firstDay }, { dayOfWeek: [0, 6] }],
      }}
    />
  )
}

Ay ve yıl dropdown'ları

Doğum günü gibi uzak tarihler için captionLayout: "dropdown" ile birlikte bir startMonth ve endMonth ayarlayın. Trigger'ı id'sine işaret eden bir <label /> ile etiketleyin.

import { DatePicker } from "@/components/ui/date-picker"

export function DatePickerDropdowns() {
  return (
    <div className="flex flex-col gap-1.5">
      <label htmlFor="birthday" className="text-sm font-medium">
        Date of birth
      </label>
      <DatePicker
        id="birthday"
        placeholder="Select your birthday"
        calendarProps={{
          captionLayout: "dropdown",
          startMonth: new Date(1920, 0),
          endMonth: new Date(),
          disabled: { after: new Date() },
        }}
      />
    </div>
  )
}

Bir formda

name ile tek bir tarih 2026-10-14, bir aralık 2026-10-20/2026-10-24 olarak gönderilir. Boş seçiciler boş bir dize gönderir.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { DatePicker, DateRangePicker } from "@/components/ui/date-picker"

export function DatePickerForm() {
  const [submitted, setSubmitted] = React.useState<string>()

  return (
    <form
      className="flex flex-col items-start gap-3"
      onSubmit={(event) => {
        event.preventDefault()
        const data = new FormData(event.currentTarget)
        setSubmitted(JSON.stringify(Object.fromEntries(data)))
      }}
    >
      <DatePicker name="due" defaultValue={new Date(2026, 9, 14)} />
      <DateRangePicker
        name="stay"
        defaultValue={{
          from: new Date(2026, 9, 20),
          to: new Date(2026, 9, 24),
        }}
      />
      <Button type="submit">Submit</Button>
      <output className="text-sm break-all text-muted-foreground">
        {submitted ?? "Not submitted"}
      </output>
    </form>
  )
}

Devre dışı

Devre dışı bir trigger yine de bir değer gösterebilir.

import { DatePicker } from "@/components/ui/date-picker"

export function DatePickerDisabled() {
  return (
    <div className="flex flex-wrap justify-center gap-2">
      <DatePicker disabled />
      <DatePicker disabled defaultValue={new Date(2026, 0, 1)} />
    </div>
  )
}

Dar kapsayıcı

Trigger asla kapsayıcısından büyümez. Uzun etiketler sarmak yerine kısaltılır.

import { DateRangePicker } from "@/components/ui/date-picker"

export function DatePickerNarrow() {
  return (
    <div className="w-40">
      <DateRangePicker
        defaultValue={{
          from: new Date(2026, 0, 28),
          to: new Date(2026, 11, 3),
        }}
      />
    </div>
  )
}

Sheet içinde

Seçici sheet'in üstünde katmanlanır ve Escape yalnızca seçiciyi kapatır.

import { Button } from "@/components/ui/button"
import { DateRangePicker } from "@/components/ui/date-picker"
import {
  Sheet,
  SheetBody,
  SheetContent,
  SheetDescription,
  SheetHeader,
  SheetTitle,
  SheetTrigger,
} from "@/components/ui/sheet"

export function DatePickerInSheet() {
  return (
    <Sheet>
      <SheetTrigger render={<Button variant="outline" />}>
        Edit booking
      </SheetTrigger>
      <SheetContent>
        <SheetHeader>
          <SheetTitle>Edit booking</SheetTitle>
          <SheetDescription>
            The picker opens above the sheet and Escape closes only the picker.
          </SheetDescription>
        </SheetHeader>
        <SheetBody>
          <DateRangePicker />
        </SheetBody>
      </SheetContent>
    </Sheet>
  )
}

Sağdan sola

Trigger etiketi için locale ve takvim için calendarProps içinde dir: "rtl" ile bir react-day-picker locale'i geçin. Ok tuşları yönü izler.

"use client"

import { arSA } from "react-day-picker/locale"

import { DatePicker, DateRangePicker } from "@/components/ui/date-picker"

export function DatePickerRtl() {
  return (
    <div dir="rtl" className="flex flex-wrap justify-center gap-2">
      <DatePicker
        locale="ar"
        placeholder="اختر تاريخًا"
        title="اختر تاريخًا"
        clearLabel="مسح"
        clearable
        defaultValue={new Date(2026, 9, 2)}
        calendarProps={{ locale: arSA, dir: "rtl" }}
      />
      <DateRangePicker
        locale="ar"
        placeholder="اختر فترة"
        title="اختر فترة"
        calendarProps={{ locale: arSA, dir: "rtl" }}
      />
    </div>
  )
}
TuşAction
EnterSpaceTrigger üzerinde, seçiciyi açar ve seçili güne veya bugüne odaklanır. Bir günde, onu seçer.
←→Önceki veya sonraki güne geçer.
↑↓Önceki veya sonraki haftanın aynı gününe geçer.
Page UpPage DownÖnceki veya sonraki aya geçer.
ShiftPage UpÖnceki yıla geçer. Shift Page Down sonrakine geçer.
HomeEndHaftanın başına veya sonuna geçer.
EscSeçiciyi kapatır ve odağı trigger'a geri verir.
  • Popover title ile etiketlenir ve alt sheet onu bir başlık olarak gösterir. placeholder ile birlikte çevirin.
  • Trigger'ın kendine ait görünür bir etiketi yoktur. Onu bir <label /> ile eşleştirin veya aria-label geçin.
  • Devre dışı günler klavye tarafından atlanır ve kullanılamaz olarak duyurulur.

Her iki seçici de aşağıdaki prop'ları paylaşır ve bir popover veya alt sheet içinde bir <Calendar /> olan bir <Button /> trigger'ı render eder.

PropTürVarsayılan
value
Date | null–
defaultValue
Date | nullnull
onValueChange
(value: Date | null) => void–
placeholder
string"Pick a date"
titlePopover'ın erişilebilir adı, sheet'in başlığı.
string"Select a date"
open
boolean–
defaultOpen
booleanfalse
onOpenChange
(open: boolean) => void–
localeTrigger etiketini Intl.DateTimeFormat ile biçimlendirir. Takvimi de çevirmek için calendarProps içinde bir react-day-picker locale'i geçin.
string"en-US"
clearableBir değer olduğunda takvimin altına bir Clear düğmesi ekler.
booleanfalse
clearLabel
string"Clear"
nameDeğerin formuyla birlikte gönderilmesi için gizli bir girdi render eder.
string–
calendarPropsmode, selected, onSelect, required, numberOfMonths ve autoFocus hariç takvime geçirilir. Devre dışı günler, captionLayout, startMonth, endMonth, locale ve dir için kullanın.
CalendarProps–
variantTrigger bir Button'dır ve diğer prop'larını da kabul eder.
Button variant"outline"
disabled
booleanfalse
classNameVarsayılan olarak w-60 olan trigger'a uygulanır.
string–
PropTürVarsayılan
value
{ from: Date; to?: Date } | null–
defaultValue
{ from: Date; to?: Date } | nullnull
onValueChangeİkinci gün seçildikten sonra çağrılır.
(value: DateRange | null) => void–
placeholder
string"Pick a date range"
title
string"Select dates"
open
boolean–
defaultOpen
booleanfalse
onOpenChange
(open: boolean) => void–
localeTrigger etiketini Intl.DateTimeFormat ile biçimlendirir. Takvimi de çevirmek için calendarProps içinde bir react-day-picker locale'i geçin.
string"en-US"
clearableBir değer olduğunda takvimin altına bir Clear düğmesi ekler.
booleanfalse
clearLabel
string"Clear"
nameDeğerin formuyla birlikte gönderilmesi için gizli bir girdi render eder.
string–
calendarPropsmode, selected, onSelect, required, numberOfMonths ve autoFocus hariç takvime geçirilir. Devre dışı günler, captionLayout, startMonth, endMonth, locale ve dir için kullanın.
CalendarProps–
variantTrigger bir Button'dır ve diğer prop'larını da kabul eder.
Button variant"outline"
disabled
booleanfalse
classNameVarsayılan olarak w-60 olan trigger'a uygulanır.
string–
ÖznitelikAçıklama
data-slot="date-picker-trigger"Trigger düğmesi.
data-emptyDeğer yokken trigger üzerinde bulunur. Placeholder'ı soluk metinle gösterir.
data-popup-openSeçici açıkken trigger üzerinde bulunur.
data-slot="date-picker-content"Takvimi popover veya sheet içine sarar.
data-slot="date-picker-clear"Clear düğmesi.

Kullanıldığı bloklar

Date picker üzerine kurulan bloklar.