React-native-calendars: Proposal to have dynamic height for calendar list

Created on 16 Aug 2017  路  12Comments  路  Source: wix/react-native-calendars

At the moment it appears there is a fixed height applied to the Calendar List, which means on smaller screens there is a lot of whitespace wasted (see below for screenshot of iPhone 5 example).

Can we get this to be a dynamic option rather than fixed? I assume there was a reason to having this hard coded value?

For reference, the code is here: https://github.com/wix/react-native-calendars/blob/master/src/calendar-list/index.js#L16

Screenshot:
screen shot 2017-08-16 at 13 57 56

Most helpful comment

Not sure why this was closed so quickly, but I suppose we can continue to discuss this.

Having an "easier implementation" and having the correct implementation are two entirely different things. The reason for raising this is purely for smaller screens, for example an iPhone 5 where depending on the content surrounding the calendar list and combined with the huge whitespace gap, it may not be easily identifiable that this is indeed a vertical scrollable calendar.

This to me is quite a big UX drawback and one that should be addressed. For instance, the native Calendar in iOS handles the variable months (4-6 rows) effectively in a continuous manner. It would be a shame to ignore this especially as this is by far the best calendar component i've come across for React Native.

All 12 comments

Yes, it is possible to have 4-6 lines of days depending on month day configuration. Having fixed height allows much easier implementation of scrolling month list, but that makes months with 4 or 5 lines of days have a bigger bottom empty space.

What about a prop for number of rows displayed?

but that would mean some of months don't display all the days, right?

Not sure why this was closed so quickly, but I suppose we can continue to discuss this.

Having an "easier implementation" and having the correct implementation are two entirely different things. The reason for raising this is purely for smaller screens, for example an iPhone 5 where depending on the content surrounding the calendar list and combined with the huge whitespace gap, it may not be easily identifiable that this is indeed a vertical scrollable calendar.

This to me is quite a big UX drawback and one that should be addressed. For instance, the native Calendar in iOS handles the variable months (4-6 rows) effectively in a continuous manner. It would be a shame to ignore this especially as this is by far the best calendar component i've come across for React Native.

Hey, sure we can discuss. Continuous implementation should be possible, but it would be much trickier because various calendar heights. If you would need to scroll to certain day in the calendar list you would need to calculate scroll position by evaluating week rows number for each month in the future until chosen day.

Sorry, got busy and didn't check back on this thread. This is what the calendar would ideally look like, if there were a minRows prop (calendar in the image has a value of 6 rows, not sure you'd want anything more than that). Would this be a desirable short-term solution?

screen shot 2017-09-05 at 11 24 21 am

hej, is this something that got implemented? or is it planned to?

I have a fix for this which is a little hack-y but consistent. Calculate the number of weeks per month, subtract that from 6 (the number of months rows allocated regardless) and give the body of the calendar negative vertical margin equal to that multiplied by the row height:

const extraPadding = (6 - this.getNumberOfWeeksInMonth(this.state.selectedDate.clone())) * -rowHeight

...do things

<View style={{...eStyles.container, marginBottom: extraPadding }} >
  <CalendarList />
</View>

Hi, I met the same issue on CalendarList, version 1.265.0, is there a solution for that ?

Hi all.

I just implemented this - in a similar way to @tvillafane although I wasn't sure if I could get hold of the getNumberOfWeeksInMonth method, so I did this:

const getCalendarHeight = () => {

    // The cunning idea here is to pad the beginning date, and end date so that it's nice and divisible by 7
    const firstDay = new Date(year, month-1, 1),
      lastDay = new Date(year, month, 0); // Looks funky, but the 0 as the day means we get the last day of the previous month. Yay JS!

    const days = 
      lastDay.getDate() +
      firstDay.getDay() +     // E.g. If it's a Monday, we'd add 1 to the days.
      (6 - lastDay.getDay()); // E.g. If it's a Friday, we'll add (6 - 5) to the days, taking us to the full week.

      return (days / 7) * 56;
  }

  return (
    <CalendarList
      style={{ height: getCalendarHeight() }}
      markingType={'multi-dot'}
      pastScrollRange={24}
      futureScrollRange={24}
      onVisibleMonthsChange={onMonthChange}
      horizontal
      pagingEnabled
      hideExtraDays={true}
      onDayPress={onDayPress}
      hideArrows={true}
      markedDates={generateRenderData(calendarData, selectedDate)}
      renderHeader={() => { }}
    />

.. where year and month are the current month and year, that are being tracked in state in my case.

@mattwoberts How did you solved when there are 2 months to rendered?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

matieux picture matieux  路  4Comments

filippoitaliano picture filippoitaliano  路  3Comments

anishtr4 picture anishtr4  路  3Comments

chapeljuice picture chapeljuice  路  3Comments

dobiedad picture dobiedad  路  4Comments