Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: material-ui-pickers v4 #1293

Closed
dmtrKovalenko opened this issue Aug 30, 2019 · 49 comments
Closed

RFC: material-ui-pickers v4 #1293

dmtrKovalenko opened this issue Aug 30, 2019 · 49 comments
Milestone

Comments

@dmtrKovalenko
Copy link
Member

dmtrKovalenko commented Aug 30, 2019

Breaking changes

We are on the way to v4. It is required to make another major release independently of @material-ui/core team. Here what I am planning to release

Material design v2 update

Material design guidelines was updated with new reference for date/time pickers reference

Here is new UI sneak peek
design update
This looks really strange:
mobile keyboard input

Also as you can see this spec contains a design for the date-range picker. So possible new release should also include #364

image

P.S. It looks like we need to redesign literally everything. So will need as many help as possible

Improved mask and keyboard mode

Updating to the new rifm version will allow us to resolve #1144 and #1289. And also new release will make possible to make a major update of date-io library with an automatic insert of keyboard-friendly formats

Changes for variants

Right now we have inline and dialog option. Due to changes in material design spec I propose to have variants mobile and desktop and accept them automatically, on the flight.

And also we want to make inline or desktop variant to be primarily supported instead of the mobile one.

Any discussion is appreciated :) @oliviertassinari

@dmtrKovalenko
Copy link
Member Author

dmtrKovalenko commented Aug 30, 2019

If you do not mind please react to the issue, so I know what do you think :)

@dmtrKovalenko dmtrKovalenko pinned this issue Aug 30, 2019
@oliviertassinari

This comment has been minimized.

@dmtrKovalenko
Copy link
Member Author

Hmm. Getting back to InlineDatePicker and MobileDatePicker can help with treeshaking but will cost.
Anyway we need to consider a better tree shaking of mobile/desktop code

@TrejGun
Copy link

TrejGun commented Sep 4, 2019

I have developed bunch of sites for tour, auto/moto, accomodation rental companies. all these companies requires date-time range picker. I'm really upset of this new spec

@williamluke4
Copy link

Love the Date Range Picker 😉. @dmtrKovalenko Any chance of a rough eta?

@ZNackasha
Copy link

ZNackasha commented Sep 9, 2019

@dmtrKovalenko Love the new look and feel. I just wanted to know if this new date picker will support time-ranges ( aka: hours, minutes and seconds ) as well? my use case for this is to allow users to select events between two different points in time.

@ttv86
Copy link

ttv86 commented Sep 12, 2019

Can we have week numbers please? Currently that is primary reason why we can't use material ui date picker.

@Angelk90

This comment has been minimized.

@oliviertassinari
Copy link
Member

oliviertassinari commented Oct 4, 2019

Given the date picker was our number one requested focus on the last developer survey.
Take this example, a good date picker can be an entry point for the adoption of Material-UI.

I'm determined to make sure that we allocate enough resources to this problem.
Most notably, I have proposed that Material-UI financially support @dmtrKovalenko to push the concern forward.

(Notice that we evaluate a similar effort for the datatables problem,
A significant difference is that Material-UI can directly monetize paid advanced features like ag-grid, dev-express, syncfusion, kendo, sencha, etc do.)

Benchmark

I have used the following sources to benchmark:

Proposal

I would recommend the following:

  1. Change react peer dependency from "^16.8.4" to "^16.8.0".
  2. A strong focus on the desktop version. Consider the mobile version later on, for 2020 or 2021.
  3. Consider not implementing a mobile landscape mode. I hope that we can get away without.
  4. Move the project to /mui-org/material-ui/. I expect the usage of the same documentation to provide a better experience for the developers. We would rely on the same conventions.
    I expect hosting the effort on the main repository will consolidate the integration of the component with the others. For instance, it will help contributors.
  5. Evaluate if the pickers should be published under @material-ui/core or @material-ui/pickers. I'm not sure about this one. I'm hesitating, my preference is with @material-ui/pickers, if possible. A developer survey could help us pick the best option.
  6. Start from the ground-up leveraging the past learnings.
  7. Remove MuiPickersUtilsProvider, depend on dayjs or date-fns by default, depending on what's smaller by default.
  8. Allow the usage of theme.props.MuiDatePicker.dateUtils to provide an adapter for moment or date-fns with @date-io.
  9. Write the sources in TypeScript.
  10. Keyboard navigation. The focus should stay on the input. If the Calendar is used, standalone, the focus should stay on the root div. Among the different solutions I have benchmarked, I have found the keyboard support of Kendo interesting for the timepicker: arrow up and down + text selection. Otherwise, when disabledKeyboard=false, I think that the Calendar should take precedence for the handling of the arrow keys over the input.
  11. Implement the code as a monolith: DatePicker. Then, consider how to break it down is reusable pieces.
  12. The supported props & features:
