Skip to content

Types

import type {
Resource,
SchedulerEvent,
SlotSelection,
ResourceSchedulerProps,
Placement,
PlacementRules,
SlotOptions,
} from "resource-scheduler";
import { ViewType } from "resource-scheduler";

A const object and a union type of the same name:

const ViewType = {
Day: "day",
Week: "week",
Month: "month",
Quarter: "quarter",
Year: "year",
} as const;
type ViewType = (typeof ViewType)[keyof typeof ViewType];
interface Resource {
id: string;
name: string;
role?: string;
events?: SchedulerEvent[]; // optional when you pass the flat `events` prop
businessHours?: BusinessHours | false; // overrides the prop; false = always available
unavailable?: UnavailableRange[]; // time off, shaded in the grid
capacity?: number; // simultaneous bookings, for utilization only. Default 1
group?: string | string[]; // header name, or a path to nest it: ["Building", "Floor 1"]
}
interface BusinessHours {
daysOfWeek?: number[]; // 0 = Sunday. Default [1, 2, 3, 4, 5]
startHour?: number; // day view only. Default 9
endHour?: number; // exclusive. Default 17
}
interface UnavailableRange {
start: Date;
end: Date; // exclusive
}
interface SchedulerEvent {
id: string;
title: string;
startDate: Date;
endDate: Date; // exclusive
color?: string;
description?: string;
resourceId?: string; // only in the flat `events` prop: the resource it belongs to
resourceIds?: string[]; // ...or several
recurrence?: Recurrence; // makes it repeat
seriesId?: string; // set on an occurrence: the id of the event it comes from
}
interface Recurrence {
freq: "hourly" | "daily" | "weekly" | "monthly" | "yearly";
interval?: number; // every n periods. Default 1. Hourly counts elapsed time
byWeekday?: number[]; // weekly, monthly, yearly; 0 = Sunday
byMonthDay?: number[]; // monthly, yearly: 1 to 31, or -1 (last day) from the end
bySetPos?: number[]; // monthly, yearly: 1 first, -1 last of what byWeekday/byMonthDay give
until?: Date; // last day it may start on, inclusive (hourly: the last moment)
count?: number; // total occurrences, counting the first
exceptions?: Date[]; // days to skip (hourly: exact starts)
}

Event is a deprecated alias of SchedulerEvent. Handlers receive a Resource whose events is always an array; the optional events above is the input type, exported as ResourceInput.

What onSlotSelect receives:

interface SlotSelection {
resourceId: string;
start: Date;
end: Date; // exclusive
}

Used by the conflict rules and by isPlacementAllowed:

interface Placement {
resourceId: string;
start: Date;
end: Date;
}
interface PlacementRules {
eventOverlap?: boolean | ((moving: SchedulerEvent, other: SchedulerEvent) => boolean);
isValidDrop?: (event: SchedulerEvent, placement: Placement) => boolean;
}

The parts you can replace with the components prop. See Replace parts.

interface SchedulerComponents {
Toolbar?: React.ComponentType<ToolbarProps>;
Event?: React.ComponentType<{ event: SchedulerEvent; resource: Resource }>;
EventPopover?: React.ComponentType<{ event: SchedulerEvent; resource: Resource; close: () => void }>;
ResourceHeader?: React.ComponentType<{ resource: Resource }>;
DateHeader?: React.ComponentType<{ date: Date; view: ViewType }>;
EmptyCell?: React.ComponentType<{ date: Date; resource: Resource }>;
}
interface ToolbarProps {
title: string; // the period as the locale writes it: "Oct 5 – Oct 9, 2026"
viewTitle: string; // "Week View"
views: ViewType[]; // availableViews, or all of them
labels: SchedulerLabels;
dir: "ltr" | "rtl";
currentDate: Date;
viewType: ViewType;
onNavigate: (direction: "prev" | "next") => void;
onViewChange: (view: ViewType) => void;
onGoToToday: () => void;
allowViewChange?: boolean;
availableViews?: ViewType[];
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
hideWeekends?: boolean;
}
interface SlotOptions {
slotDuration?: number;
dayStartHour?: number;
dayEndHour?: number;
}