LOKE Design System
Components

Calendar

A date picker calendar component with single, multiple, and range selection modes.

Calendar

The Calendar component provides a rich date selection interface supporting single dates, multiple dates, or date ranges. It includes month navigation, customizable date constraints, and various display options.

For a complete date picker experience with an input field and popover, consider using the DatePicker component which wraps Calendar with additional UI.


Features

  • Selection modes: single date, multiple dates, or date range
  • Month navigation with previous/next buttons
  • Optional year selector dropdown
  • Min/max date constraints
  • Custom disabled dates (array or function)
  • Week numbers display
  • Fixed weeks option for consistent height
  • Multi-month display
  • Customizable first day of week
  • Outside days visibility control
  • Initial focus support for accessibility

Usage

import { Calendar } from '@loke/design-system/calendar';

export default function Example() {
  const [date, setDate] = useState<Date | undefined>(new Date());

  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
    />
  );
}

Tips:

  • Use mode="single" for selecting a single date.
  • Use mode="range" for date range selection (e.g., booking dates).
  • Set minDate and maxDate to constrain selectable dates.
  • Enable showWeekNumber for calendars that need week-based navigation.

Props

Prop

Type


Examples

Single date selection

January 2026
SMTWTFS
const [date, setDate] = useState<Date | undefined>(new Date());

<Calendar
  mode="single"
  selected={date}
  onSelect={setDate}
/>

Multiple date selection

January 2026
SMTWTFS
const [dates, setDates] = useState<Date[]>([]);

<Calendar
  mode="multiple"
  selected={dates}
  onSelect={setDates}
/>

Date range selection

January 2026
SMTWTFS
March 2026
SMTWTFS
const [range, setRange] = useState<DateRange | undefined>();

<Calendar
  mode="range"
  selected={range}
  onSelect={setRange}
  numberOfMonths={2}
/>

Disabled dates

January 2026
SMTWTFS
// Disable weekends
<Calendar
  mode="single"
  disabled={(date) => date.getDay() === 0 || date.getDay() === 6}
/>

// Or disable specific dates
<Calendar
  mode="single"
  disabled={[new Date(2024, 0, 1), new Date(2024, 11, 25)]}
/>

Min and max dates

January 2026
SMTWTFS
<Calendar
  mode="single"
  minDate={new Date()}
  maxDate={new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)}
/>

Multiple months

January 2026
SMTWTFS
March 2026
SMTWTFS
<Calendar
  mode="range"
  numberOfMonths={2}
/>

Week numbers

January 2026
#SMTWTFS
52
1
2
3
4
<Calendar
  mode="single"
  showWeekNumber
/>

Year selector

SMTWTFS
<Calendar
  mode="single"
  captionProps={{ showYearSelector: true }}
/>

Accessibility

  • Calendar uses semantic table markup for screen reader compatibility.
  • Keyboard navigation with arrow keys moves between days.
  • Days are focusable with proper tabIndex management.
  • Selected state is conveyed via aria-selected attributes.
  • Disabled days are marked with disabled attribute.
  • Use initialFocus to ensure keyboard users land on a meaningful date when the calendar opens.

Best practices

  • Set appropriate minDate/maxDate constraints to prevent invalid selections.
  • Use mode="range" with numberOfMonths={2} for better date range UX.
  • Enable showWeekNumber for business applications that reference week numbers.
  • Consider fixedWeeks to prevent layout shifts when navigating months.
  • Use captionProps.showYearSelector when users need to navigate to distant dates.
  • Pair with Label component for form accessibility.