mui-x icon indicating copy to clipboard operation
mui-x copied to clipboard

[pickers] How to add Quarter View to DatePicker

Open ChristianRaoulis opened this issue 1 year ago • 2 comments

The problem in depth

We're trying to add a Year and Quarter Date Picker and struggle on getting the Quarter part to work. Is there a way to create a custom view for selecting quarters?

Your environment

`npx @mui/envinfo`
 System:
    OS: macOS 15.0.1
  Binaries:
    Node: 20.15.0 - ~/Library/pnpm/node
    npm: 10.7.0 - ~/Library/pnpm/npm
    pnpm: 9.12.1 - ~/Library/pnpm/pnpm
  Browsers:
    Chrome: 130.0.6723.70
    Edge: 130.0.2849.56
    Safari: 18.0.1
  npmPackages:
    @emotion/react: ^11.13.3 => 11.13.3 
    @emotion/styled: ^11.13.0 => 11.13.0 
    @mui/icons-material: ^6.1.5 => 6.1.5 
    @mui/lab: 6.0.0-beta.13 => 6.0.0-beta.13 
    @mui/material: ^6.1.5 => 6.1.5 
    @mui/x-charts-pro: 7.0.0-beta.5 => 7.0.0-beta.5 
    @mui/x-data-grid-pro: 7.21.0 => 7.21.0 
    @mui/x-date-pickers: ^7.21.0 => 7.21.0 
    @mui/x-date-pickers-pro: 7.21.0 => 7.21.0 
    @mui/x-license: ^7.21.0 => 7.21.0 
    @mui/x-tree-view-pro: ^7.21.0 => 7.21.0 
    @toolpad/core: ^0.7.0 => 0.7.0 
    @types/react: ^18.3.12 => 18.3.12 
    react: ^18.3.1 => 18.3.1 
    react-dom: ^18.3.0 => 18.3.1 
    typescript: ^5.6.3 => 5.6.3 

Search keywords: DatePicker Order ID: 85157

ChristianRaoulis avatar Oct 25 '24 13:10 ChristianRaoulis

Not sure if we can support something like this atm. @LukasTy ?

michelengelen avatar Oct 29 '24 11:10 michelengelen

Hello @ChristianRaoulis, thank you for creating the issue. Such an option does not exist out of the box, and providing it on your end, given the current API, would be nearly impossible.

It might be possible to achieve it by providing a custom views array including a quarter view and providing a viewRenderer for this view. However, the amount of customization needed to achieve it is not worth it IMHO. 🙈

We will have this need in mind when improving the customizability. 😉 👍

For now, I'm adding this issue to our grooming board and adding a waiting for 👍 label to gauge the interest. 😉

LukasTy avatar Oct 29 '24 15:10 LukasTy

We had the quarter logic working with v5 by extending MomentUtils and overriding the month-related logic (formatting, modifications, ...) with existing quarter functions that are already supported by moment. Specifically important was overriding getMonthArray to return only the four quarters instead of 12 months. This was enough to have the month picker show only four quarters.

Sadly, this does not work with v7 anymore, as getMonthArray has been removed from the adapter API and there was no way of customizing the amount of months anymore. The generation of month elements is now located here

Right now we stay on v5 because the only option would be building our own MonthCalendar component which would require re-building lots of other functionality provided by MonthCalendar

While having built-in support for quarters would be great, a way to customize, extend or re-use existing components or hooks would also be fine.

oschwede avatar Nov 18 '24 09:11 oschwede

@oschwede thank you for your feedback and detailed explanation of your case. 👍 @flaviendelangle WDYT about moving the month array resolving back into adapters to allow for previous possible overriding? 🤔

LukasTy avatar Nov 18 '24 09:11 LukasTy

I understand that it was the best way to do it and that by removing this option from the adapter we prevented this customzation. But I don't think bringing this feature back into the adapter is the right way to go. There was no guarantee that we would not use getMonthArray for another use case where overriding and returning only some months would break the behavior (for example I could imagine the field broken because the autocomplete uses getMonthArray with only some months but the arrow uses addMonth which has all the months). If we want to support this use case (which is of course valid), I see several approaches:

  1. If we introduce a composition API in the future, then filtering the visible months will be trivial:
<MonthCalendar.Root>
  {month => {
    if (month.month() % 3 !== 0) return null;

    return (
      <MonthCalendar.Month value={month} />
  })
</MonthCalendar.Root>

This would not impact the field (which would still have all the months but at least all the field editing would be coherent).

  1. If we want to impact both the views and the field, then we probably need a prop like to skip months, but I would wait to have more traction there.

flaviendelangle avatar Nov 18 '24 09:11 flaviendelangle

Fair point regarding the fragility of overriding the adapter method. 👍 I agree that the best approach is to prioritize better customization API to avoid the need for internals overriding. 🙈

LukasTy avatar Nov 18 '24 09:11 LukasTy