Closed eps1lon closed 1 year ago
@eps1lon Great issue and an interesting topic! A couple of thoughts that I have maturing since I started diving into the pickers with @dmtrKovalenko last year.
First, I would like to emphasize that the mobile and desktop versions of the popup content can be significantly different. You can have a clock picker on mobile but it's far from great UX on desktop: mui/mui-x#4483. The issue seems to have gained traction (with one downvote from Dmitiry which I can understand)
I think that the solution we come up with should take this constraint into account. I think that developers should be able to cherry-pick mobile-only or desktop-only trade offs. We had https://github.com/mui-org/material-ui-pickers/issues/1670 for this problem.
Second, from the survey and poll we have done, a lot more developers care about desktop than mobile. If we look at the other date pickers used by the community, it seems that they have a desktop version that they slightly tweak with CSS media queries to fit into mobile. This seems great. I think that the desktop version, with some media queries, can actually work just fine on mobile. For instance, with the TimePicker, we could very well have mui/mui-x#4483 on mobile.
But I still think that we can have a mobile-only version of the component, like the clock for a time picker, or a bottom sheet-like Ant Design Mobile or Ionic have. What I'm saying is that "desktop" could actually be desktop and mobile (small screens) and "mobile" only mobile (small and touch screens).
Third, the signals I have seen so far would suggest that "Static" components have a non-negligible market share. They are important.
Based on the above, one option we could consider (and that seems compatible with the first proposal) is:
*Picker
*PickerDesktop
*PickerDesktopView
*PickerMobile
*PickerMobileView
I think that the solution we come up with should take this constraint into account. I think that developers should be able to cherry-pick mobile-only or desktop-only tradeoffs.
This issue is not about creating a single component for mobile/desktop nor that we should reduce the difference. Aside from allowKeyboardControl
no public API/behavior is supposed to change with these changes.
Third. The signals I have seen so far would suggest that "Static" components have a non-negligible market share. They are important.
Sure. This issue is not trying to dispute that.
Based on the above, one option we could consider (and that seems compatible with the first proposal) is:
Apart from the textbox I don't see any difference. I forgot to mention different textboxes which I encorporated in the initial proposal.
@eps1lon Agree with you. I was trying to take a step back and try to present the context in which the RFC happens (how I understand it). The intent was to explore how much the proposal fits with the other constraints. It seems all good.
Regarding the difference, I have only tried to further precise it. 1. I have made a proposal for the name at each level. 2. I have clarified that the mobile view and desktop view (popup container) are different components.
Update the issue with notes about the terminology we use. Came to the realization that we should rename DayPicker
to CalendarPicker
.
I'm also leaning towards replacing the Picker
in DatePicker
, TimePicker
, DateTimePicker
and DateRangePicker
with Input
. This would distinguish them from e.g. ClockPicker
, emphasize that you don't just "pick" but also have an "input" (i.e. textbox) and match the existing HTML terms.
I have clarified that the mobile view and desktop view (popup container) are different components.
That was already part of the original issue.
@eps1lon Looks great.
Some more thoughts about DatePicker
-> DateInput
renaming:
What about we rename the current DatePicker
to DateInput
and CalendarPicker
to DatePicker
. DateInput
composes a textbox + DatePicker
. *Picker referring to the UI that you choose from pre-defined values (like the listbox
in a combobox
). Seems like the best solution for cleaning up the terminology. But I'm afraid causing more confusion for people being used to DatePicker
.
I personally find DateInput more accurate. It also seems that the developer intent is to search for "date picker" and expect a date input in a very large proportion. I would personally +1 for not doing it, saving us time in a renaming that isn't an obvious net improvement for developers.
From a benchmark perspective, it just discovered a tradeoff that I didn't even consider before. Kendo UI has a date input component that is only a textbox https://www.telerik.com/kendo-react-ui/dateinput/
for whatever it's worth: I added DatePicker to the react-ui-roundup if you wanna see a bunch side by side. https://github.com/dimitropoulos/react-ui-roundup#DatePicker
Only one of them uses DateInput
, but I gotta say I agree that DateInput
is a better name. The picker itself can still be DatePicker
, but I don't love how so many frameworks conflate input vs. picker.
Although, I will mention, that some of these libraries have both DatePicker and DateInput, e.g. blueprint https://blueprintjs.com/docs/#datetime/dateinput, and some really only have the picker https://quasar.dev/vue-components/date and the input part is not really baked in.
You can see them all if you click "OPEN ALL IN NEW TABS" on https://react-ui-roundup.dimitrimitropoulos.com/#DatePicker
Hi guys! any plans to implement DateTimeRangeInput ?
Regarding the topic on "Picker vs. Input", in hindsight, I think that:
DateInput
component that only handles the textbox. For instance, with a birthday picker, end-users should never need the popup (they already know their date).DatePicker
should implement the most common use case, hence that we should keep the current name as using a date picker with an input and a popup seems the default. The value in changing the name seems marginal compared to the value of relying on what the majority of the developers have learned. We all talk about a "date picker", not a "date input". Wouldn't it be confusing to have the most important component is named differently? Does this issue cover https://github.com/mui-org/material-ui-pickers/issues/1526 ?
Does this issue cover mui-org/material-ui-pickers#1526 ?
I'm afraid not. This issue is mainly about terminology and composition not about component behavior.
While we're at it: Just wanted to leave the suggestion of @m4theushw in yesterdays meeting about naming the components DateField
. Personally, I find this the best candidate but I don't think it's realistic to move away from the current terminology.
@alexfauquette @joserodolfofreitas that one will be interesting to keep track off
I am restarting this discussion to be able to have something concrete in the coming week and to implement the new nomenclature before the end of the alpha.
Side note: I am using the term view as all the panels that focuses on a single date section.
For most date section, 1 view = 1 panel visible on screen (we list all the months of the year in a single panel, we show all the hours of the day in a single panel etc...).
But for the DayPicker
(to be renamed) component, we have a small inconsistency because sometime we say the DayPicker
is a single view and sometime we say each month in the DayPicker
is a view.
My understanding is that we have 4 families of components
The components with only an HTML input (current DateField
and DateRangeField
)
The components with an HTML input and a view displayed in a modal or a tooltip (current DatePicker
, MobileDatePicker
, DesktopDatePicker
, DateRangePicker
, ...)
The components with only ONE view rendered directly on the page (current DayPicker
, MonthPicker
, YearPicker
)
The components with several views rendered directly on the page (current StaticDatePicker
, StaticTimePicker
, ...)
The list below covers more than just the components exposed by our package. It also covers some slots naming because we can't decide how to name our components without deciding which names are already taken for another concept in the slots.
Component used to render an HTML
input component
Examples:
// Set the input rendered in the `DateField` component
// Only one `OutlinedInput` will be rendered
<DateField components={{ input: OutlinedInput }} />
// Set the input rendered in the `MultiInputDateRangeField` component
// Two `FilledInput` will be rendered, one for the start date and one for the end date
<MultiInputDateRangeField components={{ input: FilledInput }} />
// Set the input rendered in the field of the `DatePicker` component
// Only one `OutlinedInput` will be rendered
<DatePicker components={{ input: OutlinedInput }} />
Component used to edit a date with the keyboard
Examples:
// Standalone usage of a field component
<DateField />
// Set the field rendered in the `DateRangePicker` component
<DateRangePicker components={{ field: MultiInputDateRangeField }} />
<DateRangePicker components={{ field: SingleInputDateRangeField }} />
// Set both the field and the input rendered in the `DateRangePicker` component
<DateRangePicker
components={{
field: MultiInputDateRangeField,
input: OutlinedInput,
}}
/>
Competitors naming for the same concept:
Component used to edit one or several date section (day, month, year, hour, minutes, seconds) with the mouse
Examples:
// Standalone usage of views
<MonthView /> // current `MonthPicker`, to edit month
<YearView /> // current `YearPicker`, to edit year
<DayView /> // current `DayPicker`, to edit day
<CalendarView /> // current `CalendarPicker`, to edit day / month / year
// Set the list of views rendered in a `DatePicker` component
<DatePicker views={['month', 'day']} />
Competitors naming for the same concept:
RangeCalendar
for instance)Component used to edit a date with both the keyboard and the mouse Is the combination of a field and one or several views
Examples:
// Standalone usage of responsive picker components
<DatePicker />
<DateRangePicker />
<DateTimePicker />
<DateRangeTimePicker />
// Standalone usage of mobile / desktop picker components
<MobileDateRangeTimePicker />
<DesktopDatePicker />
Competitors naming for the same concept:
DateTime
for instance, but I did not find an actual component name, just the doc page name)One things that is clear is that no nomenclature is being used by all of our competitors.
We are all using the same terms for various things.
My main goal here is to be consistent across our components (MonthPicker
should clearly not have the same suffix as DatePicker
for instance)
@flaviendelangle sounds great.
One note, on this demo
<DateField components={{ input: OutlinedInput }} />
I think that for many teams they will want to use:
<DateField components={{ input: TextField }} />
Which I think is still coherent if we argue that a DateField is a specialized version of a TextField.
My main goal here is to be consistent across our components (MonthPicker should clearly not have the same suffix as DatePicker for instance)
Could you elaborate more on this point? 🤔
IMHO, I'd argue that the current naming of those components represents their intent more correctly than View
.
MonthView
- I might expect to see a visual representation of months in a year or days in a month given such name.
MonthPicker
- I would expect a component with ability to pick/choose a particular month
I think that for many teams they will want to use:
<DateField components={{ input: TextField }} />
The exact behavior of the input
slot is something I would like to discuss, but maybe in a standalone issue.
Should it have a default value ? If so maybe not the TextField
due to the bundle size but it should clearly be compatible with the TextField
out of the box.
Should it remain a render prop like today ?
Etc...
My main goal here is to be consistent across our components (MonthPicker should clearly not have the same suffix as DatePicker for instance)
Could you elaborate more on this point?
Currently, the Picker
term refers to either:
DatePicker
, DateRangePicker
, ...)CalendarPicker
, MonthPicker
, YearPicker
, or with a prefix StaticDatePicker
, StaticDateRangePicker
, ...) For me there is an inconsistency there. And by reading the name of the component, we should know if there is an input and a modal, or if the content is directly on your screen.
We can of course discuss this naming, the most important part for me being the differentiation between the two.
For example, we could add the Static
prefix to all of them (StaticMonthPicker
).
But I don't have the feeling the Static
describes the actual behavior either.
For example, we could add the Static prefix to all of them (StaticMonthPicker).
Oh, I see your point. That is a problem we could solve by tweaking the naming and you did give a very good example of using Static
as we already use it for other pickers without input.
But I don't have the feeling the Static describes the actual behavior either.
Indeed, there are a few of ways we could go:
Static
as per @eps1lon suggestion (also adding this name to the components in question)Static
to YearPicker
, MonthPicker
, CalendarPicker
to align with existing Static<Type>Picker
static
components with View
(i.e.: YearPicker
-> YearPickerView
, StaticDatePicker
-> DatePickerView
)DatePicker
-> DateInput
) as per @eps1lon suggestionI've listed the options in my personal preference order.
I'm not a fan of the last option just because of the possible confusion caused to developers.
One possible alternatives to Static
I could think of is Fixed
. 🤔
I was thinking about the Inline
prefix.
@alexfauquette if you have some idea.
From What I understood from the previous discussion, the current modification proposal is the next one.
Some naming do not change. The components with an input are ending with Field
v5 name | v6 name |
---|---|
DateTimePicker |
same |
TimePicker |
same |
DateRangePicker |
same |
DatePicker |
same |
DesktopDatePicker |
same |
DesktopDateRangePicker |
same |
DesktopDateTimePicker |
same |
DesktopTimePicker |
same |
MobileDatePicker |
same |
MobileDateRangePicker |
same |
MobileDateTimePicker |
same |
MobileTimePicker |
same |
The components that are referring to a views=['day', 'year']
end with View
for consistency
v5 name | v6 name |
---|---|
MonthPicker |
MonthView |
YearPicker |
YearView |
DateRangePickerDay |
MultiMonthDayView (tricky one) |
PickersDay |
DayView |
For Clock and Calendar I have a doubt. Should we emphasize that it's an aggregation of different views. Interface si conflicting with the notion of interface of typescript
v5 name | v6 name |
---|---|
ClockPicker |
ClockView or ClockInterface |
CalendarPicker |
CalendarView or CalendarInterface |
Same question for statics
v5 name | v6 name |
---|---|
StaticTimePicker |
TimePickerView or TimePickerInterface |
StaticDateRangePicker |
DateRangePickerView or DateRangePickerInterface |
StaticDateTimePicker |
DateTimePickerView or DateTimePickerInterface |
StaticDatePicker |
DatePickerView or DatePickerInterface |
We also export CalendarPickerSkeleton
and PickerStaticWrapper
be nobody care and they are not a problem
From a developer point of view (I'm not sure about how complex it's to implement) I would expect DateField
to behave like TextField
. So you no not pass TextField
to its slots, but the subcomponents
// Simple customization
<DateField label="..." placeholder="..." components={{
Input: OutlinedInput,
InputLabel: ..
FormHelperText: ...
}} />
@flaviendelangle I don't get for wichi component do you want to pass Inline
For components without views?
@flaviendelangle I don't get for wichi component do you want to pass Inline For components without views?
The debate is about those components:
The components that are referring to a views=['day', 'year'] end with View for consistency
@LukasTy is not a fan of the View
suffix, and I agree that it's worth taking some time to think about it.
We also export CalendarPickerSkeleton and PickerStaticWrapper be nobody care and they are not a problem
Yes for those two I don't really understand the use case yet.
From a developer point of view (I'm not sure about how complex it's to implement) I would expect DateField to behave like TextField.
The problem being that on a date range field, we can have 2 TextField
rendered.
In a perfect world, I would have a suffix for DateField
& co that is not Field
but something never used.
In a perfect world, I would have a suffix for DateField & co that is not Field but something never used.
I think "Field" makes sense, although, as you said is the closest but not ideal.
Personally, I see everything as an input, you can input the date with a mouse (using a picker) or with a keyboard (using a field). But I agree that input is usually related to the most basic component of the hierarchy.
The naming that would make the most sense to me would be:
Example:
<DateRange pickers: {['month', 'year']} components:{{ field: MultiInputDateRangeField, monthPicker: MyMonthPicker }} />
So in your nomenclature, if I understand correctly we would have:
DatePicker
=> Date
(that one is problematic because Date
is also the name of the JS interface)DateTimePicker
=> DateTime
DateField
=> DateField
CalendarPicker
=> CalendarPicker
(or DatePicker
if we are 100% coherent but that's tricky to give the name of a v5 component)MonthPicker
=> MonthPicker
Yes, that would be the most intuitive for me, and we wouldn't need to use the generic "View".
The DatePicker => Date (that one is problematic because Date is also the name of the JS interface)
I was inspired by retool. But I see your point, thought when it's written as a component doesn't seem that bad.
<Date pickers: {['month', 'year']} components:{{ monthPicker: MyMonthPicker }} />
https://codesandbox.io/s/throbbing-forest-n7skkj?file=/src/App.js
The problem is name collision
Follow yesterday's meeting, we decided to wait before applying the changes in order to gather more information about how these Static / View components would be used.
My latest proposal was to use the "Calendar" prefix and to remove any prefix from Clock
This leaves us with the naming of the Static
, but I feel that once we will have a headless version ready, those wrappers will loose a lot of there interest.
TL;DR: Changes to the public API are
Static*Picker
will become*PickerView
(naming open).DayPicker
will becomeCalendarPicker
DayPicker
view
date
will becomeday
allowKeyboardControl
<input type={...} />
will end inInput
instead ofPicker
e.g.TimePicker
will becomeTimeInput
For a short summary of the terminology used see https://gist.github.com/eps1lon/97cbf619cffd30f12deece8d72b0c941
variants
Right now we ship every picker in 4 different variants:
StaticDatePicker
MobileDatePicker
DesktopDatePicker
DatePicker
Static variants are the underyling picker without the textbox(s). It isn't static at all since it takes user input, validates it etc. Mobile and desktop are for their respective environment and "responsive" just switches dynamically between "mobile" and "desktop" based on a media query.
None of these components share a common entry point in their implementation (anymore). However, it seems to me that all of these compose naturally into:
The "popup content" is what will become the
*PickerView
component (or*PickerGrid
,*PickerDialogContainer
). The naming is still open since it's somewhat arbitrary what we consider the "view". It's just as arbitrary as "static" but it seems to me that "static" is even more misleading.The "responsive" component will then just be a thin wrapper around the desktop and tooltip variants that doesn't need much customization. Instead, we should encourage custom wrappers especially for lazy loading etc.
timing related naming
cursive formatting refers to natural language which isn't clearly defined (especially considering different languages which differ in what is a date or time).
monospace
formatting refers to technical terms that are well defined.date
with textbox + calendarpickertime
with textbox + clockpickermoment
with textbox + (clockpicker + calendarpicker + switch for calendar vs clock)year
,month
andday
hour
,minute
andsecond
year
What we call a
date
is not the same as a JavaScriptDate
. Instead we follow the naming of HTML input types where we split a point in time (amoment
) intodate
andtime
(ISO 8601 equally applies).date
is further split intoyear
,month
andday
.time
is split intohour
,minute
andsecond
.allowKeyboardControl
Dropping
allowKeyboardControl
is more of a drive-by improvement. This is effectively a prop that makes the component strictly worse (since it excludes people relying on keyboard input). I suspect the prop was motivated by the fact that the original implementation registered all keyboard handlers globally when we can use keydown handlers on the specific components instead.Picker
vsInput
This change is unlikely to land in the public interface. But it might make sense to use that terminology internally.
Right now we use
picker
as a generic term for all components that were part of@material-ui/pickers
. But it's unclear what this term means considering we haveClockPicker
andTimePicker
(which is justClockPicker
+ textbox).Let's entertain the idea of renaming
DatePicker
toDateInput
andCalendarPicker
toDatePicker
.DateInput
composes a textbox +DatePicker
. *Picker referring to the UI that you choose from pre-defined values (like thelistbox
in acombobox
). Seems like the best solution for cleaning up the terminology. But I'm afraid causing more confusion for people being used toDatePicker
.I would propose
/cc @mui-org/maintainers