Selection and Protection
The package is designed around booking behavior, not just generic date picking. That means selection and reservation rules are first-class parts of the API.
Default protection behavior
With protection enabled, the calendar prevents selection when the clicked day is:
- in the past
- reserved
- before an already selected start date
- after an already selected end date
- separated from the selected range by a reserved interval
Range mode
Set range to true when you want a start and end date:
<Calendar range selected={selected} onChange={setSelected} />
In range mode, the component waits for a valid second click before completing the selection.
Range selection with protection
The range flow waits for two valid dates and reports why blocked clicks were rejected.
import { useState } from "react";
import { Calendar } from "@demark-pro/react-booking-calendar";
export function RangeCalendar() {
const [selected, setSelected] = useState([null, null]);
const [message, setMessage] = useState(null);
return (
<Calendar
range
selected={selected}
reserved={reserved}
onChange={(nextValue) => {
setSelected(nextValue);
setMessage(null);
}}
onOverbook={(_date, overbookType) => {
setMessage(overbookType);
}}
/>
);
}
Using date and time values
The calendar accepts full Date values, not just day-only dates. That means
you can store check-in and check-out times directly in reserved and keep them
in the selected range.
Date and time booking values
`reserved` and `selected` accept full `Date` values, so the calendar can preserve check-in and check-out times.
import { useState } from "react";
import { Calendar } from "@demark-pro/react-booking-calendar";
const reserved = [
{
startDate: new Date(2030, 4, 12, 14, 0),
endDate: new Date(2030, 4, 14, 10, 0),
},
{
startDate: new Date(2030, 4, 17, 14, 0),
endDate: new Date(2030, 4, 19, 10, 0),
},
];
export function DateTimeCalendar() {
const [selected, setSelected] = useState([
reserved[0].endDate,
reserved[1].startDate,
]);
return (
<Calendar
range
selected={selected}
reserved={reserved}
onChange={setSelected}
/>
);
}
Handling blocked clicks
Use onOverbook to react when a click is rejected:
<Calendar
onOverbook={(date, overbookType) => {
console.log("Blocked selection", date, overbookType);
}}
/>
The exported OverbookTypes union includes:
PASTBOOKEDBEFORE_STARTAFTER_ENDBOOKED_BETWEENDISABLED
Turning protection off
You can disable reservation protection entirely:
<Calendar protection={false} />
That allows selection across reserved intervals, while disabled rules still
apply. This is useful for review tools and internal admin flows, but it is
usually the wrong setting for customer-facing booking forms.