Calendar

A calendar component that allows users to select a single date.

Available from eds-core/1.11.0

Quick Start

Installation
npm install @adaptavant/eds-core
Import
import { Calendar } from '@adaptavant/eds-core';

Default

The Calendar component accepts value and onValueChange props, allowing you to control its state.

Please pick a day.
const [selectedDate, setSelectedDate] = React.useState();

return (
	<Stack className="gap-4">
		<Calendar onValueChange={setSelectedDate} value={selectedDate} />
		<Text>
			{selectedDate
				? `You selected ${selectedDate.toDateString()}.`
				: 'Please pick a day.'}
		</Text>
	</Stack>
);

Size

Customise the size of the Calendar via the size prop.

<Box className="flex gap-5">
	{/* Small */}
	<Calendar size="small" />
	{/* Standard */}
	<Calendar />
</Box>

Disabled days

You can disable dates from being selected by using the isDateUnavailable prop, which takes a function that receives a date and returns true if that value should be disabled. In this example, the weekends and today's date are disabled which prevents users from selecting these dates.

Please pick a day.
function isWeekend(date) {
  const day = date.getDay();
  return day === 0 || day === 6;
}

function isToday(date) {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  date.setHours(0, 0, 0, 0);  
  return today.getTime() === date.getTime();
}

const [selectedDate, setSelectedDate] = React.useState();
return (
	<Stack className="gap-4">
		<Calendar
			isDateUnavailable={(date) => isWeekend(date) || isToday(date)}
			onValueChange={setSelectedDate}
			value={selectedDate}
		/>
		<Text>
			{selectedDate
				? `You selected ${selectedDate.toDateString()}.`
				: 'Please pick a day.'}
		</Text>
	</Stack>
);

First day of week

Use the weekStartsOn prop to change the first day of the week. Accepts a value from 0 (Sunday) to 6 (Saturday).

<Stack className="gap-4">
	<Calendar weekStartsOn={1} /> {/* Monday */}
</Stack>

Min and Max value

Use the minValue and maxValue props to define a specific date range for the calendar. This limits users to selecting dates only within the designated range and prevents navigation to months outside the specified months.

Note: The below calendar restricts date selection to the current year using minValue and maxValue props. Users cannot navigate to months outside this range, ensuring the dates from other years are disabled.

Please pick a day.
function startOfMonth(date) {
	const start = new Date(date.getFullYear(), date.getMonth(), 1);
	return start;
}

function endOfMonth(date) {
	const end = new Date(date.getFullYear(), date.getMonth() + 1, 0);
	return end;
}

const [selectedDate, setSelectedDate] = React.useState();

return (
	<Stack className="gap-4">
		<Calendar
			maxValue={endOfMonth(new Date(new Date().getFullYear(),11))} // December, Current Year
			minValue={startOfMonth(new Date(new Date().getFullYear(),0))} // January, Current Year
			onValueChange={(date) => {
				setSelectedDate(date);
			}}
			value={selectedDate}
		/>
		<Text>
			{selectedDate
				? `You selected ${selectedDate.toDateString()}`
				: 'Please pick a day.'}
		</Text>
	</Stack>
);

Style API

Our design system components include style props that allow you to easily customize different parts of each component to match your design needs.

Please refer to the Style API documentation for more insights.

Calendar parts

<Stack className="gap-4">
	<Calendar
		classNames={{
			caption: 'border-2 bg-caution',
			captionWrapper: 'rounded-none bg-caution-secondary',
			captionLabel: 'font-mono',
			captionYear: 'font-mono',
			captionIconEnd: 'bg-neutral-tertiary rounded-full',
			navButtonNext: 'bg-neutral-tertiary rounded-none hover:scale-110',
			navButtonPrevious: 'bg-neutral-tertiary rounded-none hover:scale-110',
			head: 'bg-positive',
			headRow: 'p-2 m-2 bg-positive-hover',
			headCell: 'bg-positive-secondary',
			tableBody: 'border mt-2',
			headCellContent: 'font-mono text-positive',
			nav: 'p-1 bg-neutral-tertiary-hover',
			monthGrid: 'border p-1',
			table: 'border',
			cellButton: 'hover:scale-125 bg-constant-black',
			cellText: 'font-mono text-constant-white',
		}}
	/>
</Stack>

Stylable Parts

Description

caption

The main caption area containing the month, year and navigation buttons.

captionIconEnd

Icon element placed at the end of the caption

captionLabel

The label that displays the name of the month in the caption

captionWrapper

A wrapper for the caption content, enclosing the caption icon, label, and year

captionYear

The element displaying the year in the caption

head

The table header row containing day names

headCell

The cell containing each day's name

headCellContent

The content within each headCell

headRow

The table row containing day names

monthGrid

The container holding all the month cells in the month view

nav

The navigation container for the navigation buttons that change months or years

navButtonNext

The button for navigating to the next month or year

navButtonPrevious

The button for navigating to the previous month or year

row

A row within the month view, containing a week's worth of day cells

table

The table containing the day names and day cells

tableBody

The table body containing rows of day cells

cell

Represents the single day cell or month cell

cellButton

The button inside day cell or month cell

cellText

The text inside day cell or month cell