Status Calendar
openstatus/status-calendarFreeBlock
Monthly calendar view of status history with per-day markers and event hover cards
Install it
npx shadcn@latest add https://openstatus.dev/r/status-calendar.jsonSource
1"use client";23import { StatusBarCard } from "@/components/blocks/status-bar";4import { useStatusBlocksLabels } from "@/components/blocks/status-i18n";5import type {6 StatusBarData,7 StatusEventType,8 StatusType,9} from "@/components/blocks/status.types";10import { Button } from "@/components/ui/button";11import {12 HoverCard,13 HoverCardContent,14 HoverCardTrigger,15} from "@/components/ui/hover-card";16import { Separator } from "@/components/ui/separator";17import { Skeleton } from "@/components/ui/skeleton";18import { useMediaQuery } from "@/hooks/use-media-query";19import { cn } from "@/lib/utils";20import {21 type Locale,22 addMonths,23 format,24 isSameDay,25 startOfDay,26 startOfMonth,27 subMonths,28} from "date-fns";29import { ChevronLeft, ChevronRight } from "lucide-react";30import {31 type FocusEvent,32 type ReactNode,33 type RefObject,34 forwardRef,35 useCallback,36 useEffect,37 useMemo,38 useRef,39 useState,40} from "react";41import { DayPicker, type DayProps } from "react-day-picker";4243type BarEvent = StatusBarData["events"][number];4445export interface StatusCalendarMarker {46 id: string | number;47 /** Day this marker belongs to, in the viewer's local timezone. */48 date: Date;49 /** Drives the day cell's tinted-fill color (worst-severity wins per day). */50 status: Exclude<StatusType, "empty">;51 /** Event shape mirrors StatusBarEvent so the popover can render the same row. */52 type: StatusEventType;53 name: string;54 /** Full event range (use the event's true start/end, not the per-day instance). */55 from?: Date | null;56 to?: Date | null;57 isAggregated?: boolean;58 href?: string;59}6061export interface StatusCalendarProps {62 markers: StatusCalendarMarker[];63 /** Controlled month. Defaults to the first of the current month. */64 month?: Date;65 defaultMonth?: Date;66 onMonthChange?: (month: Date) => void;67 /** 0 = Sunday, 1 = Monday. Mockup shows Monday. */68 weekStartsOn?: 0 | 1;69 /**70 * Treat the calendar as status history: render days after the latest event71 * (or today, whichever is later) as disabled. Days up to and including that72 * boundary — including scheduled future events — stay interactive. Forward73 * navigation is still capped at the latest event's month. Defaults to false.74 */75 disableFuture?: boolean;76 className?: string;77 /** Calendar header label on the left side of the chrome. */78 title?: ReactNode;79 /**80 * date-fns Locale used by DayPicker for weekday/month names. Callers should81// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from openstatus
All 26 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Status Bannerstatus-banner | openstatus | Blocks | Free | no deps | |
| Status Barstatus-bar | openstatus | Blocks | Free | 1 dep | |
| Status Blank Statesstatus-blank | openstatus | Blocks | Free | no deps | |
| Status Page Chromestatus-chrome | openstatus | Blocks | Free | no deps | |
| Status Page (Complete)status-complete | openstatus | Blocks | Free | no deps | |
| Status Componentstatus-component | openstatus | Blocks | Free | 2 deps | |
| Status Component Groupstatus-component-group | openstatus | Blocks | Free | no deps | |
| Status Page (Essentials)status-essentials | openstatus | Blocks | Free | no deps |