DatePicker.propTypes = {
  /**
   * The date engine to use, default to X.
   * You can use moment or else following https://github.com/dmtrKovalenko/date-io.
   *
   * It contains the locale.
   * Want to change the first day of the week? Change the locale.
   */
  dateUtils: PropTypes.object,
  /**
   * If `true`, a column is added to show the week numbers of the year.
   *
   * default false
   */
  showWeekNumbers: PropTypes.bool,
  /**
   * Format used to display the date in the input.
   * The format is used to parse the input string and stringify date object internally.
   * The format should match the supported behavior of the provided style engine.
   */
  inputFormat: PropTypes.string,
  /**
   * Parsable date, e.g. new Date() or moment().
   * The support value type depends on the date engine used, see the `dateUtils` prop.
   */
  value: DateIOType,
  /**
   * The default value. Use when the component is not controlled.
   */
  defaultValue: DateIOType,
  /**
   * Specify the dates that are disabled.
   *
   * @param {DateIOType} date The date to consider
   * @returns {boolean}
   */
  disabledDate: PropTypes.func
  /**
   * Specify the times that are disabled.
   *
   * @param {DateIOType} date The time to consider
   * @returns {boolean}
   */
  disabledTime: PropTypes.func
  /**
   * The minimum selectable date.
   */
  minDate: DateIOType,
  /**
   * Whether shortcuts to quickly select a range of dates are displayed or not.
   * If true, preset shortcuts will be displayed.
   * If false, no shortcuts will be displayed.
   * If an array is provided, the custom shortcuts will be displayed.
   */
  rangeShortcuts: PropTypes.oneOfType([PropTypes.bool, PropTypes.array]),
  /**
   * The maximum selectable date.
   */
  maxDate: DateIOType,
  /**
   * The maximum time the user can select.
   * The year, month, and day parts of the Date object are ignored.
   */
  maxTime: DateIOType
  /**
   * The minimum time the user can select.
   * The year, month, and day parts of the Date object are ignored.
   */
  minTime: DateIOType
  /**
   * Callback fired when the value changes.
   *
   * @param {object} event The event source of the callback
   * @param {DateIOType} value
   */
  onChange: PropTypes.func,
  /**
   * Control the popup open state.
   */
  open: PropTypes.bool,
  /**
   * Callback fired when the popup requests to be opened.
   * Use in controlled mode (see open).
   *
   * @param {object} event The event source of the callback.
   */
  onOpen: PropTypes.func,
  /**
   * Callback fired when the popup requests to be closed.
   * Use in controlled mode (see open).
   *
   * @param {object} event The event source of the callback.
   */
  onClose: PropTypes.func,
  /**
   * Date that will be initially highlighted if null was passed.
   *
   * from (initialFocusedDate)
   * default today
   */
  defaultHighlight: DateIOType,
  /**
   * Number of months to show. Supported value between 1 and 3.
   *
   * default 1
   */
  monthsShown: PropTypes.number,
  /**
   * Disable the arrow keyboard navigation.
   *
   * from (allowKeyboardControl)
   * default false
   */
  disabledKeyboard: PropTypes.bool,
  /**
   * If `true`, the current day shouldn't be highlighted in the calendar.
   *
   * default false
   */
  disableHighlightToday: PropTypes.bool,
  /**
   * If `true`, the popup won't close when a value is selected.
   *
   * from (autoOk)
   * default false
   */
  disableCloseOnSelect: PropTypes.bool,
  /**
   * Props applied to the [`TextField`](/api/text-field/) element.
   */
  TextFieldProps: PropTypes.object,
  /**
   * If `true`, the clear button is visible.
   *
   * default false
   */
  showInputClear: PropTypes.bool,
  /**
   * If `true`, the clear button is visible.
   *
   * default false
   */
  showCalendarClear: PropTypes.bool,
  /**
   * If `true`, the today button is visible.
   *
   * default false
   */
  showCalendarToday: PropTypes.bool,
  /**
   * An object containing all the translation keys.
   *
   * Default:
   *
   * - today: Today
   * - clear: Clear
   * - selectMonth: Select a month
   * - selectYear: Select a year
   */
  labels: PropTypes.object,
  /**
   * If `true`, the user needs to confirm his choice.
   *
   * default false
   */
  confirm: PropTypes.bool,
  /**
   * If `true`, the user should select a range.
   *
   * default false
   */
  range: PropTypes.bool,
  /**
   * Whether to use a 12 hour format with an AM/PM choice or a 24 hour format.
   *
   * Default to the browser preference.
   *
   * ?
   * https://stackoverflow.com/questions/27647918/detect-with-javascript-if-users-machine-is-using-12-hour-clock-am-pm-or-24-cl/27648032
   */
  useAmPm: PropTypes.bool,
  /**
   * Allow the user to pick a value between:
   *
   *  - year
   *  - month
   *  - day
   *  - week
   *  - time
   *
   * default ['year', 'month', 'day']
   */
  mode: PropTypes.array,
}

