ButtonCard
Get Started
Introduction
Components
Accordion
Badge
Button
Card
Checkbox
Command
Dialog
Dropdown Menu
Input
Select
Switch
Table
Tabs
Toast
Tooltip
Forms
Controlled Input
Field Arrays
Submit
Validation

Calendar

A date picker component with month navigation and single or range selection.

March 2026
SuMoTuWeThFrSa
single
range

#Installation

bunx --bun barefoot add calendar

#Usage

March 2026
SuMoTuWeThFrSa
March 2026
SuMoTuWeThFrSa
April 2026
SuMoTuWeThFrSa
March 2026
SuMoTuWeThFrSa
1"use client"23import { createSignal } from "@barefootjs/dom"4import { Calendar } from "@/components/ui/calendar"56function CalendarDemo() {7  const [selected, setSelected] = createSignal<Date | undefined>()89  return (10    <div className="space-y-4">11      {/* Single date selection */}12      <Calendar13        mode="single"14        selected={selected()}15        onSelect={setSelected}16      />1718      {/* Range selection */}19      <Calendar mode="range" numberOfMonths={2} />2021      {/* With constraints (next 30 days only) */}22      <Calendar23        mode="single"24        fromDate={new Date()}25        toDate={new Date(Date.now() + 30 * 86400000)}26      />27    </div>28  )29}

#Examples

#Basic

March 2026
SuMoTuWeThFrSa

No date selected

1"use client"23import { createSignal, createMemo } from "@barefootjs/dom"4import { Calendar } from "@/components/ui/calendar"56export function CalendarBasicDemo() {7  const [date, setDate] = createSignal<Date | undefined>(undefined)89  const formattedDate = createMemo(() => {10    const d = date()11    if (!d) return 'No date selected'12    return d.toLocaleDateString('en-US', {13      weekday: 'long',14      year: 'numeric',15      month: 'long',16      day: 'numeric',17    })18  })1920  return (21    <div className="flex flex-col items-center gap-4">22      <Calendar selected={date()} onSelect={setDate} />23      <p className="text-sm text-muted-foreground">{formattedDate()}</p>24    </div>25  )26}

#Form

Book an appointment

March 2026
SuMoTuWeThFrSa
1"use client"23import { createSignal, createMemo } from "@barefootjs/dom"4import { Calendar } from "@/components/ui/calendar"56export function CalendarFormDemo() {7  const today = new Date()8  const [date, setDate] = createSignal<Date | undefined>(undefined)9  const [name, setName] = createSignal('')1011  const canSubmit = createMemo(() => date() !== undefined && name().length > 0)1213  const formattedDate = createMemo(() => {14    const d = date()15    if (!d) return ''16    return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })17  })1819  return (20    <div className="space-y-4 max-w-sm">21      <div className="space-y-2">22        <h4 className="text-sm font-medium">Book an appointment</h4>23        <div className="space-y-2">24          <label className="text-sm text-muted-foreground">Name</label>25          <input26            className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs"27            placeholder="Your name"28            value={name()}29            onInput={(e: Event) => setName((e.target as HTMLInputElement).value)}30          />31        </div>32        <div className="space-y-2">33          <label className="text-sm text-muted-foreground">Date</label>34          <Calendar35            selected={date()}36            onSelect={setDate}37            fromDate={today}38          />39          {date() && (40            <p className="text-sm text-muted-foreground">41              Selected: {formattedDate()}42            </p>43          )}44        </div>45      </div>46      <button47        className="inline-flex ... bg-primary text-primary-foreground disabled:opacity-50"48        disabled={!canSubmit()}49      >50        Book Appointment51      </button>52    </div>53  )54}

#Constraints

Schedule a meeting

Weekdays only, within the next 30 days

March 2026
SuMoTuWeThFrSa

Select a weekday

1"use client"23import { createSignal, createMemo } from "@barefootjs/dom"4import { Calendar } from "@/components/ui/calendar"56export function CalendarWithConstraintsDemo() {7  const today = new Date()8  const maxDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 30)9  const [date, setDate] = createSignal<Date | undefined>(undefined)1011  // Disable weekends (Saturday=6, Sunday=0)12  const isWeekend = (d: Date) => d.getDay() === 0 || d.getDay() === 61314  const formattedDate = createMemo(() => {15    const d = date()16    if (!d) return 'Select a weekday'17    return d.toLocaleDateString('en-US', { weekday: 'long', month: 'short', day: 'numeric' })18  })1920  return (21    <div className="flex flex-col items-center gap-4">22      <div className="text-center space-y-1">23        <h4 className="text-sm font-medium">Schedule a meeting</h4>24        <p className="text-xs text-muted-foreground">Weekdays only, within the next 30 days</p>25      </div>26      <Calendar27        selected={date()}28        onSelect={setDate}29        fromDate={today}30        toDate={maxDate}31        disabled={isWeekend}32      />33      <p className="text-sm text-muted-foreground">{formattedDate()}</p>34    </div>35  )36}

#API Reference

PropTypeDefaultDescription
mode'single' | 'range''single'Selection mode: single date or date range.
selectedDate-The currently selected date (controlled, single mode).
onSelect(date: Date | undefined) => void-Callback when a date is selected (single mode).
selectedRange{ from?: Date; to?: Date }-The currently selected range (controlled, range mode).
onRangeSelect(range: { from?: Date; to?: Date }) => void-Callback when a range is selected (range mode).
fromDateDate-Minimum selectable date.
toDateDate-Maximum selectable date.
numberOfMonthsnumber1Number of months to display side by side.
classNamestring-Additional CSS classes.