Klarhimmel UI

Calendar

Stable

A month of days to choose from: the WAI-ARIA date picker grid, with today named and unavailable days said.

npx shadcn add @klarhimmel/calendar

When to use

  • Use for

    Choosing a day when seeing the month helps: a booking, a deadline.

  • Not for

    A date people already know. Use Date picker, so they can type it.

  • Pairs with

    Date picker, Popover, a status line.

Preview

November 2026

MonTueWedThuFriSatSun

Chosen: 2026-11-18. Arrow keys move, Page Up and Page Down change month.

calendar.tsx
import { Theme } from '@/components/klarhimmel/theme/style';
import { Calendar } from '@/components/klarhimmel/ui/calendar';

export default function Example() {
  return (
    <Theme theme="brand">
      <Calendar defaultValue="2026-11-20" today="2026-11-16" />
    </Theme>
  );
}

Install

Import

import { Calendar } from '@/components/klarhimmel/ui/calendar';
Lands in
components/klarhimmel/ui/calendar.tsx, plus cn() and the theme item if they are missing. Import theme.css after Tailwind.
Render in
Render it inside <Theme>, once near the root of your app. Tokens and fonts are scoped to it, so outside it the component is unstyled.

Examples

  • Limits

    November 2026

    MonTueWedThuFriSatSun

    Nothing before today, nothing after 20 December, and no weekends. Those days are struck through and cannot be chosen, but arrows still pass over them.

    import { Calendar } from '@/components/klarhimmel/ui/calendar';
    
    const weekend = (iso: string) => [0, 6].includes(new Date(`${iso}T00:00:00Z`).getUTCDay());
    
    export default function CalendarLimits() {
      return (
        <div className="flex flex-col gap-3">
          <Calendar defaultValue="2026-11-18" today="2026-11-16" min="2026-11-16" max="2026-12-20" isDisabled={weekend} aria-label="Weekdays in the next five weeks" />
          <p className="max-w-xs text-kh-small text-kh-muted">Nothing before today, nothing after 20 December, and no weekends. Those days are struck through and cannot be chosen, but arrows still pass over them.</p>
        </div>
      );
    }
  • Sunday

    november 2026

    sönmåntisonstorsfrelör

    Swedish names, weeks starting on Sunday, and your own button words.

    import { Calendar } from '@/components/klarhimmel/ui/calendar';
    
    export default function CalendarSunday() {
      return (
        <div className="flex flex-col gap-3">
          <Calendar defaultValue="2026-11-18" today="2026-11-16" firstDay="sun" locale="sv" labels={{ previous: 'Föregående månad', next: 'Nästa månad', today: 'idag' }} />
          <p className="text-kh-small text-kh-muted">Swedish names, weeks starting on Sunday, and your own button words.</p>
        </div>
      );
    }

API reference

PropTypeDefaultDescription
value / defaultValue / onValueChangestring / (value: string) => void-The chosen day as 'YYYY-MM-DD'; '' means none. Controlled or uncontrolled.
month / onMonthChangestring / (month: string) => voidthe chosen day's monthThe month shown, 'YYYY-MM'.
min / max / isDisabledstring / string / (iso: string) => boolean-Days that cannot be chosen are struck through and aria-disabled; arrows still pass over them.
todaystring-Today as 'YYYY-MM-DD': ringed and named. Never read from the clock here, so server and browser agree.
firstDay / locale'mon' | 'sun' / string'mon' / 'en'Where the week starts; the language names are written in.
labels{ previous; next; today }English wordsThe two month buttons and the word added to today's name. Pass them translated.
autoFocus / aria-labelboolean / string- / the monthFocus the day on mount (a calendar opened from a button); a name when the month heading is not enough.
classNamestring-Extra classes, merged after the component's own.

Accessibility

KeyDoes
TabEnters the grid on one day (the chosen day, else today)
Left / RightA day back or forward, across months
Up / DownA week back or forward
Home / EndThe start or the end of the week
Page Up / Page DownA month back or forward; with Shift, a year
Enter / SpaceChooses the day

The WAI-ARIA date picker grid. The month is announced when it changes; days that cannot be chosen stay focusable, say so, and are struck through.

Accessibility