References

I have kept track of some visual clue for the above proposal.
You fill find features or components that have associated link with the benchmark sources.

  • YearPicker

YearPicker
material.io

YearPicker pagination
antd

  • TimePicker

TimePicker
kendo

TimePicker_
antd

  • switch between date and time

switch between date and time_
kendo

switch between date and time
antd

  • showWeekNumbers=true

showWeekNumbers=true
bootstrap

showWeekNumbers=true_
antd

  • showInputClear=true

showInputClear=true
gmail

  • showCalendarToday=true

showCalendarToday=true
antd

showCalendarToday=true_
blueprint

showCalendarToday=true__
syncfusion

  • showCalendarClear=true

showCalendarClear=true

blueprint

  • rangeShortcuts=true

rangeShortcuts=true
blueprint

rangeShortcuts=true_
google ads

rangeShortcuts=true__
airbnb

  • range=true

range=true
material.io

range=true projection
less important feature

  • MonthPicker

MonthPicker

  • disableHighlightToday=false

disableHighlightToday=false
bootstrap

disableHighlightToday=false_
material.io

  • DayPicker

DayPicker
material.io

  • confirm=true

confirm=true
antd

confirm=true_
google analytics

confirm=true__
google ads

  • Calendar

Calendar
material.io

  • monthsShown=2

Calendar-monthsShown=2

material.io

  • monthsShown=3

Calendar-monthsShown=3

google analytics


This is meant as a sketch of what the next steps could look like. Feedback appreciated.
cc @mui-org/core-contributors

@williamluke4
Copy link

williamluke4 commented Oct 4, 2019

I remember finding a date range picker where you could just define the flow of the views..
For example:

<DateRange views={['year', 'month' 'day']} />
<DateRange views={['week']} />
<DateRange views={['time']} />

If i need to clarify some more let me know :)

@williamluke4
Copy link

As for moving the project to /mui-org/material-ui/. I think this is a great idea!! as it would remove the issues with versioning

@spudcud
Copy link

spudcud commented Oct 9, 2019

I agree with limiting the # of date libraries available. I vote for dayjs because it has real TimeZone support. date-fns I have used and is great but it does not have good TimeZone support. My use case is that we need to show all dates and times in UTC regardless of where the user is. I am still in-process implementing dayjs with this library and so far it seems good. date-fns did not have what I needed so I had to skip away from it (unfortunately).

edit: dayjs does not work correctly now when typing datetimes directly. The last minute digit cannot be typed by the user. An issue is logged for it. With this issue dayjs is unusable.

@alexplumb
Copy link

I switched my business' app from moment to luxon because we wanted to use this library - please don't make me switch again! :(

@Angelk90
Copy link

@dmtrKovalenko , @alexplumb , @williamluke4 , @oliviertassinari :

Is there anything new when this component is ready?

Take a look at the input field with the multiple selection, as they set the way to also select the time between the two dates.
Link: date-time-picker

@designorant
Copy link
Contributor

May I suggest introducing a native prop that render the input as a standard type="date"? Mobile devices have an acceptable support for date and time inputs these days.

This would naturally come with some drawbacks, i.e.:

Partial support in iOS Safari refers to not supporting the week input type, nor the min, max or step attributes

but would greatly improve the UX on mobile devices anyway.

@zefj
Copy link

zefj commented Nov 6, 2019

So are we finally getting a "Today" button in inline pickers? Because the rationale in #782 is so bad it hurts my brain, especially in an otherwise brilliant library (except the fact it comes compiled, which is dumb and makes debugging and figuring the internals out absolutely impossible, but that's another matter).

@williamluke4
Copy link

@dmtrKovalenko @oliviertassinari Are there any plans to have major version parity with the core library? As by the time @material-ui/pickers V4 is released, I would expect the core lib to be at V5. Would it not make sense that the major version of @material-ui/pickers mirror that of @material-ui/core?

@dmtrKovalenko
Copy link
Member Author

@williamluke4 just yesterday we have been discussing this with @oliviertassinari. Still we are not sure about moving pickers to the core, but versions will mirror the core version 100%.

Also (likely) documentation and source code of pickers will be moved to the core repository

@oliviertassinari
Copy link
Member

I'm personally in favor of keeping @material-ui/pickers as a different npm package because:

  • It's an opportunity to experiment with something we don't do with the other packages.
    • User-land: I'm particularly interested in seeing the impact it has on adoption 1. inside Material-UI 2. outside Material Design (as a design spec) and 3. outside Material-UI (as a framework).
    • Maintainer-land: we can experiment with different tools: e.g. writing the sources in TypeScript, using different testing tools, etc.
  • It gives Dmitriy a success feedback loop metric: how many downloads do the components get? Do people inside Material-UI use it, or do they go use something else in the React ecosystem? Do people outside Material-UI use it? Because there is nothing even close to the quality of the component? I'm particularly interested in setting incentives that can make it possible to get a better component than what you will find if you pay for a date picker component, e.g. https://www.telerik.com/kendo-react-ui/components/dateinputs/.

But yeah, I think that the package major version should match to make it feels like a single entity that moves forward. I think that using a mono git repository would help in the matter.

@williamluke4
Copy link

Yeah 100% agree that it should remain a separate package :)

