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 PartsDescription
captionThe main caption area containing the month, year and navigation buttons.
captionIconEndIcon element placed at the end of the caption
captionLabelThe label that displays the name of the month in the caption
captionWrapperA wrapper for the caption content, enclosing the caption icon, label, and year
captionYearThe element displaying the year in the caption
headThe table header row containing day names
headCellThe cell containing each day's name
headCellContentThe content within each headCell
headRowThe table row containing day names
monthGridThe container holding all the month cells in the month view
navThe navigation container for the navigation buttons that change months or years
navButtonNextThe button for navigating to the next month or year
navButtonPreviousThe button for navigating to the previous month or year
rowA row within the month view, containing a week's worth of day cells
tableThe table containing the day names and day cells
tableBodyThe table body containing rows of day cells
cellRepresents the single day cell or month cell
cellButtonThe button inside day cell or month cell
cellTextThe text inside day cell or month cell