react-modular-datepicker

Headless Architecture

Learn how react-modular-datepicker separates date calculation logic from UI rendering.

Headless Architecture

react-modular-datepicker is built around a headless-first philosophy. The core selection logic, month generation, grid calculations, navigation states, and date formatting are completely decoupled from the UI rendering layer.


Two Ways to Use

1. Ready-to-use <Calendar /> Component

If you want a polished, pre-styled datepicker out of the box, use the <Calendar /> component. It handles navigation buttons, month headers, weekday grids, state styling, and month/year pickers automatically.

import { Calendar } from 'react-modular-datepicker';

<Calendar
  selectionMode="range"
  monthsToDisplay={2}
  onChange={(range) => console.log(range)}
/>

2. Headless useDates() Hook

If you need complete design freedom—for instance, building a full-page event planner, custom popover pickers, or proprietary design systems—use the useDates hook.

import { useDates } from 'react-modular-datepicker';

function CustomCalendar() {
  const { calendars, getDateProps, getBackProps, getForwardProps } = useDates({
    selectionMode: 'single',
  });

  const calendar = calendars[0];

  return (
    <div>
      <div className="header">
        <button {...getBackProps()}>Prev</button>
        <span>{calendar.year} - {calendar.month + 1}</span>
        <button {...getForwardProps()}>Next</button>
      </div>

      <div className="grid grid-cols-7">
        {calendar.weeks.flat().map((dateObj, idx) => (
          dateObj ? (
            <button key={idx} {...getDateProps({ dateObj })}>
              {dateObj.date.getDate()}
            </button>
          ) : <div key={idx} />
        ))}
      </div>
    </div>
  );
}
Live Preview: Headless Custom Layout
October 2026
Su
Mo
Tu
We
Th
Fr
Sa

How Date Objects Work

The useDates hook generates a matrix of DateObj instances representing each day cell in the calendar grid. Each DateObj contains normalized boolean states:

  • selected: boolean — Whether this date is currently selected.
  • selectable: boolean — Whether this date can be clicked (respects min/max bounds and disabled dates).
  • today: boolean — Whether this date is today.
  • prevMonth / nextMonth: boolean — Indicates buffer days outside the current sheet.
  • isRangeStart / isRangeEnd / isRangeBetween / isRangeHovering: boolean — Range selection state flags.
  • modifiers: string[] — Custom modifier tags assigned via callback props.

This data structure allows custom components to apply styles without recalculating date logic.

On this page