Skip to main content

Built-in Selectors

Pre-built selector functions for the three most common views. Pass them to the matching use*CalendarSelector hook.

SingleRangeMultiple
selectSingleDaysselectRangeDaysselectMultipleDays
selectSingleMonthsselectRangeMonthsselectMultipleMonths
selectSingleYearsselectRangeYearsselectMultipleYears
selectSingleCanConfirmselectRangeCanConfirmselectMultipleCanConfirm

select*Days

Everything needed to render a month grid.

interface CalendarDaysView<TCell> {
weekdayLabels: readonly string[];
cells: readonly TCell[];
displayedMonthLabel: string;
displayedYearLabel: string;
}
function Grid() {
const days = useSingleCalendarSelector(selectSingleDays);
const { selectDate, goPrevMonth, goNextMonth } = useSingleCalendarActions();

return (
<View>
<Header
label={`${days.displayedMonthLabel} ${days.displayedYearLabel}`}
onPrev={goPrevMonth}
onNext={goNextMonth}
/>
<WeekdayRow labels={days.weekdayLabels} />
<DayGrid cells={days.cells} onSelect={selectDate} />
</View>
);
}

weekdayLabels are already rotated for firstDayOfWeek. cells always has 42 entries (6×7 grid).

Cell types

ModeTypeSelection fields
SingleSingleDayCellInfoisSelected
RangeRangeDayCellInfoinRange, isRangeStart, isRangeEnd
MultipleMultipleDayCellInfoisSelected

All share base day-cell fields. See DayCellInfo for the full interface.

select*Months

interface CalendarMonths {
months: readonly { index: number; label: string }[];
activeMonth: number; // 0-based
}
const { months, activeMonth } = useSingleCalendarSelector(selectSingleMonths);
const { selectMonth } = useSingleCalendarActions();

select*Years

interface CalendarYears {
years: readonly number[]; // 12-year page containing activeYear
activeYear: number;
}
const { years, activeYear } = useRangeCalendarSelector(selectRangeYears);
const { selectYear, prevYearPage, nextYearPage } = useRangeCalendarActions();

select*CanConfirm

const canConfirm = useMultipleCalendarSelector(selectMultipleCanConfirm);

<Button onPress={confirm} disabled={!canConfirm} title="Done" />;

Recomputes when the selection state that gates confirm() changes.

When to Write Your Own Selector

Built-ins cover the derived views the store already maintains. For everything else, pass an inline function:

const isHijri = useSingleCalendarSelector((s) => s.system.id === 'hijri');
const cellCount = useSingleCalendarSelector((s) => s.days.cells.length);

Keep returns narrow so unrelated store updates don't re-render your component.