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 || 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
react-native-calendars@1.1313.0
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, 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
react-native-calendars@1.1313.0