KQ-1349 · CALENDAR/APP

Calendar App

A complete calendar screen built around week-planner and meeting-card: a month grid and the week that morph into each other — the week you are in is a row of the month, so Week grows that row to fill the grid on glide while the other weeks fold away, then the planner cross-fades in over it, and Month runs it back — with a view switch whose pill travels on snap, months that slide in from 16px, a sidebar of mini month, calendars and the day ahead, and an event drawer that docks on glide, slides over or rises as a sheet you can pull down 1:1. Everything is read against `now`. The month is a real grid: arrows, Home, End and Page keys move the day, Enter steps into its events and Escape steps back out.

KQ-1349 · CALENDAR/APP

October 2026

Mon
Tue
Wed
Thu
Fri
Sat
Sun
+1
+1
+2

                      Arrow keys move the day, Home and End to the week's ends, Page Up and Page Down a month. Enter steps into the day's events, Escape steps back out.

                      drawer open · design review · escape closes

                      Install

                      One command — the source lands in your repo. Or copy it from the Code tab.

                      $ pnpm dlx shadcn@latest add @kinetiq/calendar-app

                      Props

                      view / defaultView
                      "month" | "week"
                      default "month"
                      The month, or the focused day's week; changing it runs the morph.
                      onViewChange
                      (view: CalendarView) => void
                      default —
                      Fires from the switch, a day's number or Show in week.
                      drawer
                      "side" | "over" | "sheet"
                      default "side"
                      How the event drawer arrives: docked at the right (the calendar narrows), over the calendar above a scrim, or as a sheet from the bottom that pulls down. A phone always uses the sheet.
                      density
                      "compact" | "cozy" | "roomy"
                      default "cozy"
                      Month chips (two plain, three with times on wide grids, or three filled) and week-planner's hour height.
                      events / defaultEvents
                      CalendarEvent[]
                      default defaultCalendarEvents
                      Week-planner events with optional attendees, agenda and notes; an event with attendees opens as a meeting card.
                      onEventsChange
                      (events: CalendarEvent[]) => void
                      default —
                      Fires from the drag, edit, creation or deletion that changed the events, with all of them.
                      calendars
                      WeekCalendar[]
                      default defaultCalendarCalendars
                      The calendars events belong to, with their tints (CSS colours, never hex).
                      hidden / defaultHidden
                      string[]
                      default []
                      Calendar ids whose events are hidden everywhere.
                      onHiddenChange
                      (ids: string[]) => void
                      default —
                      Fires from the calendar checkboxes.
                      day / defaultDay
                      Date | number
                      default the day of `now`
                      The focused day: the month and the week shown, and the day the agenda reads.
                      onDayChange
                      (day: number) => void
                      default —
                      Fires with the new day's midnight from the grid, the mini month, the arrows, Today or the planner.
                      selected / defaultSelected
                      string | null
                      default null
                      The event in the drawer, or null for a closed drawer.
                      onSelectedChange
                      (id: string | null) => void
                      default —
                      Fires from a chip, an agenda row, a planner event, Close, Escape, the scrim or the pull.
                      now
                      Date | number
                      default defaultCalendarNow
                      The current moment: today, the now line, the agenda's Now and countdowns, and the meeting card's ring. Never read from the clock during render.
                      zoneOffset
                      number
                      default 0
                      Minutes east of UTC that dates and times are drawn in, so server and browser agree.
                      weekStartsOn
                      0 | 1
                      default 1
                      1 starts weeks on Monday, 0 on Sunday.
                      onCreate
                      (event: CalendarEvent) => void
                      default —
                      An event was drawn or added in the week.
                      onDelete
                      (event: CalendarEvent) => void
                      default —
                      An event was deleted from the drawer or the week.
                      onJoinedChange
                      (id: string, joined: boolean) => void
                      default —
                      The viewer joined or left a meeting from its card.
                      status
                      "ready" | "loading" | "error"
                      default "ready"
                      Loading draws placeholder chips; error offers Try again.
                      onRetry
                      () => void
                      default —
                      Try again was pressed in the error state.
                      label
                      string
                      default "Calendar"
                      The screen's accessible name.
                      sound
                      boolean
                      default false
                      Play a swish for the morph, the drawer and the sidebar and a tick for each step of the day cursor; the composed pieces play their own. Off unless asked for.
                      disabled
                      boolean
                      default false
                      Read only: nothing can be moved, made or deleted.
                      className
                      string
                      default —
                      Classes for the root. It is 560px tall by default; pass a height class to change it.