Custom Components
Use the components prop when styling hooks are not enough and you need to
replace internal parts with your own React components.
Component structure
<CalendarContainer>
<MonthContainer>
<MonthArrowBack />
<MonthContent />
<MonthArrowNext />
</MonthContainer>
<WeekContainer>
<WeekContent />
</WeekContainer>
<DaysContainer>
<DayContainer>
<DayContent />
<DayToday />
<DaySelection />
<DayReservation />
</DayContainer>
</DaysContainer>
</CalendarContainer>
Custom component overrides
Swap only the internal pieces you need while keeping the booking logic and state model intact.
import {
Calendar,
DaySelectionProps,
MonthContentProps,
} from "@demark-pro/react-booking-calendar";
const MonthContent = ({
month,
year,
options,
innerProps,
getClassNames,
}: MonthContentProps) => {
const { className = "", ...restInnerProps } = innerProps ?? {};
return (
<div
className={getClassNames("MonthContent", className)}
{...restInnerProps}
>
{new Date(year, month).toLocaleDateString(options?.locale, {
month: "short",
calendar: "gregory",
})}
<strong>
{new Intl.NumberFormat(options?.locale, {
useGrouping: false,
}).format(year)}
</strong>
</div>
);
};
const DaySelection = ({
state,
innerProps,
getClassNames,
}: DaySelectionProps) => {
const { className = "", ...restInnerProps } = innerProps ?? {};
if (!state.isSelected && !state.isSelectedStart && !state.isSelectedEnd) {
return null;
}
return (
<div
className={getClassNames("DaySelection", className)}
{...restInnerProps}
>
{state.isSelectedStart ? "Start" : state.isSelectedEnd ? "End" : "Stay"}
</div>
);
};
<Calendar
range
selected={selected}
reserved={reserved}
onChange={setSelected}
components={{
MonthContent,
DaySelection,
}}
/>;
Event markers under dates
This pattern works well for booking dashboards, events calendars, and internal ops views where each day needs extra status markers below the date label.
Events calendar with markers
A custom `DayContent` override can keep the default selection behavior and still render event dots under each date.
import { useState } from "react";
import { Calendar } from "@demark-pro/react-booking-calendar";
const events = [
{ date: new Date(2030, 4, 12), color: "#0d8b84" },
{ date: new Date(2030, 4, 12), color: "#f6b048" },
{ date: new Date(2030, 4, 14), color: "#f36c3d" },
];
const dayKey = (date) =>
String(date.getFullYear()) +
"-" +
String(date.getMonth()) +
"-" +
String(date.getDate());
const markersByDay = events.reduce((acc, item) => {
const key = dayKey(item.date);
if (!acc[key]) acc[key] = [];
acc[key].push(item);
return acc;
}, {});
const DayContent = ({
children,
date,
state,
innerProps,
getClassNames,
}) => {
const { className = "", ...restInnerProps } = innerProps ?? {};
const markers = markersByDay[dayKey(date)] ?? [];
return (
<div className={getClassNames("DayContent", className)} {...restInnerProps}>
<span>{children}</span>
{state.isSameMonth && markers.length > 0 ? (
<span>
{markers.slice(0, 3).map((marker, index) => (
<span
key={index}
style={{ backgroundColor: marker.color }}
/>
))}
</span>
) : null}
</div>
);
};
<Calendar
selected={selected}
onChange={setSelected}
components={{ DayContent }}
/>;
Important rule
Define replacement components outside the render path. Recreating them inline on every render can cause remounts and state loss.
If your override formats built-in calendar dates, keep the output on the Gregorian calendar so it stays aligned with the rendered grid.
Using innerProps
Every replacement component receives the functional props it needs through
innerProps. Spread them unless you intentionally want to replace behavior:
const DaySelection = ({ innerProps, getClassNames, state }) => {
const { className = "", ...restInnerProps } = innerProps ?? {};
if (!state.isSelected && !state.isSelectedStart && !state.isSelectedEnd) {
return null;
}
return (
<div
className={getClassNames("DaySelection", className)}
{...restInnerProps}
/>
);
};
Exported prop types
The package exports prop types for the replaceable parts, including:
CalendarContainerPropsMonthContentPropsWeekContentPropsDayContentPropsDaySelectionPropsDayReservationPropsDayTodayProps
That makes it easier to write strongly typed overrides in TypeScript apps.