ExpandableCalendar: support month-based navigation when in closed (week) mode
Title: ExpandableCalendar: add arrowNavigationMode prop to support month-based arrow navigation in closed (week) mode
Problem When ExpandableCalendar is in the closed/collapsed (week) state, pressing the left/right arrows always advances by one week. This is hardcoded in scrollPage:
// index.js if (isOpen) { d.setDate(1); d.addMonths(next ? 1 : -1); // ✅ lands on 1st of month } else { const firstDayOfWeek = (next ? 7 : -7) - dayOfTheWeek + firstDay; d.addDays(firstDayOfWeek); // ❌ always advances by 1 week } There is also no way to override this from outside the component — _onPressArrowLeft/Right always calls scrollPage after your onPressArrowLeft/Right prop, so any custom handler you provide will be immediately overridden by the library's week-advance.
Use case A monthly budget/forecast screen that keeps the calendar collapsed to save space. Users expect the arrows to navigate by month, not by week — identical to the behavior the calendar already has when expanded.
What I tried Providing onPressArrowLeft/Right to set state to the 1st of the previous/next month — but the library also calls scrollPage after the prop fires, causing a race condition that snaps the calendar back or creates an infinite onMonthChange loop.
Proposed solution A new prop arrowNavigationMode?: 'week' | 'month' (default 'week' for backwards compatibility). When set to 'month', scrollPage uses the same month-navigation branch regardless of open/closed state.
Implementation The change is 3 lines across 2 files:
src/expandableCalendar/index.js
- horizontal = true, ..., testID, ...others } = props;
- horizontal = true, ..., testID, arrowNavigationMode = 'week', ...others } = props;
- if (isOpen) {
- if (isOpen || arrowNavigationMode === 'month') {
- }, [horizontal, isOpen, firstDay, numberOfDays, setDate, date]);
}, [horizontal, isOpen, arrowNavigationMode, firstDay, numberOfDays, setDate, date]); src/expandableCalendar/index.d.ts
/** Controls arrow navigation granularity in closed mode. 'week' (default) advances by one week; 'month' advances to the 1st of the next/previous month */
arrowNavigationMode?: 'week' | 'month'; Usage
<ExpandableCalendar arrowNavigationMode="month" onMonthChange={({ year, month }) => setSelectedDate(new Date(year, month - 1, 1))} /> Version [email protected]
Source: wix/react-native-calendars