events-calendar
Version:
A flexible, responsive, and feature-rich calendar component for modern React applications.
299 lines (275 loc) • 12.1 kB
TypeScript
import * as react from 'react';
import react__default, { Dispatch, MouseEvent, RefObject, SetStateAction, ReactNode } from 'react';
import dayjs, { Dayjs } from 'dayjs';
declare function setTime(date: Dayjs, time: Dayjs): Dayjs;
declare const CALENDAR_VIEWS: readonly ["year", "month", "week", "day"];
declare const MONTHS: readonly ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
declare const DAY_LABELS_SHORT: readonly ["S", "M", "T", "W", "T", "F", "S"];
declare const DAYS_IN_FULL_MONTH = 42;
declare const DEFAULT_COLOR = "#0ea5e9";
declare const HOURS: readonly ["1 AM", "2 AM", "3 AM", "4 AM", "5 AM", "6 AM", "7 AM", "8 AM", "9 AM", "10 AM", "11 AM", "12 PM", "1 PM", "2 PM", "3 PM", "4 PM", "5 PM", "6 PM", "7 PM", "8 PM", "9 PM", "10 PM", "11 PM"];
/**
* Checks if a date is between two other dates, inclusive of the start date,
* and optionally exclusive of the end date.
*
* @param date - The date to test.
* @param testStart - The start date of the range.
* @param testEnd - The end date of the range.
* @param startOnly - If true, only consider the start date as inclusive (default: false).
* @returns True if `date` is between `testStart` and `testEnd` (inclusive start, optional inclusive end).
*/
declare function isBetween(date: Dayjs, testStart: Dayjs, testEnd: Dayjs, startOnly?: boolean): boolean;
/**
* Checks if two date ranges overlap.
*
* Returns true if any part of the first range (start1 to end1)
* overlaps with the second range (start2 to end2).
*
* @param start1 - Start of the first date range
* @param end1 - End of the first date range
* @param start2 - Start of the second date range
* @param end2 - End of the second date range
* @returns `true` if the two date ranges overlap, otherwise `false`
*/
declare function hasOverlap(start1: Dayjs, end1: Dayjs, start2: Dayjs, end2: Dayjs): boolean;
interface updateDragNDropPlaceholderProps {
state: CalendarState;
dispatch: Dispatch<CalendarAction>;
date: Dayjs;
view: CalendarView;
}
declare function updateEvent({ state, dispatch, date, view }: updateDragNDropPlaceholderProps): void;
declare function getTimeDiff(dt1: Dayjs, dt2: Dayjs): number;
declare function getTimeLabel(event: CalendarEvent, timeDuration: number): string;
declare function filterByWeek<T extends CalendarEvent>(array: T[], weekStartDate: Dayjs): T[];
/**
* Filters a list of calendar events to include only those that occur on a given date.
*
* An event is included if the `date` is:
* - strictly between the event's `start` and `end` dates,
* - equal to the `start` date,
* - or equal to the `end` date.
*
* @param data - The list of calendar events to filter.
* @param date - The target date to match against event ranges.
* @returns An array of events that occur on the specified date.
*/
declare function filterByDate<T extends CalendarEvent>(data: T[], date: Dayjs): T[];
/**
* Filters events that overlap with the visible range of a calendar view (month or year).
*
* @template T - Optional custom data attached to the calendar event.
* @param {CalendarEvent<T>[]} events - List of calendar events.
* @param {Dayjs} activeDate - The current date used to determine the visible time range.
* @param {CalendarView} view - The current calendar view ('month' or 'year').
* @returns {CalendarEvent<T>[]} An array of events that overlap the given view range.
*/
declare function filterByView<T>(events: CalendarEvent<T>[], activeDate: Dayjs, view: CalendarView): CalendarEvent<T>[];
declare function parseRawEvents<T>(events: RawCalendarEvent<T>[]): CalendarEvent<T>[];
declare function getVisibleEvents<T extends OrderedCalendarEvent>(data: T[], date: Dayjs, maxEvents: number, isInDayHeader: boolean): T[];
declare function arrangeWeekEvents<T extends CalendarEvent>(weekEventsArray: T[]): (OrderedCalendarEvent & T)[];
declare const getPlaceholderEvent: (start: Dayjs, end: Dayjs, isTimeEntry?: boolean, isInitialisation?: boolean) => OrderedCalendarEvent;
declare function returnValidStartEnd(start: Dayjs, end: Dayjs): Dayjs[];
declare function arrangeWeekdayEvents<T extends CalendarEvent>(dayEvents: T[], date: Dayjs): (OrderedCalendarEvent & T)[];
declare const createDayjsObjFromTime: (startTime: string | null, endTime: string | null, startString?: string, endString?: string) => {
start: dayjs.Dayjs;
end: dayjs.Dayjs;
};
declare function getBackgroundFromGroups(groups?: CalendarGroup[]): react__default.CSSProperties;
type Month = (typeof MONTHS)[number];
type CalendarView = (typeof CALENDAR_VIEWS)[number];
type CalendarGroup = {
label: string;
color: string;
};
interface RawCalendarEventBase {
id?: number | null;
title?: string;
start?: string | number | Date | Dayjs;
end?: string | number | Date | Dayjs;
startTime?: string | null;
endTime?: string | null;
isAllDay?: boolean;
groups?: CalendarGroup[];
}
interface CalendarEventBase {
id: number | null;
title: string;
start: Dayjs;
end: Dayjs;
isAllDay: boolean;
startTime?: string | null;
endTime?: string | null;
isActive?: boolean;
groups?: {
label: string;
color: string;
}[];
dragId?: number | null;
}
interface OrderedCalendarEventBase extends CalendarEventBase {
order: number;
indent: number;
}
type RawCalendarEvent<T = object> = RawCalendarEventBase & T;
type CalendarEvent<T = object> = CalendarEventBase & T;
type OrderedCalendarEvent<T = object> = OrderedCalendarEventBase & T;
type SubmitType = 'create' | 'delete' | 'update';
type MouseEventHandler = {
(e: MouseEvent, date: Dayjs, isTimeEntry: boolean, placeholderRef: RefObject<HTMLDivElement | null>): void;
};
type DateRecord = {
date: Dayjs;
isCurrentMonth?: boolean;
};
interface MinMaxDatesInView {
first: Dayjs;
last: Dayjs;
}
type OverflowArrowType = 'both' | 'left' | 'right' | 'none';
interface MonthDates extends MinMaxDatesInView {
weeks: DateRecord[][];
}
interface EventsCalendarPopoverProps {
clickedEvent: CalendarEvent;
newEvent: CalendarEvent;
onClose: () => void;
}
interface EventsCalendarContextMenuProps {
event: CalendarEvent;
onClose: () => void;
openPopover: () => void;
closeContextMenu: () => void;
}
type CalendarActionType = 'reset_calendar' | 'set_clicked_event' | 'event_create_stop' | 'event_create_start' | 'update_event' | 'event_create_end' | 'open_overflow' | 'event_reschedule_start' | 'event_reschedule_end' | 'open_popover' | 'open_context_menu';
interface CalendarAction {
activeFilters?: string[];
activeGroups?: string[];
event?: CalendarEvent | OrderedCalendarEvent;
anchor?: HTMLDivElement | null;
date?: Dayjs;
newView?: CalendarView;
type: CalendarActionType;
dragStartOffset?: number | null;
}
interface CalendarState {
clickedEvent: CalendarEvent;
popoverIsOpen: boolean;
eventAnchor: HTMLDivElement | null;
dragActive: boolean;
firstClickDate: Dayjs | null;
placeholderEvent: OrderedCalendarEvent;
dragStartOffset: number | null;
eventDragActive: boolean;
overflowAnchor: HTMLDivElement | null;
overflowIsOpen: boolean;
}
type EventClickArgs<T> = {
event: CalendarEventBase & T;
isDoubleClick: boolean;
eventRef: HTMLDivElement;
openPopover: () => void;
closePopover: () => void;
togglePopover: () => void;
};
type EventEditProps = {
clickedEvent: CalendarEvent;
newEvent: CalendarEvent;
eventRef: HTMLDivElement;
openPopover: () => void;
reset: () => void;
};
type EventsCalendarObject = {
activeDate: Dayjs;
setActiveDate: Dispatch<SetStateAction<Dayjs>>;
view: CalendarView;
setView: Dispatch<SetStateAction<CalendarView>>;
state: CalendarState;
dispatch: Dispatch<CalendarAction>;
};
type useEventsCalendarProps = {
isInitialised?: boolean;
initialDate?: string | number | Date | Dayjs;
initialView?: CalendarView;
closeOnClickOutside?: boolean;
};
declare function useEventsCalendar({ isInitialised, initialDate, initialView, closeOnClickOutside, }?: Partial<useEventsCalendarProps>): EventsCalendarObject;
interface EventsCalendarProps<T extends RawCalendarEventBase = RawCalendarEventBase> {
/**
* Shared calendar state and methods, returned by `useEventsCalendar`.
*/
calendar?: EventsCalendarObject;
/**
* Renders a more compact layout, useful in constrained spaces.
* Affects padding, font size, and layout density.
*/
compact?: boolean;
/**
* Enables drag-to-create behavior for new events.
*/
enableDragCreation?: boolean;
/**
* Allows users to reschedule events by dragging.
*/
enableRescheduling?: boolean;
/**
* Array of event objects to be rendered in the calendar.
*/
events?: RawCalendarEvent<T>[];
/**
* Whether to show a loading spinner overlay on the calendar.
*/
isFetching?: boolean;
/**
* If true, hides the built-in calendar header (navigation + view toggle).
*/
noHeader?: boolean;
/**
* z-index used for the overflow popover that appears when clicking "+N more".
*/
overflowPopoverZIndex?: number;
/**
* z-index used for the event popover component.
*/
popoverZIndex?: number;
/**
* Calendar views available to the user (e.g. 'month', 'week', 'day', 'year').
* Defaults to all supported views.
*/
views?: CalendarView[];
/**
* Fired when an existing event is clicked.
*/
onEventClick?: (props: EventClickArgs<T>) => void;
/**
* Fired when a new event is created (e.g. via drag or click).
*/
onEventCreate?: (props: EventEditProps) => void;
/**
* Fired when an event is rescheduled (e.g. via drag).
*/
onEventReschedule?: (props: EventEditProps) => void;
/**
* Custom render function for the event popover.
*/
renderPopover?: (props: EventsCalendarPopoverProps) => ReactNode;
/**
* Custom render function for a context menu (e.g. right-click on event).
*/
renderContextMenu?: (props: EventsCalendarContextMenuProps) => ReactNode;
}
declare function EventsCalendar<T extends RawCalendarEvent = RawCalendarEventBase>({ calendar, compact, enableDragCreation, enableRescheduling, events, overflowPopoverZIndex, popoverZIndex, isFetching, noHeader, onEventClick, onEventCreate, onEventReschedule, renderPopover, renderContextMenu, views, }: EventsCalendarProps<T>): react.JSX.Element;
interface HeaderProps {
activeDate: dayjs.Dayjs;
view?: CalendarView;
hideViewToggle?: boolean;
maxDate?: dayjs.Dayjs | null;
minDate?: dayjs.Dayjs | null;
onClick?: () => void;
setActiveDate: Dispatch<SetStateAction<dayjs.Dayjs>>;
setView?: Dispatch<SetStateAction<CalendarView>>;
views?: CalendarView[];
customControls?: ReactNode;
}
declare function Header({ activeDate, onClick, hideViewToggle, setActiveDate, setView, views, view, customControls, }: HeaderProps): react.JSX.Element;
export { CALENDAR_VIEWS, type CalendarAction, type CalendarEvent, type CalendarEventBase, type CalendarGroup, type CalendarState, type CalendarView, DAYS_IN_FULL_MONTH, DAY_LABELS_SHORT, DEFAULT_COLOR, type DateRecord, type EventClickArgs, type EventEditProps, EventsCalendar, type EventsCalendarContextMenuProps, type EventsCalendarObject, type EventsCalendarPopoverProps, type EventsCalendarProps, HOURS, Header, MONTHS, type MinMaxDatesInView, type Month, type MonthDates, type MouseEventHandler, type OrderedCalendarEvent, type OrderedCalendarEventBase, type OverflowArrowType, type RawCalendarEvent, type RawCalendarEventBase, type SubmitType, arrangeWeekEvents, arrangeWeekdayEvents, createDayjsObjFromTime, filterByDate, filterByView, filterByWeek, getBackgroundFromGroups, getPlaceholderEvent, getTimeDiff, getTimeLabel, getVisibleEvents, hasOverlap, isBetween, parseRawEvents, returnValidStartEnd, setTime, updateEvent, useEventsCalendar, type useEventsCalendarProps };