# [Usage](../../../usage.md) > [Components](../basics.md) > [Visuals](../basics.md) > Calendar

Month grid for displaying per-day content and handling day clicks (links or [Modals](modal.md)). Use it for dashboards, bookings or daily summaries; use the [Input](../../components/forms/input.md) with `date` type when you only need a single date picker inside a form.

![image](img/calendar_1.png)

```php
{!!
    \KFramework\Components\Visual\Calendar::make()
        ->setDayContent(function($date) {
            return 'Today is: ' . $date->format('Y-m-d');
        })
!!}
```

**End-to-end example:** leave calendar with day detail modal.
```php
// Blade:
{!!
    \KFramework\Components\Visual\Calendar::make()
        ->setMinYear(2024)
        ->setMaxYear(2026)
        ->setDayContent(function($date) {
            return $date->format('d');
        })
        ->setDayOnClick(function($date) {
            return '/leaves/day/' . $date->format('Y-m-d');
        })
!!}

// Controller:
use KFramework\Components\Visual\Calendar;

$calendar = Calendar::make()
    ->setMinYear(2024)
    ->setMaxYear(2026)
    ->setDayContent(fn($date) => $date->format('d'));

return view('leaves.index', compact('calendar'));
```

---
## Usage

- Blade:
```php
{!! \KFramework\Components\Visual\Calendar::make() !!}
```
- Controller:
```php
Calendar::make()
```

---
## Standard attributes

- `uuid`
- `id`
- `classes`
- `extraAttributes` — use `extraAttributes` to add wrappers or data attributes; `dayContent`/`dayOnClick` below receive the current `$date` for per-day rendering.

---
## Component-specific attributes

### `minYear` | `->setMinYear()`
Will set the minimum year available in the select.

| Types     | Default |
|-----------|---------|
| `integer` | `2000`  |

### `maxYear` | `->setMaxYear()`
Will set the maximum year available in the select.

| Types     | Default |
|-----------|---------|
| `integer` | `2050`  |

> Note: `Calendar::setMaxYear()` defaults to `2050` (same as `$maxYear` property).

### `dayContent` | `->setDayContent()`
Will set the content of each day, it will receive the actual `$date` (a `Carbon` instance) as callable argument to enable manipulations. Accepts a plain `Closure`, a serializable closure, or a static string. Closures are deferred: they are **not** executed during the initial page render, only via `POST /kfw/calendars/get-data` with the visible date range (max 92 days per request, owner-checked).

```php
->setDayContent(function($date) {
    return 'Today is: ' . $date->format('Y-m-d');
})
```

| Types               | Default |
|---------------------|---------|
| `Closure`, `string` | `null`  |

### `dayOnClick` | `->setDayOnClick()`
As dayContent, the actual `$date` as callable argument to enable manipulations. If a string is provided, it will be treated as an URL, so clicking a day will redirect to that url. If instead a Modal is provided, then click on the day will open the modal.

Day clicks are secured like table records: each date returned by `/kfw/calendars/get-data` carries an HMAC `signature` bound to the calendar UUID. String URLs automatically get `kfw_calendar_uuid`, `kfw_calendar_date` and `kfw_calendar_signature` query params appended. Verify them in your target route with:

```php
use KFramework\Helpers\CalendarHelper;

$date = CalendarHelper::verifyRequest(request);

if ($date === null) {
    abort(403);
}
```

```php
->setDayOnClick(function($date) {
    return '/view-day/' . $date->format('Y-m-d');
})
```

```php
->setDayOnClick(function($date) {
    return Modal::make()
        ->setContent('Today is: ' . $date->format('Y-m-d'));
})
```

| Types                        | Default |
|------------------------------|---------|
| `Closure`, `string`, `Modal` | `null`  |

## See also
- [Components basics](../basics.md)
- [Modal](modal.md), [Card](card.md), [Input](../forms/input.md)
- [url](../shared_attributes/url.md), [content](../shared_attributes/content.md)