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] Use usePickerContext() and usePickerActionsContext() instead of passing props to the shortcuts and toolbar slots #15948

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

flaviendelangle
Copy link
Member

@flaviendelangle flaviendelangle commented Dec 19, 2024

Closes #15495 ( 🙏 )

What?

  • Remove the last props passed to the shortcuts, layout and toolbar slots
  • Introduce a new useIsValidValue hook to avoid passing something to usePickerContext that updates on every render
  • Add value to usePickerContext
  • Add setValue to usePickerContext and usePickerActionContext. This should eventually be the only way for parts of the UI to update the value (it will replace the onChange prop passed to the views and to the field in the future).
  • Rename PickerShortcutChangeImportance into PickerChangeImportance since it's not only used for the shortcut anymore.

Changelog

Breaking changes

  • The component passed to the layout slot no longer receives the value, onChange and onSelectShortcut props — Learn more.

  • The component passed to the toolbar slot no longer receives the value, onChange and isLandscape props — Learn more.

  • The component passed to the shortcuts slot no longer receives the onChange, isValid and isLandscape props — Learn more.

  • The PickerShortcutChangeImportance type has been renamed PickerChangeImportanceLearn more.

@flaviendelangle flaviendelangle added breaking change component: pickers This is the name of the generic UI component, not the React module! labels Dec 19, 2024
@flaviendelangle flaviendelangle self-assigned this Dec 19, 2024
@mui-bot
Copy link

mui-bot commented Dec 19, 2024

@flaviendelangle flaviendelangle force-pushed the layout-last-props branch 4 times, most recently from 2f4fb12 to 6fe5cfa Compare December 20, 2024 10:32
@flaviendelangle flaviendelangle changed the title [pickers] Remove the last props passed to the layout slot [pickers] Use usePickerContext() and usePickerActionsContext() to get the propspassed to the shortcuts and toolbar slots Dec 20, 2024
@flaviendelangle flaviendelangle changed the title [pickers] Use usePickerContext() and usePickerActionsContext() to get the propspassed to the shortcuts and toolbar slots [pickers] Use usePickerContext() and usePickerActionsContext() instead of passing props to the shortcuts and toolbar slots Dec 20, 2024
@flaviendelangle flaviendelangle force-pushed the layout-last-props branch 3 times, most recently from 59ca6f1 to bfb0786 Compare December 20, 2024 11:24
/**
* Returns a function to check if a value is valid according to the validation props passed to the parent picker.
*/
export function useIsValidValue<TValue extends PickerValidValue>() {
Copy link
Member Author

@flaviendelangle flaviendelangle Dec 20, 2024

Choose a reason for hiding this comment

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

For now it's a super dumb hook.
It re-renders everytime the picker render and just calls the function that the picker gives him (which calls the validation).

But introducing this hook will allow us in the future to add it to the Date Calendar and Digital Clock as well and potentially to add some caching mechanism to avoid testing several times the same date.

For now it's only needed for the shortcut slot because we were passing this isValid prop.
When the view and the field will use it, it will probably impact the shape of the context(s) related to validation, but I'm pretty sure we will still have a hook with this exact signature 👌

@flaviendelangle flaviendelangle marked this pull request as ready for review December 20, 2024 11:53
* The shortcut that triggered this change.
* Should not be defined if the change does not come from a shortcut.
*/
shortcut?: PickersShortcutsItemContext;
Copy link
Member Author

Choose a reason for hiding this comment

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

In the Base UI version we won't have a notion of shortcut, so this field will probably only live in the MUI version (since some people needed it).

The other will be handled by the Base UI layer.

Copy link
Member

@michelengelen michelengelen left a comment

Choose a reason for hiding this comment

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

Looks good i general ... only concern is that we could simplify all places where we check for value == null || !utils.isValid(value) into utils.isValid(value) ... agree?

Comment on lines +372 to +375
// This contains a small behavior change.
// If the picker receives an invalid date,
// the old value would equal `null`.
// the new value would equal the invalid date received.
Copy link
Member

Choose a reason for hiding this comment

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

this feels like something is missing, no?

Comment on lines +503 to +506
// This contains a small behavior change.
// If the picker receives an invalid date,
// the old value would equal `null`.
// the new value would equal the invalid date received.
Copy link
Member

Choose a reason for hiding this comment

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

same as above

Comment on lines +34 to +35
const start = range[0] == null || !utils.isValid(range[0]) ? null : range[0];
const end = range[1] == null || !utils.isValid(range[1]) ? null : range[1];
Copy link
Member

Choose a reason for hiding this comment

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

couldn't we reverse the condition here? I did not check, but I think isValid on the adapters already include a if (value == null) return false, no?

Suggested change
const start = range[0] == null || !utils.isValid(range[0]) ? null : range[0];
const end = range[1] == null || !utils.isValid(range[1]) ? null : range[1];
const start = utils.isValid(range[0]) ? range[0] : null;
const end = utils.isValid(range[1]) ? range[1] : null;

const translations = usePickerTranslations();
const ownerState = useToolbarOwnerState();
const classes = useUtilityClasses(classesProp);

const dateText = React.useMemo(() => {
if (!value) {
if (value == null || !utils.isValid(value)) {
Copy link
Member

Choose a reason for hiding this comment

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

same as above ☝🏼

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!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[pickers] Remove all the props passed by usePickers to PickersLayout and use the new contexts instead
3 participants