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

[Slider][base] Improve logic for displaying value label #35479

Conversation

ZeeshanTamboli
Copy link
Member

@ZeeshanTamboli ZeeshanTamboli commented Dec 14, 2022

Breaking Changes for MUI Base:

- <SliderUnstyled valueLabelDisplay="on" />
+ <SliderUnstyled slots={{ valueLabel: SliderValueLabel }} /> 

The following demo shows how to show value label when it is hovered upon the thumb: https://deploy-preview-35479--material-ui.netlify.app/base/react-slider/#value-label

  • The following classes are removed from sliderUnstyledClasses since they are not needed for value label:
- valueLabel
- valueLabelOpen
- valueLabelCircle
- valueLabelLabel

You can define your own classNames in the custom value label component and target them in CSS.

  • The SliderValueLabelUnstyled component is removed from SliderUnstyled. You can provide your own custom component for the value label.

  • The Value label component hierarchy structure is changed to avoid using React.cloneElement in value label. The value label is now inside the Thumb slot - Thumb -> Input, ValueLabel.


There are two things in this PR:

  • Move the logic of valueLabelDisplay prop to Material UI. To do this, we migrate the Material UI Slider to use useSlider hook. This has the advantage of how the Slider's component structure is rendered by Material UI and also we are able to have the valueLabelDisplay logic controlled which is not needed in MUI Base due to the point below.
  • Remove the SliderLabelValueUnstyled component from MUI Base and show the value label by simply hovering on the thumb in SliderUnstyled. Add demos to showcase it (preview below). To avoid breaking changes in Material UI, we keep the same component structure like SliderLabelValueUnstyled for the value label.

Preview: https://deploy-preview-35479--material-ui.netlify.app/base/react-slider/#value-label

Closes #35398

@ZeeshanTamboli ZeeshanTamboli added component: slider This is the name of the generic UI component, not the React module! package: base-ui Specific to @mui/base labels Dec 14, 2022
@mui-bot
Copy link

mui-bot commented Dec 14, 2022

Messages
📖 Netlify deploy preview: https://deploy-preview-35479--material-ui.netlify.app/

@material-ui/core: parsed: -0.16% 😍, gzip: -0.19% 😍
@material-ui/unstyled: parsed: -0.66% 😍, gzip: -0.50% 😍

Details of bundle changes

Generated by 🚫 dangerJS against 886803e

