CalendarList: allow substituting the internal FlatList (e.g. BottomSheetFlatList, FlashList)

Author: TogeticCreated Sep 1, 2026Updated Sep 1, 2026

Feature request

CalendarList renders its months into a hardcoded FlatList with no way to substitute a different list implementation:

https://github.com/wix/react-native-calendars/blob/master/src/calendar-list/index.tsx

typescript
<FlatList
  ref={list}
  windowSize={...}
  data={items}
  renderItem={renderItem}
  ...
/>

CalendarListProps already extends Omit<FlatListProps<any>, 'data' | 'renderItem'>, so every prop of the list is configurable — but the component itself isn't. There's no renderScrollComponent-style escape hatch either.

Why it matters

Several common setups need a different list component rather than different list props:

  • Nested scrolling containersBottomSheetFlatList from @gorhom/bottom-sheet, or any list that has to coordinate with a parent gesture handler. Passing a plain FlatList's props doesn't help; the container has to be the sheet's list or the inner scroll doesn't work.
  • Extra content inside the scroll area — our own case: we wrap the list to render a contextual notice above the months, inside the same scroll container, which ListHeaderComponent alone doesn't cover for our layout.
  • Alternative list enginesFlashList and similar, for long pastScrollRange / futureScrollRange values.

Today the only options are patching the package or forking CalendarList, both for what amounts to one indirection.

Proposed change

Accept an optional list component and default to FlatList, preserving current behaviour exactly:

typescript
export interface CalendarListProps extends CalendarProps, Omit<FlatListProps<any>, 'data' | 'renderItem'> {
  ...
  /** Custom list component to render the months into. Default = FlatList */
  List?: FC<FlatListProps<any>>;
}
typescript
const List = props.List ?? FlatList;

return (
  <View style={style.current.flatListContainer} testID={testID}>
    <List ref={list} ... />
    {renderStaticHeader()}
  </View>
);

That's the whole change — a prop, a default, and swapping the JSX tag. Fully backwards compatible: omitting List gives byte-identical behaviour to today, and every existing list prop keeps flowing through untouched.

Notes

  • We've run exactly this as a local patch for a while against 1.1314.0 with no issues, including the imperative scrollToDay / scrollToMonth methods, which keep working since the ref is forwarded unchanged.
  • Naming is yours to pick — List, ListComponent, renderScrollComponent (matching RN's own naming) would all work. Happy to open a PR in whichever shape you'd prefer, and to include the type as ComponentType<FlatListProps<any>> if you'd rather not narrow it to FC.

Source: wix/react-native-calendars