Skip to content
  1. Keyline UI
  2. Date picker and calendar
Keyline UIComponents
  • Get started
    • Installation
    • Theming
    • Modes
    • Configuration
    • Composition
  • Actions
    • Button
    • Button group
    • Split button
    • Toggle
    • Toggle group
    • Toolbar
    • Menu
    • Menubar
    • Context menu
  • Inputs
    • Field and form
    • Checkbox
    • Checkbox group
    • Radio group
    • Switch
    • Slider
    • Segmented
    • Select
    • Native select
    • Combobox
    • Multiselect
    • Number field
    • OTP field
    • Time field
    • Date picker and calendar
    • Date range
  • Data
    • Table
    • Chart
    • Stat and meter
    • Status and badge
    • Progress
    • Skeleton
    • Empty
    • Avatar
    • Kbd
    • Marker
  • Navigation
    • Tabs
    • Breadcrumb
    • Pagination
    • Nav
    • Navigation menu
    • Command menu
  • Overlays
    • Dialog
    • Alert dialog
    • Drawer
    • Sheet
    • Popover
    • Hover card
    • Tooltip
    • Toast
    • Notice
  • Layout
    • App shell
    • Sidebar
    • Panel
    • Resizable
    • Scroll area
    • Accordion
    • Collapsible
    • Carousel
    • Inspector
    • Item
    • Direction
  • Conversation
    • Message
    • Bubble
    • Message scroller
    • Attachment
    • Questionnaire
  • Blocks
    • Shipments

Date picker and calendar

A day from a calendar that docks to its field. The chosen day is ink and today is underlined; days you can't choose are hatched, skipped by the arrow keys and say why.

Loading the live example…

"use client"

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

const day = (offset: number) => {
  const d = new Date()
  return new Date(d.getFullYear(), d.getMonth(), d.getDate() + offset)
}
const nextMonday = () => day(((8 - new Date().getDay()) % 7) || 7)

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

  return (
    <div className="grid max-w-[360px] gap-3">
      <DatePicker
        label="Deliver on"
        locale="en-US"
        min={day(1)}
        max={day(60)}
        value={date}
        onValueChange={setDate}
        isDateUnavailable={(d) => (d.getDay() === 0 || d.getDay() === 6 ? "no weekend deliveries" : false)}
        presets={[{ label: "Next Monday", date: nextMonday }]}
      />
      <p role="status" className="text-[14px] text-kl-ink-2">
        {date ? `On Darryl's route for ${date.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric" })}.` : "Weekdays only, from tomorrow."}
      </p>
    </div>
  )
}

Installation

npx shadcn@latest add @keyline-ui/date-picker

Run it where your components.json is. The first time, map the @keyline-ui registry: one command, in Installation.

Usage

import { DatePicker } from "@/components/keyline/ui/date-picker"
<DatePicker
  label="Deliver on"
  locale="en-US"
  min={tomorrow}
  value={date}
  onValueChange={setDate}
  isDateUnavailable={(d) => d.getDay() % 6 === 0 && "no weekend deliveries"}
/>

Examples

Day and time

DateTimePicker adds a time row under the calendar. Given slots, the row offers those times; isTimeUnavailable marks a booked one, and a day with no slot left is unavailable.

Loading the live example…

"use client"

import { useState } from "react"
import { DateTimePicker } from "@/components/keyline/ui/date-picker"

const tomorrow = () => {
  const d = new Date()
  return new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1)
}

// Michael's calendar: the 9 AM slot is his "conference room meeting" every Monday
const busy = (day: Date, time: string) => (day.getDay() === 1 && time === "09:00" ? "Michael's Monday meeting" : day.getDay() === 5 && time === "15:00" ? "pretzel day" : false)

export function ClientMeeting() {
  const [when, setWhen] = useState<Date | null>(null)

  return (
    <div className="grid max-w-[360px] gap-3">
      <DateTimePicker
        label="Meet the Lackawanna County buyer"
        locale="en-US"
        hourCycle={12}
        min={tomorrow()}
        slots={["09:00", "11:00", "13:30", "15:00"]}
        isTimeUnavailable={busy}
        isDateUnavailable={(d) => (d.getDay() === 0 || d.getDay() === 6 ? "weekend" : false)}
        value={when}
        onValueChange={setWhen}
      />
      <p role="status" className="text-[14px] text-kl-ink-2">
        {when ? `Booked. Jim takes the meeting; Dwight is not to attend.` : "Pick a day, then one of the open slots."}
      </p>
    </div>
  )
}

Props

PropTypeDefaultDescription
labelReactNodeDefault —Names the field. Required.
valueDate | nullDefault —With onValueChange, or start with defaultValue.
min / maxDateDefault —The first and last day you can choose. Month navigation stops there.
isDateUnavailable(day: Date) => string | booleanDefault —Return true, or a short reason that is read out, for a day that can't be chosen. It is hatched and the arrow keys skip it.
presets{ label, date: () => Date }[]Default []Quick choices under the calendar.
localestringDefault "en-GB"Names the months and days, and formats the field.
weekStartsOnnumberDefault 10 for Sunday.
namestringDefault —Submits the day as YYYY-MM-DD.

Also exported: Calendar, the grid on its own, and DateTimePicker, which also takes hourCycle, slots, minTime, maxTime, required and error. Built on React DayPicker and Base UI Popover.

Sheet 30 of 73PreviousTime fieldNextDate range
On this page