Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Malte Wessel committed May 12, 2017
2 parents b96c917 + 6cf5174 commit bc0fe12
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 180 deletions.
2 changes: 1 addition & 1 deletion docs/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class CustomScrollbars extends Component {
return (
<Scrollbars
renderTrackHorizontal={({ style, ...props }) =>
<div {...props} style={{ ...style, backgroundColor: 'blue' }}>
<div {...props} style={{ ...style, backgroundColor: 'blue' }}/>
}>
{this.props.children}
</Scrollbars>
Expand Down
4 changes: 2 additions & 2 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ class App extends Component {
// Called when scrolling starts
onScrollStart={this.handleScrollStart}
// Called when scrolling stops
onScrollStop={this.handlenScrollStop}>
onScrollStop={this.handlenScrollStop}
// Called when ever the component is updated. Runs inside the animation frame
onUpdate={this.handleUpdate}
onUpdate={this.handleUpdate}>
<p>Some great content...</p>
</Scrollbars>
);
Expand Down
133 changes: 64 additions & 69 deletions src/Scrollbars/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,25 @@ export default class Scrollbars extends Component {
constructor(props, ...rest) {
super(props, ...rest);

this.getScrollLeft = this.getScrollLeft.bind(this);
this.getScrollTop = this.getScrollTop.bind(this);
this.getScrollWidth = this.getScrollWidth.bind(this);
this.getScrollHeight = this.getScrollHeight.bind(this);
this.getClientWidth = this.getClientWidth.bind(this);
this.getClientHeight = this.getClientHeight.bind(this);
this.getValues = this.getValues.bind(this);
this.getThumbHorizontalWidth = this.getThumbHorizontalWidth.bind(this);
this.getThumbVerticalHeight = this.getThumbVerticalHeight.bind(this);
this.getScrollLeftForOffset = this.getScrollLeftForOffset.bind(this);
this.getScrollTopForOffset = this.getScrollTopForOffset.bind(this);

this.scrollLeft = this.scrollLeft.bind(this);
this.scrollTop = this.scrollTop.bind(this);
this.scrollToLeft = this.scrollToLeft.bind(this);
this.scrollToTop = this.scrollToTop.bind(this);
this.scrollToRight = this.scrollToRight.bind(this);
this.scrollToBottom = this.scrollToBottom.bind(this);

this.handleTrackMouseEnter = this.handleTrackMouseEnter.bind(this);
this.handleTrackMouseLeave = this.handleTrackMouseLeave.bind(this);
this.handleHorizontalTrackMouseDown = this.handleHorizontalTrackMouseDown.bind(this);
Expand Down Expand Up @@ -76,45 +95,38 @@ export default class Scrollbars extends Component {
}

getScrollLeft() {
const { view } = this.refs;
return view.scrollLeft;
return this.view.scrollLeft;
}

getScrollTop() {
const { view } = this.refs;
return view.scrollTop;
return this.view.scrollTop;
}

getScrollWidth() {
const { view } = this.refs;
return view.scrollWidth;
return this.view.scrollWidth;
}

getScrollHeight() {
const { view } = this.refs;
return view.scrollHeight;
return this.view.scrollHeight;
}

getClientWidth() {
const { view } = this.refs;
return view.clientWidth;
return this.view.clientWidth;
}

getClientHeight() {
const { view } = this.refs;
return view.clientHeight;
return this.view.clientHeight;
}

getValues() {
const { view } = this.refs;
const {
scrollLeft,
scrollTop,
scrollWidth,
scrollHeight,
clientWidth,
clientHeight
} = view;
} = this.view;

return {
left: (scrollLeft / (scrollWidth - clientWidth)) || 0,
Expand All @@ -130,9 +142,8 @@ export default class Scrollbars extends Component {

getThumbHorizontalWidth() {
const { thumbSize, thumbMinSize } = this.props;
const { view, trackHorizontal } = this.refs;
const { scrollWidth, clientWidth } = view;
const trackWidth = getInnerWidth(trackHorizontal);
const { scrollWidth, clientWidth } = this.view;
const trackWidth = getInnerWidth(this.trackHorizontal);
const width = Math.ceil(clientWidth / scrollWidth * trackWidth);
if (trackWidth === width) return 0;
if (thumbSize) return thumbSize;
Expand All @@ -141,65 +152,56 @@ export default class Scrollbars extends Component {

getThumbVerticalHeight() {
const { thumbSize, thumbMinSize } = this.props;
const { view, trackVertical } = this.refs;
const { scrollHeight, clientHeight } = view;
const trackHeight = getInnerHeight(trackVertical);
const { scrollHeight, clientHeight } = this.view;
const trackHeight = getInnerHeight(this.trackVertical);
const height = Math.ceil(clientHeight / scrollHeight * trackHeight);
if (trackHeight === height) return 0;
if (thumbSize) return thumbSize;
return Math.max(height, thumbMinSize);
}

getScrollLeftForOffset(offset) {
const { view, trackHorizontal } = this.refs;
const { scrollWidth, clientWidth } = view;
const trackWidth = getInnerWidth(trackHorizontal);
const { scrollWidth, clientWidth } = this.view;
const trackWidth = getInnerWidth(this.trackHorizontal);
const thumbWidth = this.getThumbHorizontalWidth();
return offset / (trackWidth - thumbWidth) * (scrollWidth - clientWidth);
}

getScrollTopForOffset(offset) {
const { view, trackVertical } = this.refs;
const { scrollHeight, clientHeight } = view;
const trackHeight = getInnerHeight(trackVertical);
const { scrollHeight, clientHeight } = this.view;
const trackHeight = getInnerHeight(this.trackVertical);
const thumbHeight = this.getThumbVerticalHeight();
return offset / (trackHeight - thumbHeight) * (scrollHeight - clientHeight);
}

scrollLeft(left = 0) {
const { view } = this.refs;
view.scrollLeft = left;
this.view.scrollLeft = left;
}

scrollTop(top = 0) {
const { view } = this.refs;
view.scrollTop = top;
this.view.scrollTop = top;
}

scrollToLeft() {
const { view } = this.refs;
view.scrollLeft = 0;
this.view.scrollLeft = 0;
}

scrollToTop() {
const { view } = this.refs;
view.scrollTop = 0;
this.view.scrollTop = 0;
}

scrollToRight() {
const { view } = this.refs;
view.scrollLeft = view.scrollWidth;
this.view.scrollLeft = this.view.scrollWidth;
}

scrollToBottom() {
const { view } = this.refs;
view.scrollTop = view.scrollHeight;
this.view.scrollTop = this.view.scrollHeight;
}

addListeners() {
/* istanbul ignore if */
if (typeof document === 'undefined') return;
const { view, trackHorizontal, trackVertical, thumbHorizontal, thumbVertical } = this.refs;
const { view, trackHorizontal, trackVertical, thumbHorizontal, thumbVertical } = this;
view.addEventListener('scroll', this.handleScroll);
if (!getScrollbarWidth()) return;
trackHorizontal.addEventListener('mouseenter', this.handleTrackMouseEnter);
Expand All @@ -216,7 +218,7 @@ export default class Scrollbars extends Component {
removeListeners() {
/* istanbul ignore if */
if (typeof document === 'undefined') return;
const { view, trackHorizontal, trackVertical, thumbHorizontal, thumbVertical } = this.refs;
const { view, trackHorizontal, trackVertical, thumbHorizontal, thumbVertical } = this;
view.removeEventListener('scroll', this.handleScroll);
if (!getScrollbarWidth()) return;
trackHorizontal.removeEventListener('mouseenter', this.handleTrackMouseEnter);
Expand Down Expand Up @@ -274,22 +276,20 @@ export default class Scrollbars extends Component {

handleHorizontalTrackMouseDown(event) {
event.preventDefault();
const { view } = this.refs;
const { target, clientX } = event;
const { left: targetLeft } = target.getBoundingClientRect();
const thumbWidth = this.getThumbHorizontalWidth();
const offset = Math.abs(targetLeft - clientX) - thumbWidth / 2;
view.scrollLeft = this.getScrollLeftForOffset(offset);
this.view.scrollLeft = this.getScrollLeftForOffset(offset);
}

handleVerticalTrackMouseDown(event) {
event.preventDefault();
const { view } = this.refs;
const { target, clientY } = event;
const { top: targetTop } = target.getBoundingClientRect();
const thumbHeight = this.getThumbVerticalHeight();
const offset = Math.abs(targetTop - clientY) - thumbHeight / 2;
view.scrollTop = this.getScrollTopForOffset(offset);
this.view.scrollTop = this.getScrollTopForOffset(offset);
}

handleHorizontalThumbMouseDown(event) {
Expand Down Expand Up @@ -333,21 +333,19 @@ export default class Scrollbars extends Component {
handleDrag(event) {
if (this.prevPageX) {
const { clientX } = event;
const { view, trackHorizontal } = this.refs;
const { left: trackLeft } = trackHorizontal.getBoundingClientRect();
const { left: trackLeft } = this.trackHorizontal.getBoundingClientRect();
const thumbWidth = this.getThumbHorizontalWidth();
const clickPosition = thumbWidth - this.prevPageX;
const offset = -trackLeft + clientX - clickPosition;
view.scrollLeft = this.getScrollLeftForOffset(offset);
this.view.scrollLeft = this.getScrollLeftForOffset(offset);
}
if (this.prevPageY) {
const { clientY } = event;
const { view, trackVertical } = this.refs;
const { top: trackTop } = trackVertical.getBoundingClientRect();
const { top: trackTop } = this.trackVertical.getBoundingClientRect();
const thumbHeight = this.getThumbVerticalHeight();
const clickPosition = thumbHeight - this.prevPageY;
const offset = -trackTop + clientY - clickPosition;
view.scrollTop = this.getScrollTopForOffset(offset);
this.view.scrollTop = this.getScrollTopForOffset(offset);
}
return false;
}
Expand Down Expand Up @@ -388,22 +386,20 @@ export default class Scrollbars extends Component {
}

showTracks() {
const { trackHorizontal, trackVertical } = this.refs;
clearTimeout(this.hideTracksTimeout);
css(trackHorizontal, { opacity: 1 });
css(trackVertical, { opacity: 1 });
css(this.trackHorizontal, { opacity: 1 });
css(this.trackVertical, { opacity: 1 });
}

hideTracks() {
if (this.dragging) return;
if (this.scrolling) return;
if (this.trackMouseOver) return;
const { autoHideTimeout } = this.props;
const { trackHorizontal, trackVertical } = this.refs;
clearTimeout(this.hideTracksTimeout);
this.hideTracksTimeout = setTimeout(() => {
css(trackHorizontal, { opacity: 0 });
css(trackVertical, { opacity: 0 });
css(this.trackHorizontal, { opacity: 0 });
css(this.trackVertical, { opacity: 0 });
}, autoHideTimeout);
}

Expand Down Expand Up @@ -439,17 +435,16 @@ export default class Scrollbars extends Component {
const { onUpdate, hideTracksWhenNotNeeded } = this.props;
const values = this.getValues();
if (getScrollbarWidth()) {
const { thumbHorizontal, thumbVertical, trackHorizontal, trackVertical } = this.refs;
const { scrollLeft, clientWidth, scrollWidth } = values;
const trackHorizontalWidth = getInnerWidth(trackHorizontal);
const trackHorizontalWidth = getInnerWidth(this.trackHorizontal);
const thumbHorizontalWidth = this.getThumbHorizontalWidth();
const thumbHorizontalX = scrollLeft / (scrollWidth - clientWidth) * (trackHorizontalWidth - thumbHorizontalWidth);
const thumbHorizontalStyle = {
width: thumbHorizontalWidth,
transform: `translateX(${thumbHorizontalX}px)`
};
const { scrollTop, clientHeight, scrollHeight } = values;
const trackVerticalHeight = getInnerHeight(trackVertical);
const trackVerticalHeight = getInnerHeight(this.trackVertical);
const thumbVerticalHeight = this.getThumbVerticalHeight();
const thumbVerticalY = scrollTop / (scrollHeight - clientHeight) * (trackVerticalHeight - thumbVerticalHeight);
const thumbVerticalStyle = {
Expand All @@ -463,11 +458,11 @@ export default class Scrollbars extends Component {
const trackVerticalStyle = {
visibility: scrollHeight > clientHeight ? 'visible' : 'hidden'
};
css(trackHorizontal, trackHorizontalStyle);
css(trackVertical, trackVerticalStyle);
css(this.trackHorizontal, trackHorizontalStyle);
css(this.trackVertical, trackVerticalStyle);
}
css(thumbHorizontal, thumbHorizontalStyle);
css(thumbVertical, thumbVerticalStyle);
css(this.thumbHorizontal, thumbHorizontalStyle);
css(this.thumbVertical, thumbVerticalStyle);
}
if (onUpdate) onUpdate(values);
if (typeof callback !== 'function') return;
Expand Down Expand Up @@ -562,26 +557,26 @@ export default class Scrollbars extends Component {
})
};

return createElement(tagName, { ...props, style: containerStyle, ref: 'container' }, [
return createElement(tagName, { ...props, style: containerStyle, ref: (ref) => { this.container = ref; } }, [
cloneElement(
renderView({ style: viewStyle }),
{ key: 'view', ref: 'view' },
{ key: 'view', ref: (ref) => { this.view = ref; } },
children
),
cloneElement(
renderTrackHorizontal({ style: trackHorizontalStyle }),
{ key: 'trackHorizontal', ref: 'trackHorizontal' },
{ key: 'trackHorizontal', ref: (ref) => { this.trackHorizontal = ref; } },
cloneElement(
renderThumbHorizontal({ style: thumbHorizontalStyleDefault }),
{ ref: 'thumbHorizontal' }
{ ref: (ref) => { this.thumbHorizontal = ref; } }
)
),
cloneElement(
renderTrackVertical({ style: trackVerticalStyle }),
{ key: 'trackVertical', ref: 'trackVertical' },
{ key: 'trackVertical', ref: (ref) => { this.trackVertical = ref; } },
cloneElement(
renderThumbVertical({ style: thumbVerticalStyleDefault }),
{ ref: 'thumbVertical' }
{ ref: (ref) => { this.thumbVertical = ref; } }
)
)
]);
Expand Down
Loading

0 comments on commit bc0fe12

Please sign in to comment.