Calendar

The Calendar component provides an accessible date picker with a clean, modern interface. It’s perfect for forms, booking interfaces, and any application requiring date selection.

Note: The Calendar component is currently experiencing rendering issues due to a dependency conflict. The examples below show the code but not the live components. We’re working on a fix.

Usage

<script>
  import { Calendar } from "$lib/components/ui/calendar";
  
  let date = new Date();
</script>

<Calendar bind:value={date} />

Examples

Basic Calendar

A simple calendar for picking a single date.

Calendar component preview temporarily unavailable

With Default Placeholder

A calendar with a placeholder date.

Calendar with placeholder preview temporarily unavailable

With Custom Weekday Format

Customize how weekday names are displayed.

Calendar with custom weekday format preview temporarily unavailable

Disabled Calendar

A calendar that cannot be interacted with.

Disabled calendar preview temporarily unavailable

With Date Range Selection

A calendar demonstrating how to implement date range selection.

Calendar with date range selection preview temporarily unavailable

With Unavailable Dates

A calendar showing some dates as unavailable.

Calendar with unavailable dates preview temporarily unavailable

API Reference

Calendar Components

ComponentDescription
CalendarThe root calendar component.
Calendar.HeaderThe header section of the calendar.
Calendar.HeadingDisplays the current month and year.
Calendar.PrevButtonButton to navigate to the previous month.
Calendar.NextButtonButton to navigate to the next month.
Calendar.MonthsContainer for the month views.
Calendar.GridThe grid layout for calendar dates.
Calendar.GridHeadThe header for the calendar grid.
Calendar.GridBodyThe body of the calendar grid containing dates.
Calendar.GridRowA row in the calendar grid.
Calendar.HeadCellA cell in the calendar header.
Calendar.CellA cell in the calendar body.
Calendar.DayThe interactive day element.

Calendar Root Properties

PropertyTypeDefaultDescription
valueDateundefinedThe selected date value.
placeholderDateundefinedDisplayed date when no date is selected.
weekdayFormat"narrow" \| "short" \| "long""short"Format for weekday names.
disabledbooleanfalseWhether the calendar is disabled.
readonlybooleanfalseWhether the calendar is readonly.
isDateDisabled(date: Date) => booleanundefinedFunction to determine if a date should be disabled.
isDateUnavailable(date: Date) => booleanundefinedFunction to determine if a date is unavailable.
fromDateDateundefinedMinimum selectable date.
toDateDateundefinedMaximum selectable date.
numberOfMonthsnumber1Number of months to display.
fixedWeeksbooleanfalseWhether to always show 6 weeks per month.
localestringBrowser’s localeThe locale to use for formatting.
classstringundefinedCustom CSS classes.
refHTMLDivElementundefinedA reference to the underlying HTML element.

Calendar Day Properties

PropertyTypeDefaultDescription
selectedbooleanfalseWhether the day is selected.
outsidebooleanfalseWhether the day is outside the current month.
disabledbooleanfalseWhether the day is disabled.
unavailablebooleanfalseWhether the day is unavailable.
todaybooleanfalseWhether the day is today.
classstringundefinedCustom CSS classes.
refHTMLButtonElementundefinedA reference to the underlying HTML element.

Implementation

The Calendar component is built on top of bits-ui primitives. The main implementation renders a composable calendar structure with proper semantic markup and ARIA attributes for accessibility:

<script lang="ts">
	import { Calendar as CalendarPrimitive } from "bits-ui";
	import * as Calendar from "./index.js";
	import { cn } from "$lib/utils.js";

	let {
		ref = $bindable(null),
		value = $bindable(),
		placeholder = $bindable(),
		class: className,
		weekdayFormat = "short",
		...restProps
	}: CalendarPrimitive.RootProps = $props();
</script>

<CalendarPrimitive.Root
	bind:value
	bind:ref
	bind:placeholder
	{weekdayFormat}
	class={cn("p-3", className)}
	{...restProps}
>
	{#snippet children({ months, weekdays })}
		<Calendar.Header>
			<Calendar.PrevButton />
			<Calendar.Heading />
			<Calendar.NextButton />
		</Calendar.Header>
		<Calendar.Months>
			{#each months as month}
				<Calendar.Grid>
					<Calendar.GridHead>
						<Calendar.GridRow class="flex">
							{#each weekdays as weekday}
								<Calendar.HeadCell>
									{weekday.slice(0, 2)}
								</Calendar.HeadCell>
							{/each}
						</Calendar.GridRow>
					</Calendar.GridHead>
					<Calendar.GridBody>
						{#each month.weeks as weekDates}
							<Calendar.GridRow class="mt-2 w-full">
								{#each weekDates as date}
									<Calendar.Cell {date} month={month.value}>
										<Calendar.Day />
									</Calendar.Cell>
								{/each}
							</Calendar.GridRow>
						{/each}
					</Calendar.GridBody>
				</Calendar.Grid>
			{/each}
		</Calendar.Months>
	{/snippet}
</CalendarPrimitive.Root>

The Calendar.Day component is styled with Tailwind CSS and includes various states such as today, selected, disabled, and unavailable to provide clear visual feedback.