# Calendar

A keyboard- and screen-reader-accessible date picker for single-date and range selection.

## Installation

```tsx
import { Calendar } from "@makeplane/propel/components/calendar";
```
## Usage

```tsx
import { Calendar } from "@makeplane/propel/components/calendar";
import * as React from "react";

export default function BasicDemo() {
  const [selected, setSelected] = React.useState<Date | undefined>(new Date(2025, 0, 24));

  return (
    <Calendar
      mode="single"
      defaultMonth={new Date(2025, 0, 1)}
      selected={selected}
      onSelect={setSelected}
    />
  );
}
```

`Calendar` starts in the day view. Select its month or year heading to browse months and years, then choose one to return to the day grid. It draws no surface of its own — no border, shadow, fill, radius or padding — so the host owns the chrome. Put it in a `PopoverContent` for a date picker, or in a dialog or a card, and it takes that surface's single border and gutters instead of adding its own.

## Examples

### Date picker

The grid inside a `rich` `PopoverContent`: the popover paints the border, shadow, radius and 16px gutters, and the trigger's label follows the selection. Picking a day closes the panel.

```tsx
import { Button } from "@makeplane/propel/components/button";
import { Calendar } from "@makeplane/propel/components/calendar";
import { Icon } from "@makeplane/propel/components/icon";
import { Popover, PopoverContent, PopoverTrigger } from "@makeplane/propel/components/popover";
import { CalendarOutline } from "@makeplane/propel/icons";
import * as React from "react";

const triggerDate = new Intl.DateTimeFormat("en-US", { dateStyle: "medium" });

export default function DatePickerDemo() {
  const [selected, setSelected] = React.useState<Date | undefined>(new Date(2025, 0, 24));
  const [open, setOpen] = React.useState(false);

  return (
    <Popover open={open} onOpenChange={setOpen}>
      <Button
        stretch="auto"
        variant="secondary"
        size="md"
        icon={<Icon icon={CalendarOutline} />}
        render={<PopoverTrigger />}
        label={selected ? triggerDate.format(selected) : "Pick a date"}
      />
      {/* The popover owns the surface — border, shadow, radius, gutters. The grid draws none. */}
      <PopoverContent positionMethod="fixed" aria-label="Pick a date">
        <Calendar
          mode="single"
          defaultMonth={new Date(2025, 0, 1)}
          selected={selected}
          onSelect={(day) => {
            setSelected(day);
            setOpen(false);
          }}
        />
      </PopoverContent>
    </Popover>
  );
}
```

### Range

```tsx
import { Calendar } from "@makeplane/propel/components/calendar";
import * as React from "react";

// Mirrors react-day-picker's `DateRange` shape without importing it (demos import
// only from `@makeplane/propel/components/*`).
type DateRange = { from: Date | undefined; to?: Date | undefined };

export default function RangeDemo() {
  const [range, setRange] = React.useState<DateRange | undefined>({
    from: new Date(2025, 0, 13),
    to: new Date(2025, 0, 20),
  });

  return (
    <Calendar
      mode="range"
      defaultMonth={new Date(2025, 0, 1)}
      selected={range}
      onSelect={setRange}
    />
  );
}
```

### Disabled days

```tsx
import { Calendar } from "@makeplane/propel/components/calendar";
import * as React from "react";

export default function DisabledDaysDemo() {
  const [selected, setSelected] = React.useState<Date | undefined>();

  return (
    <Calendar
      mode="single"
      defaultMonth={new Date(2025, 0, 1)}
      selected={selected}
      onSelect={setSelected}
      // Weekends (Sunday and Saturday) render muted and cannot be selected.
      disabled={{ dayOfWeek: [0, 6] }}
    />
  );
}
```

### Today indicator

The current date is marked with an accent dot below the day number; the dot persists when today is selected. Pin it with the `today` prop — here it's set to January 6 for a deterministic grid.

```tsx
import { Calendar } from "@makeplane/propel/components/calendar";
import * as React from "react";

export default function TodayIndicatorDemo() {
  const [selected, setSelected] = React.useState<Date | undefined>();

  return (
    <Calendar
      mode="single"
      defaultMonth={new Date(2025, 0, 1)}
      today={new Date(2025, 0, 6)}
      selected={selected}
      onSelect={setSelected}
    />
  );
}
```
## API Reference

`Calendar` forwards [react-day-picker's `DayPickerProps`](https://daypicker.dev/api/interfaces/DayPickerProps) — `mode`, `selected`, `onSelect`, `month`, `defaultMonth`, `disabled`, `today`, and the rest. Use `defaultView="months"` or `defaultView="years"` to start in a different view. `className`, `style`, `classNames`, `numberOfMonths`, `captionLayout`, `navLayout`, and `showWeekNumber` are omitted: styling is owned by propel's tokens, and those DayPicker layout modes have no styled contract.

The `labels` prop also accepts `labelPreviousYear`, `labelNextYear`, `labelPreviousYearPage`, `labelNextYearPage`, `labelMonthView`, and `labelYearView` to name the month and year chooser controls for assistive technology.
