Skip to content

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

Description

@Togetic

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

<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:

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions