zillow / react-slider

Accessible, CSS agnostic, slider component for React.
https://zillow.github.io/react-slider
MIT License
891 stars 232 forks source link

Mark appears outside of slider if minimum is not 0 #214

Closed sohymg closed 2 years ago

sohymg commented 3 years ago

Description

If min > 0, the first mark is rendered outside of slider.

CodeSandbox

Sorry I couldn't get the marks to appear in the sandbox. This is how it looks like if min=1

image

stonebk commented 3 years ago

Hi @sohymg, sorry, without a sandbox that reproduces the issue, we can't figure out what is wrong with your usage.

Please add a codesandbox and we can reopen.

peterboyer commented 3 years ago

@sohymg Yep, just ran into this issue now.

@stonebk Please re-open this issue. Here is a CodeSandbox link: https://codesandbox.io/s/aged-sea-h7np2?file=/src/App.js

Screen Shot 2021-06-01 at 13 54 05

peterboyer commented 3 years ago

For those who want a fix now here, I solved this by implementing a drop-in replacement component that patches the min/max/value/onChange props to operate as if the min was 0 (which displays correctly).

The idea is, for whatever your min value is treat it as 0 and the max value will compensate. Then whatever value is set apply the reverse of the min value transform to get the intended value.

import { useCallback } from "react";
import BaseReactSlider, {
  ReactSliderProps as BaseReactSliderProps,
} from "react-slider";

interface Props extends BaseReactSliderProps {}

export type { Props as ReactSliderProps };

/**
 * Temporary workaround for https://github.com/zillow/react-slider/issues/214
 * Once fixed, import in slider-extended can be reset to import from the
 * original react-slider library instead.
 */
export const ReactSlider: React.FC<Props> = (props) => {
  const {
    value: rawValue = 0,
    onChange: rawOnChange,
    min: rawMin = 0,
    max: rawMax = 100,
    ...forwardedProps
  } = props;

  const value = rawValue - rawMin;
  const onChange = useCallback(
    (nextValue: number) => {
      rawOnChange && rawOnChange(nextValue + rawMin);
    },
    [rawOnChange]
  );
  const min = 0;
  const max = rawMax - rawMin;

  return (
    <BaseReactSlider
      {...forwardedProps}
      value={value}
      onChange={onChange}
      min={min}
      max={max}
    />
  );
};

export default ReactSlider;
stonebk commented 3 years ago

~@ptboyer what browser/platform are you using? It looks OK to me:~

Screen Shot 2021-06-01 at 3 20 56 PM

Scratch that, I see now:

Screen Shot 2021-06-01 at 3 24 16 PM

MauroTaliente commented 3 years ago

Hi, solved this problem by forcing a new size adjustment. I hope to be helpful

` // RESIZE HACK const sliderRef = useRef(null); useEffect(() => { if (!sliderRef.current) return; sliderRef.current.handleResize(); return () => {} }, [sliderRef]);

<ReactSlider
  {...{
    ref: sliderRef,
  ...

`

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Hampei commented 2 years ago

problem is in renderMarks

marks = Array.from({ length: range }).map((_, key) => key);

This should be marks = Array.from({ length: range }).map((_, key) => key + min);

I had a quick try to fix it, but can't test it within react-test-renderer, since the slider does not have a size and that's not easy to add within that lib. Probably need to switch to enzymn to get some proper tests of this. Would it be ok to add this?