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

[pickers] Remove code duplication for the multi input range fields #15505

Conversation

flaviendelangle
Copy link
Member

@flaviendelangle flaviendelangle commented Nov 20, 2024

I'm doing this refacto now because it will make a lot easier to apply heavy change to those components and move the opening logic to be handled by the field instead of the picker.

  • Create a new public unstable hook useMultiInputRangeField that replaces useMultiInputDateRangeField, useMultiInputTimeRangeField and useMultiInputDateTimeRangeField (with improved DX)
  • Create a new internal function createMultiInputRangeField that create a multi input range field for Material
  • Use createMultiInputRangeField to create MultiInputDateRangeField, MultiInputTimeRangeField and MultiInputDateTimeRangeField
  • Clean the exported interfaces (no more MultiInputRangeFieldClasses exported, each component has it's interfaces such as MultiInputDateRangeFieldClasses, like any other regular component)

Extracted PRs

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 10, 2025
@flaviendelangle flaviendelangle marked this pull request as ready for review January 13, 2025 18:14
@github-actions github-actions bot added the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 14, 2025
Copy link

This pull request has conflicts, please resolve those before we can evaluate the pull request.

@github-actions github-actions bot removed the PR: out-of-date The pull request has merge conflicts and can't be merged label Jan 14, 2025
@flaviendelangle flaviendelangle force-pushed the use-managert-for-multi-input-range-picker branch from 64d46b7 to 86d236b Compare January 14, 2025 07:12
Copy link
Member

@LukasTy LukasTy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Superb improvement, especially codebase wise! 👍 💯
Leaving one problematic comment and some nitpicks. 😃

Clean the exported interfaces (no more MultiInputRangeFieldClasses exported, each component has it's interfaces such as MultiInputDateRangeFieldClasses, like any other regular component)
My main concern—do we need this change? What does it improve? 🤔


export const multiInputDateRangeFieldClasses: MultiInputRangeFieldClasses = generateUtilityClasses(
'MuiMultiInputDateRangeField',
['root', 'separator'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have we considered making the textField as a slot as well? 🤔

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we did not because people could use the PickersTextField (or TextField from the core for the old DOM structure) classes directly.

If you think it's worth doing, then we can create an issue to do a follow up since it's not directly related to this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's debatable. 🤔
For consistent styling, yes, users can and should specify styles on the "root" component overrides (i.e. PickersTextField), but I can see use cases where someone would want to style specifically range Picker inputs differently. 🤷
But should we do it before there is demand for it? I'm not certain...
@noraleonte have you felt such a need when exploring styling customization for Pickers? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a very strong opinion on this 🤔 I guess a use case where overriding could be an app like Booking, Airbnb etc where you have forms in your app with inputs styled a certain way, but you want your app's main feature - the range picker - to have a different styling.
Targeting classes from the root works fine, since it's just one level of nesting. But having a specific slot might be a better DX generally 🤔

Comment on lines +22 to +23
MuiMultiInputDateRangeField: MultiInputDateRangeFieldClassKey;
MuiMultiInputDateTimeRangeField: MultiInputDateTimeRangeFieldClassKey;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it's worth having a separate type per field type, even though they are all identical and essentially just reexport exactly that in the original files. 🙈 🤷
I feel like it is a bit redundant... Also, close to no point in exporting them. 🤔

Suggested change
MuiMultiInputDateRangeField: MultiInputDateRangeFieldClassKey;
MuiMultiInputDateTimeRangeField: MultiInputDateTimeRangeFieldClassKey;
MuiMultiInputDateRangeField: MultiInputDateRangeFieldClassKey;
MuiMultiInputDateTimeRangeField: MultiInputDateTimeRangeFieldClassKey;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My goal here was to make those components behave like any other component in our packages.
Every component has named XXX has a XXXClassKey and XXXClasses exposed. And it has a MuiXXX entry in the theme.

And I don't think the reduced amount of exported variables is worth the mental overhead of having those components behaving differently.

WDYT?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those are valid arguments. 👍
As for XXXClasses exports - I completely agree.
But for the XXXClassKey... I'm not sure if we should even be exporting them. 🙈
They seem mostly used/reserved for declaring it here, and we could do the following instead: 🤷

-MuiMultiInputDateRangeField: MultiInputDateRangeFieldClassKey;
+MuiMultiInputDateRangeField: keyof MultiInputDateRangeFieldClasses;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK we are exporting the XXXClassKey purely because @mui/material does.
And unless I'm missing some rational, I agree with you that it's a loooooooooot of exports just to avoid a keyof for the few people that are using it 😆

If you're in favor of dropping all the XXXClassKey in our packages, we can double check with the core that we didn't miss a good reason not to.
And then plan it for v9.

value: valueProp === undefined ? undefined : valueProp[0],
defaultValue: defaultValue === undefined ? undefined : defaultValue[0],
onChange: handleStartDateChange,
autoFocus, // Do not add on end field.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prop passing looks broken. 🙈
It end up on the Stack element:
Screenshot 2025-01-14 at 20 28 57

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The autoFocus was weirdly handled by the field, I moved it to the field internal props to mimic readOnly and disabled. It seems to work well, even on single input fields but I'll double check 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The autoFocus behavior seems somewhat broken on v7 as well. 🤔
But we are now breaking one behavior - autoFocus on a enableAccessibleFieldDOMStructure={false} SingleInput field. 🙈
This case works on v7.
As for other cases (DateRangePicker or MultiInputDateRangeField with enableAccessibleFieldDOMStructure={false} autoFocus) - they are also broken on v7, so it's not a blocker and can be fixed separately. 👌

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wow standalone field autoFocus is totally broken with the old DOM structure indeed...

But do you have a scenario where it works before this PR and does not work after?
For me standalone single input range field + autoFocus is broken both before and after.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But do you have a scenario where it works before this PR and does not work after?

Nevermind, I must have mixed something up... My previously mentioned case seems to work with both enableAccessibleFieldDOMStructure flag versions. 👌

flaviendelangle and others added 8 commits January 15, 2025 10:24
Co-authored-by: Lukas Tyla <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
Co-authored-by: Lukas Tyla <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
Co-authored-by: Lukas Tyla <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
…utRangeField/createMultiInputRangeField.tsx

Co-authored-by: Lukas Tyla <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
…ge-picker' into use-managert-for-multi-input-range-picker
@flaviendelangle flaviendelangle force-pushed the use-managert-for-multi-input-range-picker branch from 79841ce to f860cc9 Compare January 15, 2025 09:40
Copy link
Member

@LukasTy LukasTy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, apart from a small problem with the mentioned autoFocus behavior. 👍

packages/x-date-pickers/src/hooks/useSplitFieldProps.ts Outdated Show resolved Hide resolved
@LukasTy LukasTy added the v8.x label Jan 15, 2025
Co-authored-by: Lukas Tyla <llukas.tyla@gmail.com>
Signed-off-by: Flavien DELANGLE <flaviendelangle@gmail.com>
value: valueProp === undefined ? undefined : valueProp[0],
defaultValue: defaultValue === undefined ? undefined : defaultValue[0],
onChange: handleStartDateChange,
autoFocus, // Do not add on end field.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But do you have a scenario where it works before this PR and does not work after?

Nevermind, I must have mixed something up... My previously mentioned case seems to work with both enableAccessibleFieldDOMStructure flag versions. 👌

@flaviendelangle flaviendelangle merged commit 90751bb into mui:master Jan 15, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change component: pickers This is the name of the generic UI component, not the React module! v8.x
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants