@innosolutions/inno-calendar
v1.0.37
Published
A headless-first, fully customizable React calendar
Readme
@inno/calendar
A headless-first, fully customizable React calendar for enterprise applications.
🤖 AI Agents: For comprehensive implementation details, copy the contents of AGENT.md into your context.
Installation
npm install @innosolutions/inno-calendar# Optional: Radix UI for enhanced popovers/tooltips
npm install @radix-ui/react-popover @radix-ui/react-tooltip @radix-ui/react-dropdown-menuQuick Start
import { InnoCalendar, type CalendarEvent } from "@innosolutions/inno-calendar";
import "@innosolutions/inno-calendar/styles";
const events: CalendarEvent[] = [
{
id: "1",
title: "Team Meeting",
startDate: new Date("2026-02-04T09:00:00"),
endDate: new Date("2026-02-04T10:00:00"),
color: "blue",
},
];
function MyCalendar() {
return (
<InnoCalendar
events={events}
initialView="week"
onEventClick={(event) => console.log(event)}
onSlotSelect={(selection) =>
console.log(selection.startDate, selection.endDate)
}
/>
);
}Features
- 8 View Modes — Day, Week, Month, Year, Agenda, Timeline (1/3/7 day)
- Headless Architecture — Use hooks directly or pre-built components
- Drag & Drop — Drag to select time ranges, drag events to reschedule
- TypeScript — Fully typed with generic event data support
- Customizable — Custom popovers, settings panels, filters
- No External Dependencies — Native Date API, minimal footprint
Views
| View | Description |
| --------------- | -------------------------- |
| day | Single day hourly grid |
| week | 7-day grid with time slots |
| month | Monthly calendar |
| year | 12-month overview |
| agenda | Scrollable event list |
| timeline-day | Resource timeline (1 day) |
| timeline-3day | Resource timeline (3 days) |
| timeline-week | Resource timeline (7 days) |
Event Structure
interface CalendarEvent<TData = Record<string, unknown>> {
// Required
id: string;
title: string;
startDate: Date;
endDate: Date;
// Optional display fields
color?:
| "blue"
| "green"
| "red"
| "yellow"
| "purple"
| "orange"
| "pink"
| "teal"
| "gray"
| "indigo";
hexColor?: string; // Hex override (takes precedence over color)
description?: string;
isCanceled?: boolean;
isAllDay?: boolean;
isMultiDay?: boolean;
isRecurring?: boolean;
resourceId?: string; // For resource/timeline views
// Built-in filtering (optional — skip if you filter server-side)
scheduleTypeId?: number;
scheduleTypeName?: string;
participants?: ICalendarUser[];
// @deprecated — still functional, but migrate to `data` bag.
// Will be removed in the next major version.
meetingTookPlace?: boolean; // → data.meetingTookPlace
isAccepted?: boolean; // → data.isAccepted
companyId?: number; // → data.companyId
cancelReason?: string | null; // → data.cancelReason
user?: ICalendarUser; // → data.user
// ... and others (see types.ts for full list)
data?: TData; // Your custom domain-specific fields (RECOMMENDED)
}Props
<InnoCalendar
// Data
events={events}
users={users}
scheduleTypes={scheduleTypes}
// Initial State
initialView="week"
initialDate={new Date()}
// Callbacks
onEventClick={(event) => {}}
onSlotSelect={(selection) => {}}
onSlotClick={(date, hour) => {}}
onAddEvent={() => {}}
onEventDrop={(result) => {}}
onDateChange={(date, view) => {}}
onViewChange={(view) => {}}
// Customization
renderPopover={({ event, onClose }) => <CustomPopover />}
settingsContent={<SettingsPanel />}
filterContent={<FiltersRow />}
showHeader={true}
/>Provider Pattern
For shared state across components:
import {
InnoCalendarProvider,
useInnoCalendar,
CalendarHeader,
WeekView,
} from "@innosolutions/inno-calendar";
function App() {
return (
<InnoCalendarProvider initialEvents={events} initialView="week">
<CalendarContent />
</InnoCalendarProvider>
);
}
function CalendarContent() {
const { view, filteredEvents, selectedDate } = useInnoCalendar();
return (
<>
<CalendarHeader />
<WeekView events={filteredEvents} date={selectedDate} />
</>
);
}Working Hours
const workingHours = {
0: { enabled: false, from: 8, to: 17 }, // Sunday
1: { enabled: true, from: 9, to: 18 }, // Monday
2: { enabled: true, from: 9, to: 18 }, // Tuesday
3: { enabled: true, from: 9, to: 18 }, // Wednesday
4: { enabled: true, from: 9, to: 18 }, // Thursday
5: { enabled: true, from: 9, to: 17 }, // Friday
6: { enabled: false, from: 8, to: 12 }, // Saturday
};
<InnoCalendar
events={events}
preferencesConfig={{
defaults: { workingHours },
}}
/>;Styles
Import the bundled styles for proper rendering:
import "@innosolutions/inno-calendar/styles";Or include CSS custom properties for theming:
:root {
--inno-border-color: #e5e7eb;
--inno-primary: #3b82f6;
--inno-hour-height: 96px;
}TypeScript
import type {
CalendarEvent,
TCalendarView,
TEventColor,
ICalendarUser,
IScheduleType,
ISelectionResult,
TWorkingHours,
} from "@innosolutions/inno-calendar";License
MIT © InnoSolutions
