MarceloPrado / flash-calendar

The fastest React Native calendar 📆⚡
https://marceloprado.github.io/flash-calendar/
MIT License
1.05k stars 31 forks source link

Bug: ref scrollToDate sometimes scroll past the desired date #18

Closed MarceloPrado closed 4 months ago

MarceloPrado commented 8 months ago

TODO: add better issue description

subramanian-elavathur commented 8 months ago

We faced this issue with v0.0.6 of the library but I am not able to reproduce it in v0.0.7.

I am sharing the some details from our bug investigation done on v0.0.6, in case it helps with your issue here.

Code to reproduce

import {
  Calendar,
  CalendarListRef,
  toDateId,
} from '@marceloterreiro/flash-calendar';
import {addWeeks, endOfWeek, startOfWeek} from 'date-fns';
import React, {useCallback, useRef, useState} from 'react';
import {Text, TouchableOpacity, View} from 'react-native';
import {SafeAreaView} from 'react-native-safe-area-context';

const today = toDateId(new Date());

const getWeekStartOrEnd = (dateId: string, weekEnd?: boolean): string => {
  const weekCalculator = weekEnd ? endOfWeek : startOfWeek;
  return toDateId(
    weekCalculator(dateId, {
      weekStartsOn: 1,
    }),
  );
};

export function BasicCalendarList() {
  const [selectedDate, setSelectedDate] = useState<string>(today);
  const [weekStart, setWeekStart] = useState<string>(getWeekStartOrEnd(today));
  const [weekEnd, setWeekEnd] = useState<string>(
    getWeekStartOrEnd(today, true),
  );
  const ref = useRef<CalendarListRef>(null);

  const onDateChange = useCallback((dateId: string) => {
    setSelectedDate(dateId);
    setWeekStart(getWeekStartOrEnd(dateId));
    setWeekEnd(getWeekStartOrEnd(dateId, true));
  }, []);

  return (
    <SafeAreaView
      style={{
        flex: 1,
        gap: 20,
        backgroundColor: 'white',
      }}>
      <Text style={{textAlign: 'center', fontWeight: 'bold'}}>
        Selected date: {selectedDate}
      </Text>
      <Calendar.List
        calendarActiveDateRanges={[
          {
            startId: weekStart,
            endId: weekEnd,
          },
        ]}
        calendarFirstDayOfWeek="monday"
        calendarInitialMonthId={selectedDate}
        calendarMinDateId={'2023-02-27'}
        onCalendarDayPress={onDateChange}
        ref={ref}
      />
      <View style={{flexDirection: 'row', gap: 20, justifyContent: 'center'}}>
        <TouchableOpacity
          onPress={() => {
            const previousWeek = addWeeks(selectedDate, -1);
            onDateChange(toDateId(previousWeek));
            ref?.current?.scrollToDate(previousWeek, true);
          }}
          style={{backgroundColor: '#DCB3E3', padding: 5, borderRadius: 5}}>
          <Text>Previous</Text>
        </TouchableOpacity>
        <TouchableOpacity
          onPress={() => {
            onDateChange(toDateId(new Date()));
            ref?.current?.scrollToDate(new Date(), true);
          }}
          style={{backgroundColor: '#DCB3E3', padding: 5, borderRadius: 5}}>
          <Text>Today</Text>
        </TouchableOpacity>
        <TouchableOpacity
          onPress={() => {
            const nextWeek = addWeeks(selectedDate, 1);
            onDateChange(toDateId(nextWeek));
            ref?.current?.scrollToDate(nextWeek, true);
          }}
          style={{backgroundColor: '#DCB3E3', padding: 5, borderRadius: 5}}>
          <Text>Next</Text>
        </TouchableOpacity>
      </View>
    </SafeAreaView>
  );
}

Incorrect Scrolling Behavior seen on v0.0.6

https://github.com/MarceloPrado/flash-calendar/assets/4240966/9828d17d-3b99-493c-8c4c-abaf1af2f51b

Scrolling Fixed on v0.0.7

https://github.com/MarceloPrado/flash-calendar/assets/4240966/40b58d39-e687-4676-91db-702636eb2804

Hope this helps!

@abs192

MarceloPrado commented 4 months ago

Thanks for the help! Turns out #19 (v0.0.7) also fixed this issue 🙂