mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.43k stars 32.16k forks source link

[Slider] marks texts are out of bounds when labels are too long #32345

Open abriginets opened 2 years ago

abriginets commented 2 years ago

Duplicates

Latest version

Current behavior 😯

If your marks text is too big then it's going to move out of it's parent's element bounds. image

The same applies to tooltips image

Expected behavior πŸ€”

I'd suggest adding a new option to slider which would prevent overflow. Not sure if MUI is still using Popper.js, but they have this feature built-in https://popper.js.org/docs/v2/modifiers/prevent-overflow/

Steps to reproduce πŸ•Ή

Just create any slider inside of Paper and add mark with long label in props.

Context πŸ”¦

No response

Your environment 🌎

`npx @mui/envinfo` **Browser is Chrome 100** ``` System: OS: Linux 5.4 Ubuntu 20.04.4 LTS (Focal Fossa) Binaries: Node: 16.13.1 - ~/.asdf/installs/nodejs/16.13.1/bin/node Yarn: Not Found npm: 8.1.2 - ~/.asdf/plugins/nodejs/shims/npm Browsers: Chrome: Not Found Firefox: Not Found npmPackages: @emotion/react: ^11.9.0 => 11.9.0 @emotion/styled: ^11.8.1 => 11.8.1 @mui/base: 5.0.0-alpha.76 @mui/icons-material: ^5.6.1 => 5.6.1 @mui/lab: ^5.0.0-alpha.77 => 5.0.0-alpha.77 @mui/material: ^5.6.1 => 5.6.1 @mui/private-theming: 5.6.1 @mui/styled-engine: 5.6.1 @mui/system: 5.6.1 @mui/types: 7.1.3 @mui/utils: 5.6.1 @mui/x-date-pickers: ^5.0.0-alpha.0 => 5.0.0-alpha.0 @types/react: ^17.0.44 => 17.0.44 react: ^17.0.2 => 17.0.2 react-dom: ^17.0.2 => 17.0.2 typescript: ^4.6.3 => 4.6.3 ```
PunitSoniME commented 2 years ago

Can you provide codesandbox link example with issue please ?

You can fork this Codesandbox

abriginets commented 2 years ago

Sure, there it is https://codesandbox.io/s/delicate-morning-f1cd1q?file=/src/index.tsx

mnajdova commented 2 years ago

I assume you meant Slider, not Checkbox. In cases like this, I would assume the parent component should basically grow as the content (or be wider in order to have place for the marks). But if there is someone from the community willing to dive into this enhancement, it would be great.

abriginets commented 2 years ago

Yes, sorry, I meant Slider.

I would assume the parent component should basically grow as the content

I was also thinking about simply shorting the number but sometimes I just don't know how big this number would be and how Intl API would display the multiplier value.

For anyone who's going to work on this I suggest you take Ion.RangeSlider's behavior as a reference. You can see that it keeps edge mark texts in bounds when centering it under the mark is not possible.

image

PunitSoniME commented 2 years ago

I assume you meant Slider, not Checkbox. In cases like this, I would assume the parent component should basically grow as the content (or be wider in order to have place for the marks). But if there is someone from the community willing to dive into this enhancement, it would be great.

That's why I asked him to add example 😁

nicolas-ot commented 1 year ago

Im working on this

ZeeshanTamboli commented 1 year ago

Closing this. See https://github.com/mui/material-ui/pull/36891#pullrequestreview-1434429976.

MetaMmodern commented 1 year ago

@ZeeshanTamboli I think this issue should be reopened. In the linked PR it's mentioned that this should be controlled by style, but no solution was provided on how styling should be applied. Two more things to take a note of:

  1. This is not only about the last mark label, same applies to a starting label.
  2. This also applies to the marks in the track as well, if you make them circular and big they get out of track bounds. I'd like to have an option to put them in bound of track. The still can be distributed evenly though.

To be clear, look at this input

image

And now look at the boundaries of the input

image

It's clear that the last circle drops out of bound. I couldn't find any examples of such design on net though.

Why this matters for me? It causes visual bugs of underlying labels(that are not part of input) to look weird, and also the labels that are marks inside input also sometimes look weird. It doesn't match up nicely with our design system:

image

At least please provide a temporary solution for this, thanks.

ZeeshanTamboli commented 1 year ago