@MrBokeh
Copy link

MrBokeh commented Dec 9, 2019

Is there a pre-release version of the date range picker right now that we can use?

@williamluke4
Copy link

@dantman
Copy link

dantman commented Mar 27, 2020

I switched my business' app from moment to luxon because we wanted to use this library - please don't make me switch again! :(

I'd also strongly prefer it if mui/pickers did not switch to hardcoding a single date library.

It doesn't matter if the date library in question is small. If the project is using a different date library a whole library of extra code that doesn't need to be there is still being added.

There are also good reasons not to use date-fns/dayjs. Both date-fns/dayjs use bespoke localization. i18n is done inside the project itself, you are subject to what locales people have contributed to that specific library (not a universal i18n library everyone uses like CLDR), and you are stuck downloading this locale data even if you don't need it to do date localization. Luxon meanwhile uses the date localization functionality built in to the browser, no custom locale data needed if you are only supporting modern browsers.

So there are very good reasons for different projects to use different date libraries and it doesn't make sense for mui/pickers to start contradicting this when the work to support multiple has already been done.

@Angelk90
Copy link

@dmtrKovalenko , @oliviertassinari :
Trying the version on: https://v4-0-0-alpha-5.material-ui-pickers.dev/demo/daterangepicker
Clicking on the month does not allow me to select the years as shown in the figure on the right:

@mihilmy
Copy link

mihilmy commented May 7, 2020

When can we expect this to be released to production. How can I contribute to speed up the development process?

@oliviertassinari
Copy link
Member

oliviertassinari commented May 7, 2020

@mihilmy We plan to release the changes in multiple steps. v4 with a focus on the desktop UX (hosted under material-ui-pickers.dev).
Then v5 with a focus on advanced features (e.g. date range) and tight integration with the other components (hosted under http://material-ui.com/components/).

@xtgrant

This comment has been minimized.

@oliviertassinari

This comment has been minimized.

@SanjiKir
Copy link

Hey, so I can't find anywhere does v4 alpha support latest version of date-io adapters or still not? Thanks

@oliviertassinari
Copy link
Member

@SanjiKir Yes, it does.

@SEI-John
Copy link

Thanks for the great package and hard work!

I was reading through the v4 prerelease docs, and saw this on the DateRangePicker page:

The date range picker will be made available in the coming months for production use as part of a paid extension to the community edition (MIT license) of Material-UI. This paid extension will include advanced components (rich data grid, date range picker, tree view drag & drop, etc.). Pricing for early access will start with an affordable plan.

When are you planning on giving more info about this? This is the only place I can find it being mentioned.

@oliviertassinari
Copy link
Member

oliviertassinari commented Jun 29, 2020

@SEI-John We will have more to share before September 2020.

@oliviertassinari oliviertassinari modified the milestones: v4, v5 Jul 13, 2020
@mifrej
Copy link

mifrej commented Sep 25, 2020

We're at the end of September, any updates here?
It would help to know what is the status of works and realistic end dates, or obstacles, or anything.

@dmtrKovalenko
Copy link
Member Author

dmtrKovalenko commented Sep 25, 2020

I am working on moving pickers into the core repository mui/material-ui#22692

I will try to fix all ci warns today and once it will be merged this repo will be archived and pickers will live in the lab.

@mifrej
Copy link

mifrej commented Sep 25, 2020

You meant "live" instead of "leave" right 😄 Thanks for the great work

@dmtrKovalenko
Copy link
Member Author

Yes :) thanks

@florianbepunkt
Copy link

Regarding the date range picker:

If I select a date range, the selected end date is effectively not included (at least using Moment.js). I wonder if this is specified by Material Design somehow. This can be a bit confusing to both users and developers.

Let's say I have a use case like "Show me all events within the selected date range October 1st - October 5th, this translates to 2020-10-01T00:00:00 - 2020-10-05T00:00:00 (instead of 2020-10-05T23:59:59), meaning all events on October 5th would be included.

@Jenselme

This comment has been minimized.

@iakovosvo

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests