mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.14k stars 1.29k forks source link

[pickers] Allow switching between different calendar systems #5855

Open ghost opened 2 years ago

ghost commented 2 years ago

Duplicates

Latest version

Current behavior 😯

I have developed a small piece of code to support multiple calendar systems (e.g. Jalali + Gregorian) for MUI Picker with a toggle button inside the calendar popover as the switch. Everything worked as expected with one exception. When I switch from Jalali to Gregorian and vice versa, currentMonth value of calendarState does not update which leads to a minor UX bug in some situations.

As you can see in the useCalendarState file:

const now = useNow<TDate>();
const utils = useUtils<TDate>();

const reducerFn = React.useRef(
  createCalendarStateReducer<TDate>(
    Boolean(reduceAnimations),
    disableSwitchToMonthOnDayFocus,
    utils,
  )
).current;

const [calendarState, dispatch] = React.useReducer(reducerFn, {
  isMonthSwitchingAnimating: false,
  focusedDay: date || now,
  currentMonth: utils.startOfMonth(date ?? defaultCalendarMonth ?? now),
  slideDirection: 'left',
}); 

The utils variable is updated on every calendar system switch, but since the currentMonth value is inside the initial value of the calendarState reducer, it doesn't update on rerenders, resulting in the aforementioned UX bug.

As an example, in Jalali calendar, Today is 29th of Mordad month (= 20th of August), and when you open the picker, you see current month correctly. (currentMonth = 1st of Mordad in Jalali & 23rd of July in Gregorian) But when you switch to Gregorian calendar, instead of having August, you'll get July. That is because currentMonth variable is not updated and is 23rd of July.

Expected behavior 🤔

I would expect MUI codebase to anticipate changes on utils context variable, since I have developed a multi-calendar system mechanism. Although if MUI team developed this multi-calendar system feature on subsequent releases, I would be totally grateful; My problem would be solved with just re-coding the useCalendarState file in a way changes of utils variable would impact all related sections including currentMonth.

I have solved this problem with one tiny line of code in the file above temporarily using yarn-patch, but I would be thankful if we have the consistency for this feature on next releases.

React.useEffect(() => { changeMonth(utils.startOfMonth(date ?? defaultCalendarMonth ?? now)) }, [utils]);

The line is added after changeMonth function definition.

Steps to reproduce 🕹

Sandbox Example Link of the Bug

Context 🔦

No response

Your environment 🌎

No response

Order ID 💳 (optional)

No response

alexfauquette commented 2 years ago

Effectively, we did not assume the calendar system could change while using the calendar.

You could open a PR, such that we can experiment with the solution