@ZeeshanTamboli ZeeshanTamboli changed the title [SliderUnstyled] Improve logic for displaying value label [Slider][Base] Improve logic for displaying value label Dec 15, 2022
@ZeeshanTamboli ZeeshanTamboli added breaking change bug 🐛 Something doesn't work labels Dec 23, 2022
@ZeeshanTamboli ZeeshanTamboli marked this pull request as ready for review December 23, 2022 14:27
@ZeeshanTamboli ZeeshanTamboli requested a review from a team December 23, 2022 14:31
@ZeeshanTamboli ZeeshanTamboli added the docs Improvements or additions to the documentation label Dec 23, 2022
@ZeeshanTamboli ZeeshanTamboli changed the title [Slider][Base] Improve logic for displaying value label [Slider][base] Improve logic for displaying value label Dec 26, 2022
docs/data/base/components/slider/slider.md Outdated Show resolved Hide resolved
docs/data/base/components/slider/slider.md Outdated Show resolved Hide resolved
docs/data/base/components/slider/slider.md Outdated Show resolved Hide resolved
@@ -60,7 +60,7 @@
"slotProps": {
"type": {
"name": "shape",
"description": "{ input?: func<br>&#124;&nbsp;object, mark?: func<br>&#124;&nbsp;object, markLabel?: func<br>&#124;&nbsp;object, rail?: func<br>&#124;&nbsp;object, root?: func<br>&#124;&nbsp;object, thumb?: func<br>&#124;&nbsp;object, track?: func<br>&#124;&nbsp;object, valueLabel?: func<br>&#124;&nbsp;{ children?: element, className?: string, open?: bool, style?: object, value?: number, valueLabelDisplay?: 'auto'<br>&#124;&nbsp;'off'<br>&#124;&nbsp;'on' } }"
"description": "{ input?: func<br>&#124;&nbsp;object, mark?: func<br>&#124;&nbsp;object, markLabel?: func<br>&#124;&nbsp;object, rail?: func<br>&#124;&nbsp;object, root?: func<br>&#124;&nbsp;object, thumb?: func<br>&#124;&nbsp;object, track?: func<br>&#124;&nbsp;object, valueLabel?: any<br>&#124;&nbsp;func }"
Copy link
Member

@mnajdova mnajdova Dec 30, 2022

Choose a reason for hiding this comment

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

There shouldn't change here, the Material UI API's stays intact.

Copy link
Member Author

Choose a reason for hiding this comment

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

It is because of this change in the slotProps type in SliderUnstyled.d.ts:

--- a/packages/mui-base/src/SliderUnstyled/SliderUnstyled.types.ts
+++ b/packages/mui-base/src/SliderUnstyled/SliderUnstyled.types.ts
@@ -171,7 +171,7 @@ export interface SliderUnstyledOwnProps {
       SliderUnstyledOwnerState
     >;
     valueLabel?: SlotComponentProps<
-      typeof SliderValueLabelUnstyled,
+      React.ElementType,
       SliderUnstyledComponentsPropsOverrides,
       SliderUnstyledOwnerState
     >;

SliderValueLabelUnstyled component is removed and the Material UI Slider types extend the SliderUnstyled types.
Is there any way? There is one DeepOmit utility: https://github.com/ts-essentials/ts-essentials#deepomit.

@@ -155,7 +149,7 @@ const SliderUnstyled = React.forwardRef(function SliderUnstyled(props, ref) {
ownerState,
});

const ValueLabel = slots.valueLabel ?? SliderValueLabelUnstyled;
const ValueLabel = slots.valueLabel;
Copy link
Member

Choose a reason for hiding this comment

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

Will this simplify the implementation:

Suggested change
const ValueLabel = slots.valueLabel;
const ValueLabel = slots.valueLabel ?? Forward;

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 ValueLabel is now inside the Thumb slot in the JSX structure so it's not needed to Forward the children.

value={values[index]}
{...inputProps}
/>
{ValueLabel ? (
Copy link
Member

Choose a reason for hiding this comment

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

This would change the structure for the Material UI components. What was the reason for changing it? The ValueLabel should wrap the Thumb.

Copy link
Member Author

Choose a reason for hiding this comment

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

This would change the structure for the Material UI components.

It won't change since SliderUnstyled is not used in Material UI's Slider component now. We use the useSlider hook and keep the JSX structure intact like the current SliderUnstyled in production. The useSlider hook is used to implement the valueLabelDisplay logic in Material UI Slider.

What was the reason for changing it?

If you inspect the generated HTML DOM structure, the value label is actually inside the thumb slot due to this code in the SliderValueLabelUnstyled. It means that even though the ValueLabel wraps the thumb in the JSX structure, in the final generated HTML the thumb wraps the value label due to React.cloneElement.

Thus I changed the structure only in SliderUnstyled and avoided the need to provide the complicated React.cloneElement implementation for custom ValueLabel component.

This is how Joy UI's Slider is also implemented. See https://github.com/mui/material-ui/blob/master/packages/mui-joy/src/Slider/Slider.tsx#L608-L639.


I would also recommend to read the PR description and also review Slider.js file in packages/@mui-material in this PR if you haven't.

Copy link
Member

Choose a reason for hiding this comment

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

For easing up the review I would recommend splitting this in two pull requests. We can go first with replacing the SliderUnstyled with useSlider in @mui/material. It's important we don't have regressions with this change. After this one, we can safely do any changes we want to the SliderUnstyled, making sure it won't affect the Material UI's version. We aim to have each PR fix one particular problem, this would also make the review much easier.

I would also recommend to read the PR description and also review Slider.js file in packages/@mui-material in this PR if you haven't.

I focused only on the changes inside SliderUnstyled in the initial review, haven't checked the other changes, I was only looking for potential breaking changes we may do.

Copy link
Member Author

Choose a reason for hiding this comment

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

It makes sense. I will split it into two PRs.

packages/mui-base/src/SliderUnstyled/SliderUnstyled.js Outdated Show resolved Hide resolved
ZeeshanTamboli and others added 9 commits December 30, 2022 19:28
Co-authored-by: Marija Najdova <mnajdova@gmail.com>
Signed-off-by: Zeeshan Tamboli <zeeshan.tamboli@gmail.com>
Co-authored-by: Marija Najdova <mnajdova@gmail.com>
Signed-off-by: Zeeshan Tamboli <zeeshan.tamboli@gmail.com>
Co-authored-by: Marija Najdova <mnajdova@gmail.com>
Signed-off-by: Zeeshan Tamboli <zeeshan.tamboli@gmail.com>
@ZeeshanTamboli
Copy link
Member Author

As discussed in #35479 (comment), splitting this PR into two PRs. So closing in favor of #35770 and ZeeshanTamboli#2.

@ZeeshanTamboli ZeeshanTamboli deleted the issue/35398-remove-valueLabelDisplay-and-add-demo branch February 6, 2023 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change bug 🐛 Something doesn't work component: slider This is the name of the generic UI component, not the React module! docs Improvements or additions to the documentation package: base-ui Specific to @mui/base
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[docs] Customize valueLabel in SliderUnstyled with tailwind
3 participants