Skip to main content

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.

Live example
Loading interactive preview...
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.

Live example
Loading interactive preview...
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:

  • PAST
  • BOOKED
  • BEFORE_START
  • AFTER_END
  • BOOKED_BETWEEN
  • DISABLED

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.