RangeCalendar
A grid of the days of a month, to pick a range of dates.
Stay, October 2026
October 2026
| S | M | T | W | T | F | S |
|---|---|---|---|---|---|---|
27 | 28 | 29 | 30 | 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Pick the first night, then the last.
<script>
import { $bind, $signal } from 'brumate/signals';
import Button from '@brumate/ui/Button.brm';
import CalendarGrid from '@brumate/ui/CalendarGrid.brm';
import CalendarHeading from '@brumate/ui/CalendarHeading.brm';
import RangeCalendar from '@brumate/ui/RangeCalendar.brm';
let stay = $signal<{ start: string; end: string } | null>(null);
</script>
<RangeCalendar class="ui-calendar" aria-label="Stay" value=$bind(stay)>
<header>
<Button slot="previous" class="ui-button ui-icon-button">‹</Button>
<CalendarHeading />
<Button slot="next" class="ui-button ui-icon-button">›</Button>
</header>
<CalendarGrid />
</RangeCalendar>
<p>{stay ? `From ${stay.start} to ${stay.end}.` : 'Pick the first night, then the last.'}</p>
<RangeCalendar aria-label="Stay" value=$bind(stay)>
<header>
<Button slot="previous">‹</Button>
<CalendarHeading />
<Button slot="next">›</Button>
</header>
<CalendarGrid />
</RangeCalendar>
- A
RangeCalendarholds the same parts as a Calendar: aCalendarHeading, two Buttons withslot="previous"andslot="next", and aCalendarGridfor each month that shows. valueis the selected range, as{ start, end }ofYYYY-MM-DDdates, or null. It starts its own state, or binds with$bind. See State.onChangegets each range that is picked.- The other props are those of Calendar, such as
minValue,maxValue,isDateUnavailableandvisibleDuration.
Picking a range
- A first press, or Enter or Space, starts a range at a date. A second one ends it, before or after the first.
- A press of the pointer on a date and a release on another one select the range between them.
- After Enter or Space starts a range, focus moves to the next date, or the one before.
- In between, the dates show the range to the date under the pointer, or to the date that has focus. The date under the pointer takes the focus.
- The range reaches up to the nearest dates that cannot be picked. The dates past them show
data-invalidand cannot be picked or focused, and the Calendar is not invalid until the range is done.isDateUnavailablegets the first date of the range as its second argument. - Escape drops a range that is not done, and the range that was selected shows again.
- A range cannot hold a date that
isDateUnavailablemarks.allowsNonContiguousRangeslets it, and those dates do not show as selected.
Cells
- A date in the range shows
data-selected. The first date showsdata-selection-start, and the lastdata-selection-end. - The cells show the other states of a Calendar cell. See Cells.