---
title: Mini Calendar
description: A composable mini calendar component for picking dates close to today.
icon: calendar-1
author:
  name: haydenbleasel
  url: https://github.com/haydenbleasel
mode: wide
---

<PoweredBy
  packages={[
    { name: 'lucide', url: 'https://lucide.dev/' },
    { name: 'date-fns', url: 'https://date-fns.org/' },
  ]}
/>

### Installation

```package-install
npx shadcn@latest add @redpanda/mini-calendar
```

<ComponentPreview name="mini-calendar-demo" />

## When to use

The Mini Calendar component provides compact date selection for recent dates. Use this decision tree to determine when it's appropriate:

```mermaid
graph TD;
    A[❓ Need date selection?] --> B{Recent dates only?};
    A --> C[ℹ️ Use other input types];
    B --> D{Compact horizontal layout?};
    B --> E{Full calendar needed?};
    D --> F[✅ Use MiniCalendar];
    E --> G[✅ Use Calendar component];
    E --> H{Date range selection?};
    H --> I[✅ Use DateRangePicker];
    H --> J[✅ Use MiniCalendar for simplicity];

    classDef recommended fill:#4ade80,stroke:#22c55e,stroke-width:2px,color:#000;
    classDef discouraged fill:#fbbf24,stroke:#f59e0b,stroke-width:2px,color:#000;
    classDef decision fill:#60a5fa,stroke:#3b82f6,stroke-width:2px,color:#fff;
    classDef neutral fill:#9ca3af,stroke:#6b7280,stroke-width:2px,color:#fff;

    class F,G,I,J recommended;
    class A,B,D,E,H decision;
    class C neutral;
```

## Features

- Displays a configurable number of consecutive days (default: 5) in a compact horizontal layout
- Navigation with chevron buttons to move between date ranges by the configured number of days
- Fully composable with separate components for navigation, days container, and individual days
- Supports both controlled and uncontrolled usage with value/defaultValue and onValueChange props
- Highlights today's date with accent background and selected dates with the selected color tokens
- Announces selected dates with `aria-pressed` and supports native keyboard activation
- Keeps date-action appearance fixed; use containing elements for layout spacing
- Context-based state management between components using React Context
- Supports custom start dates with startDate/defaultStartDate and onStartDateChange props

## Examples

### Basic Usage

<ComponentPreview name="mini-calendar-demo" />

### Controlled

<ComponentPreview name="mini-calendar-controlled-demo" />

### Custom Layout

<ComponentPreview name="mini-calendar-custom-layout-demo" />

### Custom Days

<ComponentPreview name="mini-calendar-custom-days-demo" />

This example displays seven days and disables weekends.

## Usage

```tsx
import {
  MiniCalendar,
  MiniCalendarDay,
  MiniCalendarDays,
  MiniCalendarNavigation,
} from '@/components/redpanda-ui/mini-calendar';
```

```tsx
<MiniCalendar>
  <MiniCalendarNavigation direction="prev" />
  <MiniCalendarDays>{(date) => <MiniCalendarDay date={date} key={date.toISOString()} />}</MiniCalendarDays>
  <MiniCalendarNavigation direction="next" />
</MiniCalendar>
```

## Date-action behavior

`MiniCalendarDay` owns its month/day label, selected and today appearance, focus feedback, and loading treatment.
It supports native button attributes, refs, `render`, `nativeButton`, `focusableWhenDisabled`, `disabled`,
`isLoading`, and `testId`. The default native `type` is `button`, so selecting a date does not submit an enclosing form.
Loading keeps the date's accessible name, marks it busy, and prevents selection.

The day action does not accept general Button `variant`, `size`, `weight`, `shape`, `icon`, navigation aliases,
`className`, `style`, or replacement `children`. Put layout spacing on a containing element. Control selection with
`MiniCalendar`'s `value`, `defaultValue`, and `onValueChange`, rather than setting `aria-pressed` yourself.
`MiniCalendarNavigation` remains an ordinary Button-based navigation control; custom render elements keep their
existing appearance API and should provide an accessible name when they contain only an icon.

A day action calls a supplied `onClick` before changing the selected date. Use `event.preventDefault()` or
`event.preventBaseUIHandler()` to cancel selection. An ordinary click handler no longer replaces the internal
selection handler:

```tsx
<MiniCalendarDay
  date={date}
  onClick={(event) => {
    if (!canSelectDate(date)) {
      event.preventDefault();
    }
  }}
/>
```

## Credits

- We take our inspiration from [Kibo UI](https://www.kibo-ui.com/components/mini-calendar) for the mini calendar component and style.
