Skip to content

Commit

Permalink
feat: renderThumb now renders the entire thumb node rather than jus…
Browse files Browse the repository at this point in the history
…t the thumb content

BREAKING CHANGE: The render props `renderThumb` and `renderTrack` are now passed two arguments
instead of one, `props` and `state`. This makes it easier to just spread props when using
a render function.
  • Loading branch information
Brian Stone authored and stonebk committed Sep 27, 2019
1 parent 9fa9eb4 commit 669dcdb
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 45 deletions.
75 changes: 40 additions & 35 deletions src/components/ReactSlider/ReactSlider.jsx
Expand Up @@ -215,33 +215,39 @@ class ReactSlider extends React.Component {
* The function will be passed a single argument,
* an object with the following properties:
*
* - `index` {`number`} the index of the thumb
* - 'value' {`number` | `array`} the current value state
* state => `Value: ${state.value}`
*
* - `state.index` {`number`} the index of the thumb
* - `state.value` {`number` | `array`} the current value state
*/
// eslint-disable-next-line zillow/react/require-default-props
ariaValuetext: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

/**
* Provide a custom render function for the track node.
* The render function will be passed a single argument,
* an object with the following properties:
* The render function will be passed two arguments,
* an object with props that should be added to your handle node,
* and an object with track and slider state:
*
* (props, state) => <div {...props} />
*
* - `index` {`number`} the index of the track
* - `key` {`string`} a unique key for the track
* - 'value' {`number` | `array`} the current value state
* - `style` {`object`} positioning styles that should be applied to the node
* - `className` {`string`} default classNames for the track
* - `props` {`object`} props to be spread into your track node
* - `state.index` {`number`} the index of the track
* - `state.value` {`number` | `array`} the current value state
*/
renderTrack: PropTypes.func,

/**
* Provide a custom render function for dynamic thumb content.
* The render function will be passed a single argument,
* an object with the following properties:
* The render function will be passed two arguments,
* an object with props that should be added to your thumb node,
* and an object with thumb and slider state:
*
* (props, state) => <div {...props} />
*
* - `index` {`number`} the index of the thumb
* - `key` {`string`} a unique key for the thumb
* - 'value' {`number` | `array`} the current value state
* - `props` {`object`} props to be spread into your thumb node
* - `state.index` {`number`} the index of the thumb
* - `state.value` {`number` | `array`} the current value state
*/
// eslint-disable-next-line zillow/react/require-default-props
renderThumb: PropTypes.func,
Expand All @@ -264,6 +270,7 @@ class ReactSlider extends React.Component {
disabled: false,
snapDragDisabled: false,
invert: false,
renderThumb: props => <div {...props} />,
renderTrack: props => <div {...props} />,
};

Expand Down Expand Up @@ -844,7 +851,7 @@ class ReactSlider extends React.Component {
return obj;
}

renderThumb = (style, child, i) => {
renderThumb = (style, i) => {
const className = `${this.props.thumbClassName} ${this.props.thumbClassName}-${i} ${
this.state.index === i ? this.props.thumbActiveClassName : ''
}`;
Expand All @@ -853,7 +860,7 @@ class ReactSlider extends React.Component {
ref: r => {
this[`thumb${i}`] = r;
},
key: `thumb${i}`,
key: `${this.props.thumbClassName}-${i}`,
className,
style,
onMouseDown: this.createOnMouseDown(i),
Expand All @@ -880,7 +887,12 @@ class ReactSlider extends React.Component {
});
}

return React.createElement('div', props, child);
const state = {
index: i,
value: undoEnsureArray(this.state.value),
};

return this.props.renderThumb(props, state);
};

renderThumbs(offset) {
Expand All @@ -892,31 +904,24 @@ class ReactSlider extends React.Component {
}

const res = [];
if (this.props.renderThumb) {
for (let i = 0; i < length; i += 1) {
const child = this.props.renderThumb({
index: i,
key: `${this.props.thumbClassName}-${i}`,
value: undoEnsureArray(this.state.value),
});
res[i] = this.renderThumb(styles[i], child, i);
}
} else {
for (let i = 0; i < length; i += 1) {
res[i] = this.renderThumb(styles[i], null, i);
}
for (let i = 0; i < length; i += 1) {
res[i] = this.renderThumb(styles[i], i);
}
return res;
}

renderTrack = (i, offsetFrom, offsetTo) =>
this.props.renderTrack({
index: i,
renderTrack = (i, offsetFrom, offsetTo) => {
const props = {
key: `${this.props.trackClassName}-${i}`,
value: undoEnsureArray(this.state.value),
className: `${this.props.trackClassName} ${this.props.trackClassName}-${i}`,
style: this.buildTrackStyle(offsetFrom, this.state.upperBound - offsetTo),
});
};
const state = {
index: i,
value: undoEnsureArray(this.state.value),
};
return this.props.renderTrack(props, state);
};

renderTracks(offset) {
const tracks = [];
Expand Down
12 changes: 6 additions & 6 deletions src/components/ReactSlider/ReactSlider.md
Expand Up @@ -5,7 +5,7 @@ Single slider, similar to `<input type="range" defaultValue={0} />`
className="horizontal-slider"
thumbClassName="example-thumb"
trackClassName="example-track"
renderThumb={({ value }) => value}
renderThumb={(props, state) => <div {...props}>{state.value}</div>}
/>
```

Expand All @@ -19,7 +19,7 @@ Double slider
defaultValue={[0, 100]}
ariaLabel={['Lower thumb', 'Upper thumb']}
ariaValuetext={({ index, value }) => `Thumb value ${value[index]}`}
renderThumb={({ index, value }) => value[index]}
renderThumb={(props, state) => <div {...props}>{state.value[state.index]}</div>}
pearling
minDistance={10}
/>
Expand All @@ -34,7 +34,7 @@ Multi slider
trackClassName="example-track"
defaultValue={[0, 50, 100]}
ariaLabel={['Leftmost thumb', 'Middle thumb', 'Rightmost thumb']}
renderThumb={({ index, value }) => value[index]}
renderThumb={(props, state) => <div {...props}>{state.value[state.index]}</div>}
pearling
minDistance={10}
/>
Expand All @@ -49,7 +49,7 @@ Vertical slider
trackClassName="example-track"
defaultValue={[0, 50, 100]}
ariaLabel={['Lowest thumb', 'Middle thumb', 'Top thumb']}
renderThumb={({ index, value }) => value[index]}
renderThumb={(props, state) => <div {...props}>{state.value[state.index]}</div>}
orientation="vertical"
invert
pearling
Expand Down Expand Up @@ -78,7 +78,7 @@ const StyledThumb = styled.div`
cursor: grab;
`;

const Thumb = ({ index, value, ...props }) => <StyledThumb {...props}>{value[index]}</StyledThumb>;
const Thumb = (props, state) => <StyledThumb {...props}>{state.value[state.index]}</StyledThumb>;

const StyledTrack = styled.div`
top: 0;
Expand All @@ -87,7 +87,7 @@ const StyledTrack = styled.div`
border-radius: 999px;
`;

const Track = ({ className, ...props }) => <StyledTrack {...props} />;
const Track = (props, state) => <StyledTrack {...props} index={state.index} />;

<StyledSlider
defaultValue={[50, 75]}
Expand Down
Expand Up @@ -13,7 +13,6 @@ exports[`<ReactSlider> can render 1`] = `
>
<div
className="track track-0"
index={0}
style={
Object {
"left": 0,
Expand All @@ -22,11 +21,9 @@ exports[`<ReactSlider> can render 1`] = `
"willChange": "",
}
}
value={0}
/>
<div
className="track track-1"
index={1}
style={
Object {
"left": 0,
Expand All @@ -35,7 +32,6 @@ exports[`<ReactSlider> can render 1`] = `
"willChange": "",
}
}
value={0}
/>
<div
aria-orientation="horizontal"
Expand Down

0 comments on commit 669dcdb

Please sign in to comment.