palantir / blueprint

A React-based UI toolkit for the web
https://blueprintjs.com/
Apache License 2.0
20.71k stars 2.17k forks source link

Slider style props support or innerStyle #4456

Open ilomon10 opened 3 years ago

ilomon10 commented 3 years ago

Environment

Feature request

Add style props support for Slider component to modify style property on specific element

Examples

<Slider
  style={{ height: "100%" }}
  // OR
  innerStyle={{ height: "100%" }}
/>
adidahiya commented 3 years ago

Most of our components don't have style prop support; you mostly can achieve the same thing with className="your-custom-class" and some CSS.

ShiftedDesign commented 2 years ago

style props support would be especially helpful on MultiSlider with multiple Handles.

I have an instance where I have a uncertain amount of handles, each representing a dynamic color value.

    <StyledGradientEditor colors={props.colors.value}>
      <MultiSlider min={0} max={100} labelStepSize={20}>
        {props.colors.map((colorObj, index) => (
          <MultiSlider.Handle
            value={colorObj.stop.value}
            onChange={v => colorObj.stop.set(v)}
            className={colorObj.id.value}
            key={colorObj.id.value}
          />
        ))}
      </MultiSlider>
    </StyledGradientEditor>

I'm currently working around the inability to add style to each handle by giving it a dynamic id and then in the wrapping container assigning a custom class using StyledComponents that then sets the color of the handle:

const StyledGradientEditor = styled.div<{ colors: { color: RGBColor; id: string }[] }>`
  padding: 5px 10px;
  ${props =>
    props.colors.map(
      color =>
        `.${color.id}{
            background-color: ${getHexColor(color.color)} !important;
        }`
    )}
`;

This has some race issues with populating the class before rendering the handle but works probably 70% of the time. This would a non-issue with the ability to add the style prop to each handle which would dynamically control it's own color.

Is there a reason that some do and most don't support style?

Another note, the MultiSlider component is extremely strict with the child handles, for instance even trying to use a StyledComponent like:

const StyledHandle = styled(MultiSlider.Handle)``;

Throws a hard error, which could be another solution to getting around the style prop and follows how we go about styling other blueprint components.

adidahiya commented 2 years ago

Is there a reason that some do and most don't support style?

It's just extra code & maintenance to support arbitrary HTML attributes for every component. There will always be special considerations we have to take; it's usually not as simple as a one-line {...this.props} change. In this case, for example, we'd have to take care to merge this.props.style with the styles generated by Handle#getStyleProperties(). But if we think it's worth it for use-cases like the one you just described with an arbitrary number of handles in a MultiSlider, then I would consider adding the HTML props spread to allow <Handle style={...}>.

As for component prop/children validation throwing a hard error... over time I have moved towards the stance that we should not throw such hard errors so often, and instead should mostly use console.error() instead. I'd definitely be open to changing MultiSlider and Handle so that they use console.error instead of throw new Error.

ShiftedDesign commented 2 years ago

That's awesome news, either solution would work for me whether it is adding the style={...} prop or making it not throw new Error.

The update is much appreciated!

adidahiya commented 2 years ago

Actually, loosening children validation won't work, since we look at child.props directly for each child of MultiSlider... see https://github.com/palantir/blueprint/pull/5459#issuecomment-1192743634. If we want to address your use case, we might have to implement the style prop instead.

Can you show me what kind of UI you're trying to achieve? Why are you customizing the handle appearance?

ShiftedDesign commented 2 years ago

I was using the slider component to create a gradient editor, the handles were the individual colors and their stops. Here is a screenshot and you can see most of the handles are the correct colors except 46 which is the default handle color. image

Adding the style prop would cover my needs as well.