@MetaMmodern What I meant was to override the styles or apply custom styles. Can you provide a CodeSandbox with the issues you are facing and the steps on how to inspect them? I suggest using Stack Overflow for the solutions to these questions.

MetaMmodern commented 1 year ago

@MetaMmodern What I meant was to override the styles or apply custom styles. Can you provide a CodeSandbox with the issues you are facing and the steps on how to inspect them? I suggest using Stack Overflow for the solutions to these questions.

Hi! I think the above sandbox already covers both my problem and OPs problem, but I can create a new one as well with my styles. The problem with overriding styles or applying custom styles is that it's not that easy. The positioning of marks and mark labels is controlled internally by MUI and done through applying a style="left: {value}%" property to marks and to mark labels. So, it's something we can override only using '!important', and not only that, I don't know how that % is calculated. If by custom style you mean to apply a transform translateX(), then the issue is that it gets applied to all marks and all marks are shifted to the left then. If you mean to apply it to the last mark/mark label only, then the problem is that elements are not then distributed correctly. So you need to apply a calculated transform, but idk what do I need to base it calculus on. Maximum I can check the data-attribute and take it, but I don't see the total number of elements in my styling.

So yeah, this is a problem, mui controls marks placement through JS, that's how it knows the number of elements. And we can't customize it directly through sx or theme, cause our theme doesn't have such knowledge.

ZeeshanTamboli commented 1 year ago

@MetaMmodern Consider sharing a CodeSandbox with your styles (Starting template). I'll try to help you find a solution. Since you mentioned struggling with custom styles with Material UI's Slider, you might want to explore the headless ("unstyled") Slider component as an alternative. Check out the Base UI Slider at https://mui.com/base-ui/react-slider/.

MetaMmodern commented 1 year ago

@ZeeshanTamboli thank you for providing the template. Here's the repro: https://codesandbox.io/s/slider-out-of-bound-4tvlgc . Please find osme time to check it out, thank you.

I've also checked the baseUi component even before finding this thread, the core problem is as described above: you can't do this calculus out of component through xs, theme or by providing custom slots. Although it may be possible, but I have low hopes on that.

ZeeshanTamboli commented 1 year ago

@MetaMmodern, I compared it with Joy UI's Slider - https://mui.com/joy-ui/react-slider/#custom-marks. Over there, the last mark is inside the slider track due to a specific style applied to the last mark (when it's 100%). You can see the relevant code here: https://github.com/mui/material-ui/blob/6b99bc55253b21b856cd7a0df1888a3377525236/packages/mui-joy/src/Slider/Slider.tsx#L281-L283 However, this means that the marks are not evenly distributed within the bounds. Maybe that is intended for Joy UI slider.

You mentioned that applying the transform style shifts all the marks to the left. But they are distributed correctly. If you're okay with applying this to all marks, you can use the following transform style on the mark:

transform: "translate(calc(2px * -1 - min(2px, 3px)), -50%)"

This style is the same as the one used for the last mark in Joy UI's Slider. You can find this example in this CodeSandbox: https://codesandbox.io/s/slider-out-of-bound-forked-nk5mks?file=/src/App.tsx:665-726.

Does this workaround help you?

I'm reopening this issue.

MetaMmodern commented 1 year ago

@ZeeshanTamboli Thanks for the example and for reopening the issue. I'm afk, but currently can tell for sure that applying transform to all marks is not a suitable solution, because then the first mark will be shifted to the left becoming out of bound. Although distribution is preserved, the core of problem remains the same: part of component gets out of bound.

dehli commented 11 months ago

This won't solve the issue for all users, but figured I'd share what I ended up doing to address my specific use-case.

Original slider:

image

I updated CSS of labels to be:

// Left-most label
transform: translateX(0); 

// Right-most label 
transform: translateX(-100%);
image
vshee-techdev commented 4 months ago

@dehli can you mind sharing how you targeted // Right-most label i was trying to achieve it as last child but it doesnt work

dehli commented 4 months ago

@vshee-techdev Sure! I accomplished it using the sx property. It's not a general solution, but for my specific use-case it was fine.


{
  "& .MuiSlider-markLabel[data-index='0']": {
    transform: "translateX(0)"
  },
  "& .MuiSlider-markLabel[data-index='1']": {
    transform: "translateX(-100%)"
  }
}