Skip to content

Commit

Permalink
Merge pull request #80 from nfqde/fix/make-thumb-positioning-relative
Browse files Browse the repository at this point in the history
fix(ranges): Update thumb while animating container
  • Loading branch information
tajo authored May 19, 2020
2 parents 1bf15b3 + 652253a commit 4edcb7c
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 6 deletions.
4 changes: 3 additions & 1 deletion .storybook/example.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import LabeledMerge from '../examples/LabeledMerge';
import LabeledMergeSkinny from '../examples/LabeledMergeSkinny';
import LabeledMergeCustom from '../examples/LabeledMergeCustom';
import FinalChangeEvent from '../examples/FinalChangeEvent';
import AnimatingContainer from '../examples/AnimatingContainer';
// initialize polyfill for :focus-visible pseudo-class
import '../node_modules/focus-visible/dist/focus-visible.min.js';

Expand All @@ -41,4 +42,5 @@ storiesOf('Range', module)
.add('Merging labels', () => <LabeledMerge />)
.add('Merging labels skinny', () => <LabeledMergeSkinny />)
.add('Merging labels custom', () => <LabeledMergeCustom />)
.add('onFinalChange event', () => <FinalChangeEvent />);
.add('onFinalChange event', () => <FinalChangeEvent />)
.add('Animating container', () => <AnimatingContainer />);
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions e2e/animation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {
Examples,
getTestUrl,
addFontStyles
} from './utils';

jest.setTimeout(10000);

beforeEach(async () => {
await page.goto(getTestUrl(Examples.ANIMATING_CONTAINER));
await page.setViewport({ width: 600, height: 200 });
await addFontStyles(page);
});

test('update thumb when animating container', async () => {
expect(await page.screenshot()).toMatchImageSnapshot();
await new Promise(resolve => setTimeout(resolve, 2000));
expect(await page.screenshot()).toMatchImageSnapshot();
});
3 changes: 3 additions & 0 deletions e2e/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export enum Examples {
CUSTOM_MERGING_LABELS,
RTL,
FINAL_CHANGE_EVENT,
ANIMATING_CONTAINER
}

export const getTestUrl = (example: Examples): string => {
Expand Down Expand Up @@ -39,6 +40,8 @@ export const getTestUrl = (example: Examples): string => {
return `http://localhost:${PORT}/iframe.html?path=/story/range--rtl`;
case Examples.FINAL_CHANGE_EVENT:
return `http://localhost:${PORT}/iframe.html?path=/story/range--onfinalchange-event`;
case Examples.ANIMATING_CONTAINER:
return `http://localhost:${PORT}/iframe.html?path=/story/range--animating-container`;
}
};

Expand Down
98 changes: 98 additions & 0 deletions examples/AnimatingContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import * as React from 'react';
import { Range, getTrackBackground } from '../src/index';

const STEP = 0.1;
const MIN = 0;
const MAX = 100;

class AnimatingContainer extends React.Component {
state = {
values: [50],
expanded: true,
};

componentDidMount() {
this.setState({expanded: false});
}

render() {
return (
<div
style={{
display: 'flex',
justifyContent: 'center',
flexWrap: 'wrap',
width: this.state.expanded ? '100%' : '50%',
transition: 'width 1s ease 0.5s',
}}
>
<Range
values={this.state.values}
step={STEP}
min={MIN}
max={MAX}
onChange={values => this.setState({ values })}
renderTrack={({ props, children }) => (
<div
onMouseDown={props.onMouseDown}
onTouchStart={props.onTouchStart}
style={{
...props.style,
height: '36px',
display: 'flex',
width: '100%'
}}
>
<div
ref={props.ref}
style={{
height: '5px',
width: '100%',
borderRadius: '4px',
background: getTrackBackground({
values: this.state.values,
colors: ['#548BF4', '#ccc'],
min: MIN,
max: MAX
}),
alignSelf: 'center'
}}
>
{children}
</div>
</div>
)}
renderThumb={({ props, isDragged }) => (
<div
{...props}
style={{
...props.style,
height: '42px',
width: '42px',
borderRadius: '4px',
backgroundColor: '#FFF',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
boxShadow: '0px 2px 6px #AAA'
}}
>
<div
style={{
height: '16px',
width: '5px',
backgroundColor: isDragged ? '#548BF4' : '#CCC'
}}
/>
</div>
)}
/>
<output style={{ marginTop: '30px' }} id="output">
{this.state.values[0].toFixed(1)}
</output>
</div>
);
}
}

export default AnimatingContainer;
20 changes: 15 additions & 5 deletions src/Range.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ class Range extends React.Component<IProps> {
};
trackRef = React.createRef<HTMLElement>();
thumbRefs :React.RefObject<HTMLElement>[] = [];
resizeObserver: any;
schdOnMouseMove: (e: MouseEvent) => void;
schdOnTouchMove: (e: TouchEvent) => void;
schdOnEnd: (e: Event) => void;
schdOnWindowResize: () => void;
schdOnResize: () => void;

state = {
draggedThumbIndex: -1,
Expand All @@ -48,9 +49,18 @@ class Range extends React.Component<IProps> {
this.schdOnMouseMove = schd(this.onMouseMove);
this.schdOnTouchMove = schd(this.onTouchMove);
this.schdOnEnd = schd(this.onEnd);
this.schdOnWindowResize = schd(this.onWindowResize);
this.schdOnResize = schd(this.onResize);
this.thumbRefs = props.values.map(() => React.createRef<HTMLElement>());

// @ts-ignore
this.resizeObserver = (window.ResizeObserver)
// @ts-ignore
? new window.ResizeObserver(this.schdOnResize)
: {
observe: () => window.addEventListener('resize', this.schdOnResize),
unobserve: () => window.removeEventListener('resize', this.schdOnResize)
};

if (!isStepDivisible(props.min, props.max, props.step)) {
console.warn(
'The difference of `max` and `min` must be divisible by `step`'
Expand All @@ -60,7 +70,6 @@ class Range extends React.Component<IProps> {

componentDidMount() {
const { values, min, step } = this.props;
window.addEventListener('resize', this.schdOnWindowResize);
document.addEventListener('touchstart', this.onMouseOrTouchStart as any, {
passive: false
});
Expand All @@ -71,6 +80,7 @@ class Range extends React.Component<IProps> {
this.props.values.forEach(value =>
checkBoundaries(value, this.props.min, this.props.max)
);
this.resizeObserver.observe(this.trackRef.current!)
translateThumbs(this.getThumbs(), this.getOffsets(), this.props.rtl);

values.forEach(value => {
Expand All @@ -90,10 +100,10 @@ class Range extends React.Component<IProps> {
const options: AddEventListenerOptions = {
passive: false
};
window.removeEventListener('resize', this.schdOnWindowResize);
document.removeEventListener('mousedown', this.onMouseOrTouchStart as any, options);
document.removeEventListener('touchstart', this.onMouseOrTouchStart as any);
document.removeEventListener('touchend', this.schdOnEnd as any);
this.resizeObserver.unobserve(this.trackRef.current!)
}

getOffsets = () => {
Expand Down Expand Up @@ -200,7 +210,7 @@ class Range extends React.Component<IProps> {
);
};

onWindowResize = () => {
onResize = () => {
translateThumbs(this.getThumbs(), this.getOffsets(), this.props.rtl);
};

Expand Down

0 comments on commit 4edcb7c

Please sign in to comment.