Skip to content

ExpandableCalendar: support month-based navigation when in closed (week) mode #2773

Description

@deezyomar

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions