# Calendar

```ts
import { Calendar } from 'cx/widgets';
```

The `Calendar` widget displays a standalone calendar for date selection. It's also used internally by `DateField`.

```tsx
import { createModel } from "cx/data";
import { bind } from "cx/ui";
import { Calendar } from "cx/widgets";

interface Model {
  date: string;
}

const m = createModel<Model>();

export default <Calendar value={bind(m.date, "2024-06-15")} showTodayButton />;

```

## Custom Day Styling

Use `dayData` to customize individual days with styles, classes, or disable specific dates. Keys are created using `date.toDateString()`.

```tsx
import { createModel } from "cx/data";
import { Calendar } from "cx/widgets";

interface Model {
  date: string;
}

const m = createModel<Model>();

export default (
  <Calendar
    value={m.date}
    minValue="2024-06-10"
    maxValue="2024-06-20"
    refDate="2024-06-08"
    dayData={{
      [new Date("2024-06-11").toDateString()]: {
        style: "color: red; font-weight: bold",
      },
      [new Date("2024-06-12").toDateString()]: {
        disabled: true,
      },
      [new Date("2024-06-13").toDateString()]: {
        style: "outline: 2px solid #3b82f6",
      },
    }}
  />
);

```

## Keyboard Navigation

The Calendar is fully keyboard accessible. Click on the calendar to focus it, then use the following keys:

| Key           | Action                       |
| ------------- | ---------------------------- |
| ← →           | Move cursor by one day       |
| ↑ ↓           | Move cursor by one week      |
| Page Up       | Previous month               |
| Page Down     | Next month                   |
| Home          | First day of current month   |
| End           | Last day of current month    |
| Enter         | Select the focused date      |
| Mouse wheel   | Scroll through months        |

## Configuration

### Core Properties

| Property         | Type      | Default   | Description                                                                |
| ---------------- | --------- | --------- | -------------------------------------------------------------------------- |
| `value`          | `string`  | `null`    | Selected date. Accepts Date objects or ISO strings                         |
| `refDate`        | `string`  |           | Reference date for initial view when no value is selected                  |
| `disabled`       | `boolean` | `false`   | Disables the calendar                                                      |
| `highlightToday` | `boolean` | `true`    | Highlights today's date                                                    |
| `showTodayButton`| `boolean` | `false`   | Shows a "Today" button for quick selection                                 |
| `todayButtonText`| `string`  | `"Today"` | Text for the today button                                                  |
| `startWithMonday`| `boolean` | `false`   | Start weeks with Monday instead of Sunday                                  |

### Date Constraints

| Property             | Type       | Default | Description                                                      |
| -------------------- | ---------- | ------- | ---------------------------------------------------------------- |
| `minValue`           | `string`   |         | Minimum selectable date                                          |
| `minExclusive`       | `boolean`  | `false` | If `true`, the minimum date itself is not selectable             |
| `maxValue`           | `string`   |         | Maximum selectable date                                          |
| `maxExclusive`       | `boolean`  | `false` | If `true`, the maximum date itself is not selectable             |
| `disabledDaysOfWeek` | `number[]` |         | Days of week that cannot be selected. Sunday is 0, Saturday is 6 |
| `dayData`            | `object`   |         | Map of dates to custom day info (style, className, disabled)     |

### Validation

| Property                | Type     | Default                              | Description                                       |
| ----------------------- | -------- | ------------------------------------ | ------------------------------------------------- |
| `minValueErrorText`     | `string` | `"Select a date not before {0:d}."` | Error message when date is before minimum          |
| `minExclusiveErrorText` | `string` | `"Select a date after {0:d}."`       | Error message when date equals exclusive minimum  |
| `maxValueErrorText`     | `string` | `"Select a date not after {0:d}."`  | Error message when date is after maximum           |
| `maxExclusiveErrorText` | `string` | `"Select a date before {0:d}."`      | Error message when date equals exclusive maximum  |

### Behavior

| Property    | Type       | Default | Description                                                                     |
| ----------- | ---------- | ------- | ------------------------------------------------------------------------------- |
| `autoFocus` | `boolean`  | `false` | Automatically focuses the calendar on mount                                     |
| `focusable` | `boolean`  | `true`  | Whether the calendar can receive focus                                          |
| `partial`   | `boolean`  | `false` | Preserves time component when updating date                                     |
| `encoding`  | `function` |         | Custom function to encode Date objects before storing. Default: `toISOString()` |

### Callbacks

| Property         | Type       | Description                                                               |
| ---------------- | ---------- | ------------------------------------------------------------------------- |
| `onSelect`       | `function` | `(e, instance, date) => void` - Called when a date is selected            |
| `onBeforeSelect` | `function` | `(e, instance, date) => boolean` - Return `false` to prevent selection    |
| `onBlur`         | `function` | `(e, instance) => void` - Called when calendar loses focus                |
| `onFocusOut`     | `function` | `(instance) => void` - Called when focus leaves the calendar              |