diff --git a/examples/simple/components/ColoredScrollbars/App.js b/examples/simple/components/ColoredScrollbars/App.js index 5c3ea18a..971d95ab 100644 --- a/examples/simple/components/ColoredScrollbars/App.js +++ b/examples/simple/components/ColoredScrollbars/App.js @@ -1,10 +1,7 @@ -import React, { createClass } from 'react'; +import React, { Component } from 'react'; import ColoredScrollbars from './ColoredScrollbars'; -export default createClass({ - - displayName: 'App', - +export default class App extends Component { render() { return ( ); } -}); +} diff --git a/examples/simple/components/ColoredScrollbars/ColoredScrollbars.js b/examples/simple/components/ColoredScrollbars/ColoredScrollbars.js index bcfe5c2b..b9978353 100644 --- a/examples/simple/components/ColoredScrollbars/ColoredScrollbars.js +++ b/examples/simple/components/ColoredScrollbars/ColoredScrollbars.js @@ -1,20 +1,20 @@ -import React, { createClass } from 'react'; +import React, { Component } from 'react'; import { Scrollbars } from 'react-custom-scrollbars'; -export default createClass({ +export default class ColoredScrollbars extends Component { - displayName: 'ColoredScrollbars', - - getInitialState() { - return { - top: 0 - }; - }, + constructor(props, ...rest) { + super(props, ...rest); + this.state = { top: 0 }; + this.handleUpdate = this.handleUpdate.bind(this); + this.renderView = this.renderView.bind(this); + this.renderThumb = this.renderThumb.bind(this); + } handleUpdate(values) { const { top } = values; this.setState({ top }); - }, + } renderView({ style, ...props }) { const { top } = this.state; @@ -29,7 +29,7 @@ export default createClass({ style={{ ...style, ...viewStyle }} {...props}/> ); - }, + } renderThumb({ style, ...props }) { const { top } = this.state; @@ -41,7 +41,7 @@ export default createClass({ style={{ ...style, ...thumbStyle }} {...props}/> ); - }, + } render() { return ( @@ -53,4 +53,4 @@ export default createClass({ {...this.props}/> ); } -}); +} diff --git a/examples/simple/components/DefaultScrollbars/App.js b/examples/simple/components/DefaultScrollbars/App.js index 95a0cb5b..effb20da 100644 --- a/examples/simple/components/DefaultScrollbars/App.js +++ b/examples/simple/components/DefaultScrollbars/App.js @@ -1,10 +1,7 @@ -import React, { createClass } from 'react'; +import React, { Component } from 'react'; import { Scrollbars } from 'react-custom-scrollbars'; -export default createClass({ - - displayName: 'App', - +export default class App extends Component { render() { return ( ); } -}); +} diff --git a/examples/simple/components/ShadowScrollbars/App.js b/examples/simple/components/ShadowScrollbars/App.js index 8ceca5d6..0028def1 100644 --- a/examples/simple/components/ShadowScrollbars/App.js +++ b/examples/simple/components/ShadowScrollbars/App.js @@ -1,10 +1,7 @@ -import React, { createClass } from 'react'; +import React, { Component } from 'react'; import ShadowScrollbars from './ShadowScrollbars'; -export default createClass({ - - displayName: 'App', - +export default class App extends Component { render() { return ( ); } -}); +} diff --git a/examples/simple/components/ShadowScrollbars/ShadowScrollbars.js b/examples/simple/components/ShadowScrollbars/ShadowScrollbars.js index 556f3346..525df9f4 100644 --- a/examples/simple/components/ShadowScrollbars/ShadowScrollbars.js +++ b/examples/simple/components/ShadowScrollbars/ShadowScrollbars.js @@ -1,22 +1,19 @@ import css from 'dom-css'; -import React, { createClass, PropTypes } from 'react'; +import React, { Component } from 'react'; +import PropTypes from 'prop-types'; import { Scrollbars } from 'react-custom-scrollbars'; -export default createClass({ +class ShadowScrollbars extends Component { - displayName: 'ShadowScrollbars', - - propTypes: { - style: PropTypes.object - }, - - getInitialState() { - return { + constructor(props, ...rest) { + super(props, ...rest); + this.state = { scrollTop: 0, scrollHeight: 0, clientHeight: 0 }; - }, + this.handleUpdate = this.handleUpdate.bind(this); + } handleUpdate(values) { const { shadowTop, shadowBottom } = this.refs; @@ -26,7 +23,7 @@ export default createClass({ const shadowBottomOpacity = 1 / 20 * (bottomScrollTop - Math.max(scrollTop, bottomScrollTop - 20)); css(shadowTop, { opacity: shadowTopOpacity }); css(shadowBottom, { opacity: shadowBottomOpacity }); - }, + } render() { const { style, ...props } = this.props; @@ -65,4 +62,10 @@ export default createClass({ ); } -}); +} + +ShadowScrollbars.propTypes = { + style: PropTypes.object +}; + +export default ShadowScrollbars; diff --git a/examples/simple/components/SpringScrollbars/App.js b/examples/simple/components/SpringScrollbars/App.js index 97c8773f..9cde5c7e 100644 --- a/examples/simple/components/SpringScrollbars/App.js +++ b/examples/simple/components/SpringScrollbars/App.js @@ -1,16 +1,19 @@ import random from 'lodash/number/random'; -import React, { createClass } from 'react'; +import React, { Component } from 'react'; import SpringScrollbars from './SpringScrollbars'; -export default createClass({ +export default class App extends Component { - displayName: 'App', + constructor(props, ...rest) { + super(props, ...rest); + this.handleClickRandomPosition = this.handleClickRandomPosition.bind(this); + } handleClickRandomPosition() { const { scrollbars } = this.refs; const scrollHeight = scrollbars.getScrollHeight(); scrollbars.scrollTop(random(scrollHeight)); - }, + } render() { return ( @@ -42,4 +45,4 @@ export default createClass({ ); } -}); +} diff --git a/examples/simple/components/SpringScrollbars/SpringScrollbars.js b/examples/simple/components/SpringScrollbars/SpringScrollbars.js index 9969dae6..0e7e730e 100644 --- a/examples/simple/components/SpringScrollbars/SpringScrollbars.js +++ b/examples/simple/components/SpringScrollbars/SpringScrollbars.js @@ -1,16 +1,19 @@ -import React, { createClass } from 'react'; +import React, { Component } from 'react'; import { Scrollbars } from 'react-custom-scrollbars'; import { SpringSystem, MathUtil } from 'rebound'; -export default createClass({ +export default class SpringScrollbars extends Component { - displayName: 'SpringScrollbars', + constructor(props, ...rest) { + super(props, ...rest); + this.handleSpringUpdate = this.handleSpringUpdate.bind(this); + } componentDidMount() { this.springSystem = new SpringSystem(); this.spring = this.springSystem.createSpring(); this.spring.addListener({ onSpringUpdate: this.handleSpringUpdate }); - }, + } componentWillUnmount() { this.springSystem.deregisterSpring(this.spring); @@ -18,19 +21,19 @@ export default createClass({ this.springSystem = undefined; this.spring.destroy(); this.spring = undefined; - }, + } getScrollTop() { return this.refs.scrollbars.getScrollTop(); - }, + } getScrollHeight() { return this.refs.scrollbars.getScrollHeight(); - }, + } getHeight() { return this.refs.scrollbars.getHeight(); - }, + } scrollTop(top) { const { scrollbars } = this.refs; @@ -39,13 +42,13 @@ export default createClass({ const val = MathUtil.mapValueInRange(top, 0, scrollHeight, scrollHeight * 0.2, scrollHeight * 0.8); this.spring.setCurrentValue(scrollTop).setAtRest(); this.spring.setEndValue(val); - }, + } handleSpringUpdate(spring) { const { scrollbars } = this.refs; const val = spring.getCurrentValue(); scrollbars.scrollTop(val); - }, + } render() { return ( @@ -54,4 +57,4 @@ export default createClass({ ref="scrollbars"/> ); } -}); +} diff --git a/examples/simple/package.json b/examples/simple/package.json index adbf0dac..3075abeb 100644 --- a/examples/simple/package.json +++ b/examples/simple/package.json @@ -44,6 +44,7 @@ }, "dependencies": { "css-loader": "^0.23.1", + "prop-types": "^15.5.8", "rebound": "0.0.13" } } diff --git a/lib/Scrollbars/defaultRenderElements.js b/lib/Scrollbars/defaultRenderElements.js index cbb2516f..d8ba5000 100644 --- a/lib/Scrollbars/defaultRenderElements.js +++ b/lib/Scrollbars/defaultRenderElements.js @@ -25,9 +25,8 @@ function renderViewDefault(props) { } function renderTrackHorizontalDefault(_ref) { - var style = _ref.style; - - var props = _objectWithoutProperties(_ref, ['style']); + var style = _ref.style, + props = _objectWithoutProperties(_ref, ['style']); var finalStyle = _extends({}, style, { right: 2, @@ -40,9 +39,8 @@ function renderTrackHorizontalDefault(_ref) { } function renderTrackVerticalDefault(_ref2) { - var style = _ref2.style; - - var props = _objectWithoutProperties(_ref2, ['style']); + var style = _ref2.style, + props = _objectWithoutProperties(_ref2, ['style']); var finalStyle = _extends({}, style, { right: 2, @@ -55,9 +53,8 @@ function renderTrackVerticalDefault(_ref2) { } function renderThumbHorizontalDefault(_ref3) { - var style = _ref3.style; - - var props = _objectWithoutProperties(_ref3, ['style']); + var style = _ref3.style, + props = _objectWithoutProperties(_ref3, ['style']); var finalStyle = _extends({}, style, { cursor: 'pointer', @@ -68,9 +65,8 @@ function renderThumbHorizontalDefault(_ref3) { } function renderThumbVerticalDefault(_ref4) { - var style = _ref4.style; - - var props = _objectWithoutProperties(_ref4, ['style']); + var style = _ref4.style, + props = _objectWithoutProperties(_ref4, ['style']); var finalStyle = _extends({}, style, { cursor: 'pointer', diff --git a/lib/Scrollbars/index.js b/lib/Scrollbars/index.js index ad54c2be..a2291f69 100644 --- a/lib/Scrollbars/index.js +++ b/lib/Scrollbars/index.js @@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", { var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; +var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + var _raf2 = require('raf'); var _raf3 = _interopRequireDefault(_raf2); @@ -18,6 +20,10 @@ var _react = require('react'); var _react2 = _interopRequireDefault(_react); +var _propTypes = require('prop-types'); + +var _propTypes2 = _interopRequireDefault(_propTypes); + var _isString = require('../utils/isString'); var _isString2 = _interopRequireDefault(_isString); @@ -42,639 +48,776 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "d function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } -exports["default"] = (0, _react.createClass)({ - - displayName: 'Scrollbars', - - propTypes: { - onScroll: _react.PropTypes.func, - onScrollFrame: _react.PropTypes.func, - onScrollStart: _react.PropTypes.func, - onScrollStop: _react.PropTypes.func, - onUpdate: _react.PropTypes.func, - renderView: _react.PropTypes.func, - renderTrackHorizontal: _react.PropTypes.func, - renderTrackVertical: _react.PropTypes.func, - renderThumbHorizontal: _react.PropTypes.func, - renderThumbVertical: _react.PropTypes.func, - thumbSize: _react.PropTypes.number, - thumbMinSize: _react.PropTypes.number, - hideTracksWhenNotNeeded: _react.PropTypes.bool, - autoHide: _react.PropTypes.bool, - autoHideTimeout: _react.PropTypes.number, - autoHideDuration: _react.PropTypes.number, - autoHeight: _react.PropTypes.bool, - autoHeightMin: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]), - autoHeightMax: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]), - autoWidth: _react.PropTypes.bool, - autoWidthMin: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]), - autoWidthMax: _react.PropTypes.oneOfType([_react.PropTypes.number, _react.PropTypes.string]), - universal: _react.PropTypes.bool, - style: _react.PropTypes.object, - children: _react.PropTypes.node - }, - - getDefaultProps: function getDefaultProps() { - return { - renderView: _defaultRenderElements.renderViewDefault, - renderTrackHorizontal: _defaultRenderElements.renderTrackHorizontalDefault, - renderTrackVertical: _defaultRenderElements.renderTrackVerticalDefault, - renderThumbHorizontal: _defaultRenderElements.renderThumbHorizontalDefault, - renderThumbVertical: _defaultRenderElements.renderThumbVerticalDefault, - thumbMinSize: 30, - hideTracksWhenNotNeeded: false, - autoHide: false, - autoHideTimeout: 1000, - autoHideDuration: 200, - autoHeight: false, - autoHeightMin: 0, - autoHeightMax: 200, - autoWidth: false, - autoWidthMin: '100%', - autoWidthMax: '100%', - universal: false - }; - }, - getInitialState: function getInitialState() { - return { - didMountUniversal: false - }; - }, - componentDidMount: function componentDidMount() { - this.addListeners(); - this.update(); - this.componentDidMountUniversal(); - }, - componentDidMountUniversal: function componentDidMountUniversal() { - // eslint-disable-line react/sort-comp - var universal = this.props.universal; - - if (!universal) return; - this.setState({ didMountUniversal: true }); - }, - componentDidUpdate: function componentDidUpdate() { - this.update(); - }, - componentWillUnmount: function componentWillUnmount() { - this.removeListeners(); - (0, _raf2.cancel)(this.requestFrame); - clearTimeout(this.hideTracksTimeout); - clearInterval(this.detectScrollingInterval); - }, - getScrollLeft: function getScrollLeft() { - var view = this.refs.view; - - return view.scrollLeft; - }, - getScrollTop: function getScrollTop() { - var view = this.refs.view; - - return view.scrollTop; - }, - getScrollWidth: function getScrollWidth() { - var view = this.refs.view; - - return view.scrollWidth - this.getPaddingWidth(); - }, - getScrollHeight: function getScrollHeight() { - var view = this.refs.view; - - return view.scrollHeight - this.getPaddingHeight(); - }, - getClientWidth: function getClientWidth() { - var view = this.refs.view; - - return view.clientWidth - this.getPaddingWidth(); - }, - getClientHeight: function getClientHeight() { - var view = this.refs.view; - - return view.clientHeight - this.getPaddingHeight(); - }, - getPaddingWidth: function getPaddingWidth() { - return _styles.scrollbarSize; - }, - getPaddingHeight: function getPaddingHeight() { - return _styles.scrollbarSize; - }, - getValues: function getValues() { - var view = this.refs.view; - var scrollLeft = view.scrollLeft; - var scrollTop = view.scrollTop; - - - var scrollWidth = view.scrollWidth - this.getPaddingWidth(); - var scrollHeight = view.scrollHeight - this.getPaddingHeight(); - var clientWidth = view.clientWidth - this.getPaddingWidth(); - var clientHeight = view.clientHeight - this.getPaddingHeight(); - - return { - left: scrollLeft / (scrollWidth - clientWidth) || 0, - top: scrollTop / (scrollHeight - clientHeight) || 0, - scrollLeft: scrollLeft, - scrollTop: scrollTop, - scrollWidth: scrollWidth, - scrollHeight: scrollHeight, - clientWidth: clientWidth, - clientHeight: clientHeight - }; - }, - getThumbHorizontalWidth: function getThumbHorizontalWidth() { - var _props = this.props; - var thumbSize = _props.thumbSize; - var thumbMinSize = _props.thumbMinSize; - var _refs = this.refs; - var view = _refs.view; - var trackHorizontal = _refs.trackHorizontal; - - var scrollWidth = view.scrollWidth - this.getPaddingWidth(); - var clientWidth = view.clientWidth - this.getPaddingWidth(); - var trackWidth = (0, _getInnerWidth2["default"])(trackHorizontal); - var width = clientWidth / scrollWidth * trackWidth; - if (scrollWidth <= clientWidth) return 0; - if (thumbSize) return thumbSize; - return Math.max(width, thumbMinSize); - }, - getThumbVerticalHeight: function getThumbVerticalHeight() { - var _props2 = this.props; - var thumbSize = _props2.thumbSize; - var thumbMinSize = _props2.thumbMinSize; - var _refs2 = this.refs; - var view = _refs2.view; - var trackVertical = _refs2.trackVertical; - - var scrollHeight = view.scrollHeight - this.getPaddingHeight(); - var clientHeight = view.clientHeight - this.getPaddingHeight(); - var trackHeight = (0, _getInnerHeight2["default"])(trackVertical); - var height = clientHeight / scrollHeight * trackHeight; - if (scrollHeight <= clientHeight) return 0; - if (thumbSize) return thumbSize; - return Math.max(height, thumbMinSize); - }, - getScrollLeftForOffset: function getScrollLeftForOffset(offset) { - var _refs3 = this.refs; - var view = _refs3.view; - var trackHorizontal = _refs3.trackHorizontal; - - var scrollWidth = view.scrollWidth - this.getPaddingWidth(); - var clientWidth = view.clientWidth - this.getPaddingWidth(); - var trackWidth = (0, _getInnerWidth2["default"])(trackHorizontal); - var thumbWidth = this.getThumbHorizontalWidth(); - return offset / (trackWidth - thumbWidth) * (scrollWidth - clientWidth); - }, - getScrollTopForOffset: function getScrollTopForOffset(offset) { - var _refs4 = this.refs; - var view = _refs4.view; - var trackVertical = _refs4.trackVertical; - - var scrollHeight = view.scrollHeight - this.getPaddingHeight(); - var clientHeight = view.clientHeight - this.getPaddingHeight(); - var trackHeight = (0, _getInnerHeight2["default"])(trackVertical); - var thumbHeight = this.getThumbVerticalHeight(); - return offset / (trackHeight - thumbHeight) * (scrollHeight - clientHeight); - }, - scrollLeft: function scrollLeft() { - var left = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0]; - var view = this.refs.view; - - view.scrollLeft = left; - }, - scrollTop: function scrollTop() { - var top = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0]; - var view = this.refs.view; - - view.scrollTop = top; - }, - scrollToLeft: function scrollToLeft() { - var view = this.refs.view; - - view.scrollLeft = 0; - }, - scrollToTop: function scrollToTop() { - var view = this.refs.view; - - view.scrollTop = 0; - }, - scrollToRight: function scrollToRight() { - var view = this.refs.view; - - view.scrollLeft = view.scrollWidth - this.getPaddingWidth(); - }, - scrollToBottom: function scrollToBottom() { - var view = this.refs.view; - - view.scrollTop = view.scrollHeight - this.getPaddingHeight(); - }, - addListeners: function addListeners() { - /* istanbul ignore if */ - if (typeof document === 'undefined') return; - var _refs5 = this.refs; - var view = _refs5.view; - var trackHorizontal = _refs5.trackHorizontal; - var trackVertical = _refs5.trackVertical; - var thumbHorizontal = _refs5.thumbHorizontal; - var thumbVertical = _refs5.thumbVertical; - - view.addEventListener('scroll', this.handleScroll); - trackHorizontal.addEventListener('mouseenter', this.handleTrackMouseEnter); - trackHorizontal.addEventListener('mouseleave', this.handleTrackMouseLeave); - trackHorizontal.addEventListener('mousedown', this.handleHorizontalTrackMouseDown); - trackVertical.addEventListener('mouseenter', this.handleTrackMouseEnter); - trackVertical.addEventListener('mouseleave', this.handleTrackMouseLeave); - trackVertical.addEventListener('mousedown', this.handleVerticalTrackMouseDown); - thumbHorizontal.addEventListener('mousedown', this.handleHorizontalThumbMouseDown); - thumbVertical.addEventListener('mousedown', this.handleVerticalThumbMouseDown); - window.addEventListener('resize', this.handleWindowResize); - }, - removeListeners: function removeListeners() { - /* istanbul ignore if */ - if (typeof document === 'undefined') return; - var _refs6 = this.refs; - var view = _refs6.view; - var trackHorizontal = _refs6.trackHorizontal; - var trackVertical = _refs6.trackVertical; - var thumbHorizontal = _refs6.thumbHorizontal; - var thumbVertical = _refs6.thumbVertical; - - view.removeEventListener('scroll', this.handleScroll); - trackHorizontal.removeEventListener('mouseenter', this.handleTrackMouseEnter); - trackHorizontal.removeEventListener('mouseleave', this.handleTrackMouseLeave); - trackHorizontal.removeEventListener('mousedown', this.handleHorizontalTrackMouseDown); - trackVertical.removeEventListener('mouseenter', this.handleTrackMouseEnter); - trackVertical.removeEventListener('mouseleave', this.handleTrackMouseLeave); - trackVertical.removeEventListener('mousedown', this.handleVerticalTrackMouseDown); - thumbHorizontal.removeEventListener('mousedown', this.handleHorizontalThumbMouseDown); - thumbVertical.removeEventListener('mousedown', this.handleVerticalThumbMouseDown); - window.removeEventListener('resize', this.handleWindowResize); - // Possibly setup by `handleDragStart` - this.teardownDragging(); - }, - handleScroll: function handleScroll(event) { - var _this = this; - - var _props3 = this.props; - var onScroll = _props3.onScroll; - var onScrollFrame = _props3.onScrollFrame; - - if (onScroll) onScroll(event); - this.update(function (values) { - var scrollLeft = values.scrollLeft; - var scrollTop = values.scrollTop; - - _this.viewScrollLeft = scrollLeft; - _this.viewScrollTop = scrollTop; - if (onScrollFrame) onScrollFrame(values); - }); - this.detectScrolling(); - }, - handleScrollStart: function handleScrollStart() { - var onScrollStart = this.props.onScrollStart; - - if (onScrollStart) onScrollStart(); - this.handleScrollStartAutoHide(); - }, - handleScrollStartAutoHide: function handleScrollStartAutoHide() { - var autoHide = this.props.autoHide; - - if (!autoHide) return; - this.showTracks(); - }, - handleScrollStop: function handleScrollStop() { - var onScrollStop = this.props.onScrollStop; - - if (onScrollStop) onScrollStop(); - this.handleScrollStopAutoHide(); - }, - handleScrollStopAutoHide: function handleScrollStopAutoHide() { - var autoHide = this.props.autoHide; - - if (!autoHide) return; - this.hideTracks(); - }, - handleWindowResize: function handleWindowResize() { - this.update(); - }, - handleHorizontalTrackMouseDown: function handleHorizontalTrackMouseDown() { - var view = this.refs.view; - var _event = event; - var target = _event.target; - var clientX = _event.clientX; - - var _target$getBoundingCl = target.getBoundingClientRect(); - - var targetLeft = _target$getBoundingCl.left; - - var thumbWidth = this.getThumbHorizontalWidth(); - var offset = Math.abs(targetLeft - clientX) - thumbWidth / 2; - view.scrollLeft = this.getScrollLeftForOffset(offset); - }, - handleVerticalTrackMouseDown: function handleVerticalTrackMouseDown(event) { - var view = this.refs.view; - var target = event.target; - var clientY = event.clientY; - - var _target$getBoundingCl2 = target.getBoundingClientRect(); - - var targetTop = _target$getBoundingCl2.top; - - var thumbHeight = this.getThumbVerticalHeight(); - var offset = Math.abs(targetTop - clientY) - thumbHeight / 2; - view.scrollTop = this.getScrollTopForOffset(offset); - }, - handleHorizontalThumbMouseDown: function handleHorizontalThumbMouseDown(event) { - this.handleDragStart(event); - var target = event.target; - var clientX = event.clientX; - var offsetWidth = target.offsetWidth; - - var _target$getBoundingCl3 = target.getBoundingClientRect(); - - var left = _target$getBoundingCl3.left; - - this.prevPageX = offsetWidth - (clientX - left); - }, - handleVerticalThumbMouseDown: function handleVerticalThumbMouseDown(event) { - this.handleDragStart(event); - var target = event.target; - var clientY = event.clientY; - var offsetHeight = target.offsetHeight; - - var _target$getBoundingCl4 = target.getBoundingClientRect(); - - var top = _target$getBoundingCl4.top; - - this.prevPageY = offsetHeight - (clientY - top); - }, - setupDragging: function setupDragging() { - (0, _domCss2["default"])(document.body, _styles.disableSelectStyle); - document.addEventListener('mousemove', this.handleDrag); - document.addEventListener('mouseup', this.handleDragEnd); - document.onselectstart = _returnFalse2["default"]; - }, - teardownDragging: function teardownDragging() { - (0, _domCss2["default"])(document.body, _styles.disableSelectStyleReset); - document.removeEventListener('mousemove', this.handleDrag); - document.removeEventListener('mouseup', this.handleDragEnd); - document.onselectstart = undefined; - }, - handleDragStart: function handleDragStart(event) { - this.dragging = true; - event.stopImmediatePropagation(); - this.setupDragging(); - }, - handleDrag: function handleDrag(event) { - if (this.prevPageX) { - var clientX = event.clientX; - var _refs7 = this.refs; - var view = _refs7.view; - var trackHorizontal = _refs7.trackHorizontal; - - var _trackHorizontal$getB = trackHorizontal.getBoundingClientRect(); - - var trackLeft = _trackHorizontal$getB.left; +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + +var Scrollbars = function (_React$Component) { + _inherits(Scrollbars, _React$Component); + + function Scrollbars(props) { + var _ref; + + _classCallCheck(this, Scrollbars); + + for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + rest[_key - 1] = arguments[_key]; + } + + var _this = _possibleConstructorReturn(this, (_ref = Scrollbars.__proto__ || Object.getPrototypeOf(Scrollbars)).call.apply(_ref, [this, props].concat(rest))); + + _this.handleTrackMouseEnter = _this.handleTrackMouseEnter.bind(_this); + _this.handleTrackMouseLeave = _this.handleTrackMouseLeave.bind(_this); + _this.handleHorizontalTrackMouseDown = _this.handleHorizontalTrackMouseDown.bind(_this); + _this.handleVerticalTrackMouseDown = _this.handleVerticalTrackMouseDown.bind(_this); + _this.handleHorizontalThumbMouseDown = _this.handleHorizontalThumbMouseDown.bind(_this); + _this.handleVerticalThumbMouseDown = _this.handleVerticalThumbMouseDown.bind(_this); + _this.handleWindowResize = _this.handleWindowResize.bind(_this); + _this.handleScroll = _this.handleScroll.bind(_this); + _this.handleDrag = _this.handleDrag.bind(_this); + _this.handleDragEnd = _this.handleDragEnd.bind(_this); + + _this.state = _this.getInitialState(); + return _this; + } + + _createClass(Scrollbars, [{ + key: 'getInitialState', + value: function getInitialState() { + return { + didMountUniversal: false + }; + } + }, { + key: 'componentDidMount', + value: function componentDidMount() { + this.addListeners(); + this.update(); + this.componentDidMountUniversal(); + } + }, { + key: 'componentDidMountUniversal', + value: function componentDidMountUniversal() { + // eslint-disable-line react/sort-comp + var universal = this.props.universal; + + if (!universal) return; + this.setState({ didMountUniversal: true }); + } + }, { + key: 'componentDidUpdate', + value: function componentDidUpdate() { + this.update(); + } + }, { + key: 'componentWillUnmount', + value: function componentWillUnmount() { + this.removeListeners(); + (0, _raf2.cancel)(this.requestFrame); + clearTimeout(this.hideTracksTimeout); + clearInterval(this.detectScrollingInterval); + } + }, { + key: 'getScrollLeft', + value: function getScrollLeft() { + var view = this.refs.view; + + return view.scrollLeft; + } + }, { + key: 'getScrollTop', + value: function getScrollTop() { + var view = this.refs.view; + + return view.scrollTop; + } + }, { + key: 'getScrollWidth', + value: function getScrollWidth() { + var view = this.refs.view; + + return view.scrollWidth - this.getPaddingWidth(); + } + }, { + key: 'getScrollHeight', + value: function getScrollHeight() { + var view = this.refs.view; + return view.scrollHeight - this.getPaddingHeight(); + } + }, { + key: 'getClientWidth', + value: function getClientWidth() { + var view = this.refs.view; + + return view.clientWidth - this.getPaddingWidth(); + } + }, { + key: 'getClientHeight', + value: function getClientHeight() { + var view = this.refs.view; + + return view.clientHeight - this.getPaddingHeight(); + } + }, { + key: 'getPaddingWidth', + value: function getPaddingWidth() { + return _styles.scrollbarSize; + } + }, { + key: 'getPaddingHeight', + value: function getPaddingHeight() { + return _styles.scrollbarSize; + } + }, { + key: 'getValues', + value: function getValues() { + var view = this.refs.view; + var scrollLeft = view.scrollLeft, + scrollTop = view.scrollTop; + + + var scrollWidth = view.scrollWidth - this.getPaddingWidth(); + var scrollHeight = view.scrollHeight - this.getPaddingHeight(); + var clientWidth = view.clientWidth - this.getPaddingWidth(); + var clientHeight = view.clientHeight - this.getPaddingHeight(); + + return { + left: scrollLeft / (scrollWidth - clientWidth) || 0, + top: scrollTop / (scrollHeight - clientHeight) || 0, + scrollLeft: scrollLeft, + scrollTop: scrollTop, + scrollWidth: scrollWidth, + scrollHeight: scrollHeight, + clientWidth: clientWidth, + clientHeight: clientHeight + }; + } + }, { + key: 'getThumbHorizontalWidth', + value: function getThumbHorizontalWidth() { + var _props = this.props, + thumbSize = _props.thumbSize, + thumbMinSize = _props.thumbMinSize; + var _refs = this.refs, + view = _refs.view, + trackHorizontal = _refs.trackHorizontal; + + var scrollWidth = view.scrollWidth - this.getPaddingWidth(); + var clientWidth = view.clientWidth - this.getPaddingWidth(); + var trackWidth = (0, _getInnerWidth2["default"])(trackHorizontal); + var width = clientWidth / scrollWidth * trackWidth; + if (scrollWidth <= clientWidth) return 0; + if (thumbSize) return thumbSize; + return Math.max(width, thumbMinSize); + } + }, { + key: 'getThumbVerticalHeight', + value: function getThumbVerticalHeight() { + var _props2 = this.props, + thumbSize = _props2.thumbSize, + thumbMinSize = _props2.thumbMinSize; + var _refs2 = this.refs, + view = _refs2.view, + trackVertical = _refs2.trackVertical; + + var scrollHeight = view.scrollHeight - this.getPaddingHeight(); + var clientHeight = view.clientHeight - this.getPaddingHeight(); + var trackHeight = (0, _getInnerHeight2["default"])(trackVertical); + var height = clientHeight / scrollHeight * trackHeight; + if (scrollHeight <= clientHeight) return 0; + if (thumbSize) return thumbSize; + return Math.max(height, thumbMinSize); + } + }, { + key: 'getScrollLeftForOffset', + value: function getScrollLeftForOffset(offset) { + var _refs3 = this.refs, + view = _refs3.view, + trackHorizontal = _refs3.trackHorizontal; + + var scrollWidth = view.scrollWidth - this.getPaddingWidth(); + var clientWidth = view.clientWidth - this.getPaddingWidth(); + var trackWidth = (0, _getInnerWidth2["default"])(trackHorizontal); var thumbWidth = this.getThumbHorizontalWidth(); - var clickPosition = thumbWidth - this.prevPageX; - var offset = -trackLeft + clientX - clickPosition; - view.scrollLeft = this.getScrollLeftForOffset(offset); + return offset / (trackWidth - thumbWidth) * (scrollWidth - clientWidth); } - if (this.prevPageY) { - var clientY = event.clientY; - var _refs8 = this.refs; - var _view = _refs8.view; - var trackVertical = _refs8.trackVertical; + }, { + key: 'getScrollTopForOffset', + value: function getScrollTopForOffset(offset) { + var _refs4 = this.refs, + view = _refs4.view, + trackVertical = _refs4.trackVertical; + + var scrollHeight = view.scrollHeight - this.getPaddingHeight(); + var clientHeight = view.clientHeight - this.getPaddingHeight(); + var trackHeight = (0, _getInnerHeight2["default"])(trackVertical); + var thumbHeight = this.getThumbVerticalHeight(); + return offset / (trackHeight - thumbHeight) * (scrollHeight - clientHeight); + } + }, { + key: 'scrollLeft', + value: function scrollLeft() { + var left = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var view = this.refs.view; + + view.scrollLeft = left; + } + }, { + key: 'scrollTop', + value: function scrollTop() { + var top = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; + var view = this.refs.view; + + view.scrollTop = top; + } + }, { + key: 'scrollToLeft', + value: function scrollToLeft() { + var view = this.refs.view; - var _trackVertical$getBou = trackVertical.getBoundingClientRect(); + view.scrollLeft = 0; + } + }, { + key: 'scrollToTop', + value: function scrollToTop() { + var view = this.refs.view; + + view.scrollTop = 0; + } + }, { + key: 'scrollToRight', + value: function scrollToRight() { + var view = this.refs.view; - var trackTop = _trackVertical$getBou.top; + view.scrollLeft = view.scrollWidth - this.getPaddingWidth(); + } + }, { + key: 'scrollToBottom', + value: function scrollToBottom() { + var view = this.refs.view; + + view.scrollTop = view.scrollHeight - this.getPaddingHeight(); + } + }, { + key: 'addListeners', + value: function addListeners() { + /* istanbul ignore if */ + if (typeof document === 'undefined') return; + var _refs5 = this.refs, + view = _refs5.view, + trackHorizontal = _refs5.trackHorizontal, + trackVertical = _refs5.trackVertical, + thumbHorizontal = _refs5.thumbHorizontal, + thumbVertical = _refs5.thumbVertical; + + view.addEventListener('scroll', this.handleScroll); + trackHorizontal.addEventListener('mouseenter', this.handleTrackMouseEnter); + trackHorizontal.addEventListener('mouseleave', this.handleTrackMouseLeave); + trackHorizontal.addEventListener('mousedown', this.handleHorizontalTrackMouseDown); + trackVertical.addEventListener('mouseenter', this.handleTrackMouseEnter); + trackVertical.addEventListener('mouseleave', this.handleTrackMouseLeave); + trackVertical.addEventListener('mousedown', this.handleVerticalTrackMouseDown); + thumbHorizontal.addEventListener('mousedown', this.handleHorizontalThumbMouseDown); + thumbVertical.addEventListener('mousedown', this.handleVerticalThumbMouseDown); + window.addEventListener('resize', this.handleWindowResize); + } + }, { + key: 'removeListeners', + value: function removeListeners() { + /* istanbul ignore if */ + if (typeof document === 'undefined') return; + var _refs6 = this.refs, + view = _refs6.view, + trackHorizontal = _refs6.trackHorizontal, + trackVertical = _refs6.trackVertical, + thumbHorizontal = _refs6.thumbHorizontal, + thumbVertical = _refs6.thumbVertical; + + view.removeEventListener('scroll', this.handleScroll); + trackHorizontal.removeEventListener('mouseenter', this.handleTrackMouseEnter); + trackHorizontal.removeEventListener('mouseleave', this.handleTrackMouseLeave); + trackHorizontal.removeEventListener('mousedown', this.handleHorizontalTrackMouseDown); + trackVertical.removeEventListener('mouseenter', this.handleTrackMouseEnter); + trackVertical.removeEventListener('mouseleave', this.handleTrackMouseLeave); + trackVertical.removeEventListener('mousedown', this.handleVerticalTrackMouseDown); + thumbHorizontal.removeEventListener('mousedown', this.handleHorizontalThumbMouseDown); + thumbVertical.removeEventListener('mousedown', this.handleVerticalThumbMouseDown); + window.removeEventListener('resize', this.handleWindowResize); + // Possibly setup by `handleDragStart` + this.teardownDragging(); + } + }, { + key: 'handleScroll', + value: function handleScroll(event) { + var _this2 = this; + + var _props3 = this.props, + onScroll = _props3.onScroll, + onScrollFrame = _props3.onScrollFrame; + + if (onScroll) onScroll(event); + this.update(function (values) { + var scrollLeft = values.scrollLeft, + scrollTop = values.scrollTop; + + _this2.viewScrollLeft = scrollLeft; + _this2.viewScrollTop = scrollTop; + if (onScrollFrame) onScrollFrame(values); + }); + this.detectScrolling(); + } + }, { + key: 'handleScrollStart', + value: function handleScrollStart() { + var onScrollStart = this.props.onScrollStart; + + if (onScrollStart) onScrollStart(); + this.handleScrollStartAutoHide(); + } + }, { + key: 'handleScrollStartAutoHide', + value: function handleScrollStartAutoHide() { + var autoHide = this.props.autoHide; + + if (!autoHide) return; + this.showTracks(); + } + }, { + key: 'handleScrollStop', + value: function handleScrollStop() { + var onScrollStop = this.props.onScrollStop; + + if (onScrollStop) onScrollStop(); + this.handleScrollStopAutoHide(); + } + }, { + key: 'handleScrollStopAutoHide', + value: function handleScrollStopAutoHide() { + var autoHide = this.props.autoHide; + + if (!autoHide) return; + this.hideTracks(); + } + }, { + key: 'handleWindowResize', + value: function handleWindowResize() { + this.update(); + } + }, { + key: 'handleHorizontalTrackMouseDown', + value: function handleHorizontalTrackMouseDown() { + var view = this.refs.view; + var _event = event, + target = _event.target, + clientX = _event.clientX; + + var _target$getBoundingCl = target.getBoundingClientRect(), + targetLeft = _target$getBoundingCl.left; + + var thumbWidth = this.getThumbHorizontalWidth(); + var offset = Math.abs(targetLeft - clientX) - thumbWidth / 2; + view.scrollLeft = this.getScrollLeftForOffset(offset); + } + }, { + key: 'handleVerticalTrackMouseDown', + value: function handleVerticalTrackMouseDown(event) { + var view = this.refs.view; + var target = event.target, + clientY = event.clientY; + + var _target$getBoundingCl2 = target.getBoundingClientRect(), + targetTop = _target$getBoundingCl2.top; var thumbHeight = this.getThumbVerticalHeight(); - var _clickPosition = thumbHeight - this.prevPageY; - var _offset = -trackTop + clientY - _clickPosition; - _view.scrollTop = this.getScrollTopForOffset(_offset); - } - return false; - }, - handleDragEnd: function handleDragEnd() { - this.dragging = false; - this.prevPageX = this.prevPageY = 0; - this.teardownDragging(); - this.handleDragEndAutoHide(); - }, - handleDragEndAutoHide: function handleDragEndAutoHide() { - var autoHide = this.props.autoHide; - - if (!autoHide) return; - this.hideTracks(); - }, - handleTrackMouseEnter: function handleTrackMouseEnter() { - this.trackMouseOver = true; - this.handleTrackMouseEnterAutoHide(); - }, - handleTrackMouseEnterAutoHide: function handleTrackMouseEnterAutoHide() { - var autoHide = this.props.autoHide; - - if (!autoHide) return; - this.showTracks(); - }, - handleTrackMouseLeave: function handleTrackMouseLeave() { - this.trackMouseOver = false; - this.handleTrackMouseLeaveAutoHide(); - }, - handleTrackMouseLeaveAutoHide: function handleTrackMouseLeaveAutoHide() { - var autoHide = this.props.autoHide; - - if (!autoHide) return; - this.hideTracks(); - }, - showTracks: function showTracks() { - var _refs9 = this.refs; - var trackHorizontal = _refs9.trackHorizontal; - var trackVertical = _refs9.trackVertical; - - clearTimeout(this.hideTracksTimeout); - (0, _domCss2["default"])(trackHorizontal, { opacity: 1 }); - (0, _domCss2["default"])(trackVertical, { opacity: 1 }); - }, - hideTracks: function hideTracks() { - if (this.dragging) return; - if (this.scrolling) return; - if (this.trackMouseOver) return; - var autoHideTimeout = this.props.autoHideTimeout; - var _refs10 = this.refs; - var trackHorizontal = _refs10.trackHorizontal; - var trackVertical = _refs10.trackVertical; - - clearTimeout(this.hideTracksTimeout); - this.hideTracksTimeout = setTimeout(function () { - (0, _domCss2["default"])(trackHorizontal, { opacity: 0 }); - (0, _domCss2["default"])(trackVertical, { opacity: 0 }); - }, autoHideTimeout); - }, - detectScrolling: function detectScrolling() { - var _this2 = this; - - if (this.scrolling) return; - this.scrolling = true; - this.handleScrollStart(); - this.detectScrollingInterval = setInterval(function () { - if (_this2.lastViewScrollLeft === _this2.viewScrollLeft && _this2.lastViewScrollTop === _this2.viewScrollTop) { - clearInterval(_this2.detectScrollingInterval); - _this2.scrolling = false; - _this2.handleScrollStop(); + var offset = Math.abs(targetTop - clientY) - thumbHeight / 2; + view.scrollTop = this.getScrollTopForOffset(offset); + } + }, { + key: 'handleHorizontalThumbMouseDown', + value: function handleHorizontalThumbMouseDown(event) { + this.handleDragStart(event); + var target = event.target, + clientX = event.clientX; + var offsetWidth = target.offsetWidth; + + var _target$getBoundingCl3 = target.getBoundingClientRect(), + left = _target$getBoundingCl3.left; + + this.prevPageX = offsetWidth - (clientX - left); + } + }, { + key: 'handleVerticalThumbMouseDown', + value: function handleVerticalThumbMouseDown(event) { + this.handleDragStart(event); + var target = event.target, + clientY = event.clientY; + var offsetHeight = target.offsetHeight; + + var _target$getBoundingCl4 = target.getBoundingClientRect(), + top = _target$getBoundingCl4.top; + + this.prevPageY = offsetHeight - (clientY - top); + } + }, { + key: 'setupDragging', + value: function setupDragging() { + (0, _domCss2["default"])(document.body, _styles.disableSelectStyle); + document.addEventListener('mousemove', this.handleDrag); + document.addEventListener('mouseup', this.handleDragEnd); + document.onselectstart = _returnFalse2["default"]; + } + }, { + key: 'teardownDragging', + value: function teardownDragging() { + (0, _domCss2["default"])(document.body, _styles.disableSelectStyleReset); + document.removeEventListener('mousemove', this.handleDrag); + document.removeEventListener('mouseup', this.handleDragEnd); + document.onselectstart = undefined; + } + }, { + key: 'handleDragStart', + value: function handleDragStart(event) { + this.dragging = true; + event.stopImmediatePropagation(); + this.setupDragging(); + } + }, { + key: 'handleDrag', + value: function handleDrag(event) { + if (this.prevPageX) { + var clientX = event.clientX; + var _refs7 = this.refs, + view = _refs7.view, + trackHorizontal = _refs7.trackHorizontal; + + var _trackHorizontal$getB = trackHorizontal.getBoundingClientRect(), + trackLeft = _trackHorizontal$getB.left; + + var thumbWidth = this.getThumbHorizontalWidth(); + var clickPosition = thumbWidth - this.prevPageX; + var offset = -trackLeft + clientX - clickPosition; + view.scrollLeft = this.getScrollLeftForOffset(offset); } - _this2.lastViewScrollLeft = _this2.viewScrollLeft; - _this2.lastViewScrollTop = _this2.viewScrollTop; - }, 100); - }, - raf: function raf(callback) { - var _this3 = this; - - if (this.requestFrame) _raf3["default"].cancel(this.requestFrame); - this.requestFrame = (0, _raf3["default"])(function () { - _this3.requestFrame = undefined; - callback(); - }); - }, - update: function update(callback) { - var _this4 = this; - - this.raf(function () { - return _this4._update(callback); - }); - }, - _update: function _update(callback) { - var _props4 = this.props; - var onUpdate = _props4.onUpdate; - var hideTracksWhenNotNeeded = _props4.hideTracksWhenNotNeeded; - var _refs11 = this.refs; - var thumbHorizontal = _refs11.thumbHorizontal; - var thumbVertical = _refs11.thumbVertical; - var trackHorizontal = _refs11.trackHorizontal; - var trackVertical = _refs11.trackVertical; - var container = _refs11.container; - - container.scrollTop = 0; - container.scrollLeft = 0; - var values = this.getValues(); - var scrollLeft = values.scrollLeft; - var clientWidth = values.clientWidth; - var scrollWidth = values.scrollWidth; - - var trackHorizontalWidth = (0, _getInnerWidth2["default"])(trackHorizontal); - var thumbHorizontalWidth = this.getThumbHorizontalWidth(); - var thumbHorizontalX = scrollLeft / (scrollWidth - clientWidth) * (trackHorizontalWidth - thumbHorizontalWidth); - var thumbHorizontalStyle = { - width: thumbHorizontalWidth, - transform: 'translateX(' + thumbHorizontalX + 'px)' - }; - var scrollTop = values.scrollTop; - var clientHeight = values.clientHeight; - var scrollHeight = values.scrollHeight; - - var trackVerticalHeight = (0, _getInnerHeight2["default"])(trackVertical); - var thumbVerticalHeight = this.getThumbVerticalHeight(); - var thumbVerticalY = scrollTop / (scrollHeight - clientHeight) * (trackVerticalHeight - thumbVerticalHeight); - var thumbVerticalStyle = { - height: thumbVerticalHeight, - transform: 'translateY(' + thumbVerticalY + 'px)' - }; - if (hideTracksWhenNotNeeded) { - var trackHorizontalStyle = { - visibility: scrollWidth > clientWidth ? 'visible' : 'hidden' + if (this.prevPageY) { + var clientY = event.clientY; + var _refs8 = this.refs, + _view = _refs8.view, + trackVertical = _refs8.trackVertical; + + var _trackVertical$getBou = trackVertical.getBoundingClientRect(), + trackTop = _trackVertical$getBou.top; + + var thumbHeight = this.getThumbVerticalHeight(); + var _clickPosition = thumbHeight - this.prevPageY; + var _offset = -trackTop + clientY - _clickPosition; + _view.scrollTop = this.getScrollTopForOffset(_offset); + } + return false; + } + }, { + key: 'handleDragEnd', + value: function handleDragEnd() { + this.dragging = false; + this.prevPageX = this.prevPageY = 0; + this.teardownDragging(); + this.handleDragEndAutoHide(); + } + }, { + key: 'handleDragEndAutoHide', + value: function handleDragEndAutoHide() { + var autoHide = this.props.autoHide; + + if (!autoHide) return; + this.hideTracks(); + } + }, { + key: 'handleTrackMouseEnter', + value: function handleTrackMouseEnter() { + this.trackMouseOver = true; + this.handleTrackMouseEnterAutoHide(); + } + }, { + key: 'handleTrackMouseEnterAutoHide', + value: function handleTrackMouseEnterAutoHide() { + var autoHide = this.props.autoHide; + + if (!autoHide) return; + this.showTracks(); + } + }, { + key: 'handleTrackMouseLeave', + value: function handleTrackMouseLeave() { + this.trackMouseOver = false; + this.handleTrackMouseLeaveAutoHide(); + } + }, { + key: 'handleTrackMouseLeaveAutoHide', + value: function handleTrackMouseLeaveAutoHide() { + var autoHide = this.props.autoHide; + + if (!autoHide) return; + this.hideTracks(); + } + }, { + key: 'showTracks', + value: function showTracks() { + var _refs9 = this.refs, + trackHorizontal = _refs9.trackHorizontal, + trackVertical = _refs9.trackVertical; + + clearTimeout(this.hideTracksTimeout); + (0, _domCss2["default"])(trackHorizontal, { opacity: 1 }); + (0, _domCss2["default"])(trackVertical, { opacity: 1 }); + } + }, { + key: 'hideTracks', + value: function hideTracks() { + if (this.dragging) return; + if (this.scrolling) return; + if (this.trackMouseOver) return; + var autoHideTimeout = this.props.autoHideTimeout; + var _refs10 = this.refs, + trackHorizontal = _refs10.trackHorizontal, + trackVertical = _refs10.trackVertical; + + clearTimeout(this.hideTracksTimeout); + this.hideTracksTimeout = setTimeout(function () { + (0, _domCss2["default"])(trackHorizontal, { opacity: 0 }); + (0, _domCss2["default"])(trackVertical, { opacity: 0 }); + }, autoHideTimeout); + } + }, { + key: 'detectScrolling', + value: function detectScrolling() { + var _this3 = this; + + if (this.scrolling) return; + this.scrolling = true; + this.handleScrollStart(); + this.detectScrollingInterval = setInterval(function () { + if (_this3.lastViewScrollLeft === _this3.viewScrollLeft && _this3.lastViewScrollTop === _this3.viewScrollTop) { + clearInterval(_this3.detectScrollingInterval); + _this3.scrolling = false; + _this3.handleScrollStop(); + } + _this3.lastViewScrollLeft = _this3.viewScrollLeft; + _this3.lastViewScrollTop = _this3.viewScrollTop; + }, 100); + } + }, { + key: 'raf', + value: function raf(callback) { + var _this4 = this; + + if (this.requestFrame) _raf3["default"].cancel(this.requestFrame); + this.requestFrame = (0, _raf3["default"])(function () { + _this4.requestFrame = undefined; + callback(); + }); + } + }, { + key: 'update', + value: function update(callback) { + var _this5 = this; + + this.raf(function () { + return _this5._update(callback); + }); + } + }, { + key: '_update', + value: function _update(callback) { + var _props4 = this.props, + onUpdate = _props4.onUpdate, + hideTracksWhenNotNeeded = _props4.hideTracksWhenNotNeeded; + var _refs11 = this.refs, + thumbHorizontal = _refs11.thumbHorizontal, + thumbVertical = _refs11.thumbVertical, + trackHorizontal = _refs11.trackHorizontal, + trackVertical = _refs11.trackVertical, + container = _refs11.container; + + container.scrollTop = 0; + container.scrollLeft = 0; + var values = this.getValues(); + var scrollLeft = values.scrollLeft, + clientWidth = values.clientWidth, + scrollWidth = values.scrollWidth; + + var trackHorizontalWidth = (0, _getInnerWidth2["default"])(trackHorizontal); + var thumbHorizontalWidth = this.getThumbHorizontalWidth(); + var thumbHorizontalX = scrollLeft / (scrollWidth - clientWidth) * (trackHorizontalWidth - thumbHorizontalWidth); + var thumbHorizontalStyle = { + width: thumbHorizontalWidth, + transform: 'translateX(' + thumbHorizontalX + 'px)' + }; + var scrollTop = values.scrollTop, + clientHeight = values.clientHeight, + scrollHeight = values.scrollHeight; + + var trackVerticalHeight = (0, _getInnerHeight2["default"])(trackVertical); + var thumbVerticalHeight = this.getThumbVerticalHeight(); + var thumbVerticalY = scrollTop / (scrollHeight - clientHeight) * (trackVerticalHeight - thumbVerticalHeight); + var thumbVerticalStyle = { + height: thumbVerticalHeight, + transform: 'translateY(' + thumbVerticalY + 'px)' }; - var trackVerticalStyle = { - visibility: scrollHeight > clientHeight ? 'visible' : 'hidden' + if (hideTracksWhenNotNeeded) { + var trackHorizontalStyle = { + visibility: scrollWidth > clientWidth ? 'visible' : 'hidden' + }; + var trackVerticalStyle = { + visibility: scrollHeight > clientHeight ? 'visible' : 'hidden' + }; + (0, _domCss2["default"])(trackHorizontal, trackHorizontalStyle); + (0, _domCss2["default"])(trackVertical, trackVerticalStyle); + } + (0, _domCss2["default"])(thumbHorizontal, thumbHorizontalStyle); + (0, _domCss2["default"])(thumbVertical, thumbVerticalStyle); + if (onUpdate) onUpdate(values); + if (typeof callback !== 'function') return; + callback(values); + } + }, { + key: 'render', + value: function render() { + var _props5 = this.props, + onScroll = _props5.onScroll, + onScrollFrame = _props5.onScrollFrame, + onScrollStart = _props5.onScrollStart, + onScrollStop = _props5.onScrollStop, + renderView = _props5.renderView, + renderTrackHorizontal = _props5.renderTrackHorizontal, + renderTrackVertical = _props5.renderTrackVertical, + renderThumbHorizontal = _props5.renderThumbHorizontal, + renderThumbVertical = _props5.renderThumbVertical, + autoHide = _props5.autoHide, + autoHideTimeout = _props5.autoHideTimeout, + autoHideDuration = _props5.autoHideDuration, + thumbSize = _props5.thumbSize, + thumbMinSize = _props5.thumbMinSize, + universal = _props5.universal, + autoHeight = _props5.autoHeight, + autoHeightMin = _props5.autoHeightMin, + autoHeightMax = _props5.autoHeightMax, + autoWidth = _props5.autoWidth, + autoWidthMin = _props5.autoWidthMin, + autoWidthMax = _props5.autoWidthMax, + style = _props5.style, + children = _props5.children, + props = _objectWithoutProperties(_props5, ['onScroll', 'onScrollFrame', 'onScrollStart', 'onScrollStop', 'renderView', 'renderTrackHorizontal', 'renderTrackVertical', 'renderThumbHorizontal', 'renderThumbVertical', 'autoHide', 'autoHideTimeout', 'autoHideDuration', 'thumbSize', 'thumbMinSize', 'universal', 'autoHeight', 'autoHeightMin', 'autoHeightMax', 'autoWidth', 'autoWidthMin', 'autoWidthMax', 'style', 'children']); + + var didMountUniversal = this.state.didMountUniversal; + + + var containerStyle = _extends({}, _styles.containerStyleDefault, autoHeight && _extends({}, _styles.containerStyleAutoHeight, { + minHeight: autoHeightMin, + maxHeight: autoHeightMax + }), style); + + var viewStyle = _extends({}, _styles.viewStyleDefault, { + // Hide scrollbars by setting a negative margin + marginRight: -this.getPaddingWidth(), + marginBottom: -this.getPaddingHeight() + }, autoHeight && _extends({}, _styles.viewStyleAutoHeight, { + // Add paddingHeight to autoHeight in order to compensate negative margins + minHeight: (0, _isString2["default"])(autoHeightMin) ? 'calc(' + autoHeightMin + ' + ' + this.getPaddingHeight() + 'px)' : autoHeightMin + this.getPaddingHeight(), + maxHeight: (0, _isString2["default"])(autoHeightMax) ? 'calc(' + autoHeightMax + ' + ' + this.getPaddingHeight() + 'px)' : autoHeightMax + this.getPaddingHeight() + }), universal && !didMountUniversal && _styles.viewStyleUniversalInitial); + + var viewWrapperStyle = _extends({}, _styles.viewWrapperStyleDefault, autoWidth && _extends({}, _styles.viewWrapperStyleAutoHeight, { + minWidth: autoWidthMin, + maxWidth: autoWidthMax + })); + + var viewWrappedStyle = _extends({}, _styles.viewWrappedStyleDefault); + + var trackAutoHeightStyle = { + transition: 'opacity ' + autoHideDuration + 'ms', + opacity: 0 }; - (0, _domCss2["default"])(trackHorizontal, trackHorizontalStyle); - (0, _domCss2["default"])(trackVertical, trackVerticalStyle); - } - (0, _domCss2["default"])(thumbHorizontal, thumbHorizontalStyle); - (0, _domCss2["default"])(thumbVertical, thumbVerticalStyle); - if (onUpdate) onUpdate(values); - if (typeof callback !== 'function') return; - callback(values); - }, - render: function render() { - var _props5 = this.props; - var onScroll = _props5.onScroll; - var onScrollFrame = _props5.onScrollFrame; - var onScrollStart = _props5.onScrollStart; - var onScrollStop = _props5.onScrollStop; - var renderView = _props5.renderView; - var renderTrackHorizontal = _props5.renderTrackHorizontal; - var renderTrackVertical = _props5.renderTrackVertical; - var renderThumbHorizontal = _props5.renderThumbHorizontal; - var renderThumbVertical = _props5.renderThumbVertical; - var autoHide = _props5.autoHide; - var autoHideTimeout = _props5.autoHideTimeout; - var autoHideDuration = _props5.autoHideDuration; - var thumbSize = _props5.thumbSize; - var thumbMinSize = _props5.thumbMinSize; - var universal = _props5.universal; - var autoHeight = _props5.autoHeight; - var autoHeightMin = _props5.autoHeightMin; - var autoHeightMax = _props5.autoHeightMax; - var autoWidth = _props5.autoWidth; - var autoWidthMin = _props5.autoWidthMin; - var autoWidthMax = _props5.autoWidthMax; - var style = _props5.style; - var children = _props5.children; - - var props = _objectWithoutProperties(_props5, ['onScroll', 'onScrollFrame', 'onScrollStart', 'onScrollStop', 'renderView', 'renderTrackHorizontal', 'renderTrackVertical', 'renderThumbHorizontal', 'renderThumbVertical', 'autoHide', 'autoHideTimeout', 'autoHideDuration', 'thumbSize', 'thumbMinSize', 'universal', 'autoHeight', 'autoHeightMin', 'autoHeightMax', 'autoWidth', 'autoWidthMin', 'autoWidthMax', 'style', 'children']); - - var didMountUniversal = this.state.didMountUniversal; - - - var containerStyle = _extends({}, _styles.containerStyleDefault, autoHeight && _extends({}, _styles.containerStyleAutoHeight, { - minHeight: autoHeightMin, - maxHeight: autoHeightMax - }), style); - - var viewStyle = _extends({}, _styles.viewStyleDefault, { - // Hide scrollbars by setting a negative margin - marginRight: -this.getPaddingWidth(), - marginBottom: -this.getPaddingHeight() - }, autoHeight && _extends({}, _styles.viewStyleAutoHeight, { - // Add paddingHeight to autoHeight in order to compensate negative margins - minHeight: (0, _isString2["default"])(autoHeightMin) ? 'calc(' + autoHeightMin + ' + ' + this.getPaddingHeight() + 'px)' : autoHeightMin + this.getPaddingHeight(), - maxHeight: (0, _isString2["default"])(autoHeightMax) ? 'calc(' + autoHeightMax + ' + ' + this.getPaddingHeight() + 'px)' : autoHeightMax + this.getPaddingHeight() - }), universal && !didMountUniversal && _styles.viewStyleUniversalInitial); - - var viewWrapperStyle = _extends({}, _styles.viewWrapperStyleDefault, autoWidth && _extends({}, _styles.viewWrapperStyleAutoHeight, { - minWidth: autoWidthMin, - maxWidth: autoWidthMax - })); - - var viewWrappedStyle = _extends({}, _styles.viewWrappedStyleDefault); - - var trackAutoHeightStyle = { - transition: 'opacity ' + autoHideDuration + 'ms', - opacity: 0 - }; - - var trackHorizontalStyle = _extends({}, _styles.trackHorizontalStyleDefault, autoHide && trackAutoHeightStyle, universal && !didMountUniversal && { - display: 'none' - }); - - var trackVerticalStyle = _extends({}, _styles.trackVerticalStyleDefault, autoHide && trackAutoHeightStyle, universal && !didMountUniversal && { - display: 'none' - }); - - return _react2["default"].createElement( - 'div', - _extends({}, props.className ? { className: props.className } : {}, { style: containerStyle, ref: 'container' }), - _react2["default"].createElement( + + var trackHorizontalStyle = _extends({}, _styles.trackHorizontalStyleDefault, autoHide && trackAutoHeightStyle, universal && !didMountUniversal && { + display: 'none' + }); + + var trackVerticalStyle = _extends({}, _styles.trackVerticalStyleDefault, autoHide && trackAutoHeightStyle, universal && !didMountUniversal && { + display: 'none' + }); + + return _react2["default"].createElement( 'div', - { style: viewStyle, ref: 'view' }, + _extends({}, props.className ? { className: props.className } : {}, { style: containerStyle, ref: 'container' }), _react2["default"].createElement( 'div', - { style: viewWrapperStyle, ref: 'viewWrapper' }, - (0, _react.cloneElement)(renderView({ style: viewWrappedStyle }), { ref: 'viewWrapped' }, children) - ) - ), - (0, _react.cloneElement)(renderTrackHorizontal({ style: trackHorizontalStyle }), { ref: 'trackHorizontal' }, (0, _react.cloneElement)(renderThumbHorizontal({ style: _styles.thumbHorizontalStyleDefault }), { ref: 'thumbHorizontal' })), - (0, _react.cloneElement)(renderTrackVertical({ style: trackVerticalStyle }), { ref: 'trackVertical' }, (0, _react.cloneElement)(renderThumbVertical({ style: _styles.thumbVerticalStyleDefault }), { ref: 'thumbVertical' })) - ); - } -}); \ No newline at end of file + { style: viewStyle, ref: 'view' }, + _react2["default"].createElement( + 'div', + { style: viewWrapperStyle, ref: 'viewWrapper' }, + (0, _react.cloneElement)(renderView({ style: viewWrappedStyle }), { ref: 'viewWrapped' }, children) + ) + ), + (0, _react.cloneElement)(renderTrackHorizontal({ style: trackHorizontalStyle }), { ref: 'trackHorizontal' }, (0, _react.cloneElement)(renderThumbHorizontal({ style: _styles.thumbHorizontalStyleDefault }), { ref: 'thumbHorizontal' })), + (0, _react.cloneElement)(renderTrackVertical({ style: trackVerticalStyle }), { ref: 'trackVertical' }, (0, _react.cloneElement)(renderThumbVertical({ style: _styles.thumbVerticalStyleDefault }), { ref: 'thumbVertical' })) + ); + } + }]); + + return Scrollbars; +}(_react2["default"].Component); + +exports["default"] = Scrollbars; + + +Scrollbars.propTypes = { + onScroll: _propTypes2["default"].func, + onScrollFrame: _propTypes2["default"].func, + onScrollStart: _propTypes2["default"].func, + onScrollStop: _propTypes2["default"].func, + onUpdate: _propTypes2["default"].func, + renderView: _propTypes2["default"].func, + renderTrackHorizontal: _propTypes2["default"].func, + renderTrackVertical: _propTypes2["default"].func, + renderThumbHorizontal: _propTypes2["default"].func, + renderThumbVertical: _propTypes2["default"].func, + tagName: _propTypes2["default"].string, + thumbSize: _propTypes2["default"].number, + thumbMinSize: _propTypes2["default"].number, + hideTracksWhenNotNeeded: _propTypes2["default"].bool, + autoHide: _propTypes2["default"].bool, + autoHideTimeout: _propTypes2["default"].number, + autoHideDuration: _propTypes2["default"].number, + autoHeight: _propTypes2["default"].bool, + autoHeightMin: _propTypes2["default"].oneOfType([_propTypes2["default"].number, _propTypes2["default"].string]), + autoHeightMax: _propTypes2["default"].oneOfType([_propTypes2["default"].number, _propTypes2["default"].string]), + autoWidth: _propTypes2["default"].bool, + autoWidthMin: _propTypes2["default"].oneOfType([_propTypes2["default"].number, _propTypes2["default"].string]), + autoWidthMax: _propTypes2["default"].oneOfType([_propTypes2["default"].number, _propTypes2["default"].string]), + universal: _propTypes2["default"].bool, + style: _propTypes2["default"].object, + children: _propTypes2["default"].node +}; + +Scrollbars.defaultProps = { + renderView: _defaultRenderElements.renderViewDefault, + renderTrackHorizontal: _defaultRenderElements.renderTrackHorizontalDefault, + renderTrackVertical: _defaultRenderElements.renderTrackVerticalDefault, + renderThumbHorizontal: _defaultRenderElements.renderThumbHorizontalDefault, + renderThumbVertical: _defaultRenderElements.renderThumbVerticalDefault, + tagName: 'div', + thumbMinSize: 30, + hideTracksWhenNotNeeded: false, + autoHide: false, + autoHideTimeout: 1000, + autoHideDuration: 200, + autoHeight: false, + autoHeightMin: 0, + autoHeightMax: 200, + autoWidth: false, + autoWidthMin: '100%', + autoWidthMax: '100%', + universal: false +}; \ No newline at end of file diff --git a/lib/utils/getInnerHeight.js b/lib/utils/getInnerHeight.js index 1d6b4143..80561299 100644 --- a/lib/utils/getInnerHeight.js +++ b/lib/utils/getInnerHeight.js @@ -7,10 +7,9 @@ exports["default"] = getInnerHeight; function getInnerHeight(el) { var clientHeight = el.clientHeight; - var _getComputedStyle = getComputedStyle(el); - - var paddingTop = _getComputedStyle.paddingTop; - var paddingBottom = _getComputedStyle.paddingBottom; + var _getComputedStyle = getComputedStyle(el), + paddingTop = _getComputedStyle.paddingTop, + paddingBottom = _getComputedStyle.paddingBottom; return clientHeight - parseFloat(paddingTop) - parseFloat(paddingBottom); } \ No newline at end of file diff --git a/lib/utils/getInnerWidth.js b/lib/utils/getInnerWidth.js index fc7267e3..6f45ad8b 100644 --- a/lib/utils/getInnerWidth.js +++ b/lib/utils/getInnerWidth.js @@ -7,10 +7,9 @@ exports["default"] = getInnerWidth; function getInnerWidth(el) { var clientWidth = el.clientWidth; - var _getComputedStyle = getComputedStyle(el); - - var paddingLeft = _getComputedStyle.paddingLeft; - var paddingRight = _getComputedStyle.paddingRight; + var _getComputedStyle = getComputedStyle(el), + paddingLeft = _getComputedStyle.paddingLeft, + paddingRight = _getComputedStyle.paddingRight; return clientWidth - parseFloat(paddingLeft) - parseFloat(paddingRight); } \ No newline at end of file diff --git a/package.json b/package.json index 9d796388..007dce34 100644 --- a/package.json +++ b/package.json @@ -67,11 +67,12 @@ "webpack-dev-server": "^1.8.2" }, "peerDependencies": { - "react": "^0.14.0 || ^15.0.0-0", - "react-dom": "^0.14.0 || ^15.0.0-0" + "react": "^16.0.0", + "react-dom": "^16.0.0" }, "dependencies": { "dom-css": "^2.0.0", + "prop-types": "^15.5.8", "raf": "^3.1.0" } } diff --git a/src/Scrollbars/index.js b/src/Scrollbars/index.js index 96772cb4..8bfa824f 100644 --- a/src/Scrollbars/index.js +++ b/src/Scrollbars/index.js @@ -1,6 +1,8 @@ import raf, { cancel as caf } from 'raf'; import css from 'dom-css'; -import React, { createClass, PropTypes, cloneElement } from 'react'; +import React, { cloneElement } from 'react'; +import PropTypes from 'prop-types'; + import isString from '../utils/isString'; import returnFalse from '../utils/returnFalse'; import getInnerWidth from '../utils/getInnerWidth'; @@ -32,138 +34,91 @@ import { renderThumbVerticalDefault } from './defaultRenderElements'; -export default createClass({ - - displayName: 'Scrollbars', - - propTypes: { - onScroll: PropTypes.func, - onScrollFrame: PropTypes.func, - onScrollStart: PropTypes.func, - onScrollStop: PropTypes.func, - onUpdate: PropTypes.func, - renderView: PropTypes.func, - renderTrackHorizontal: PropTypes.func, - renderTrackVertical: PropTypes.func, - renderThumbHorizontal: PropTypes.func, - renderThumbVertical: PropTypes.func, - thumbSize: PropTypes.number, - thumbMinSize: PropTypes.number, - hideTracksWhenNotNeeded: PropTypes.bool, - autoHide: PropTypes.bool, - autoHideTimeout: PropTypes.number, - autoHideDuration: PropTypes.number, - autoHeight: PropTypes.bool, - autoHeightMin: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.string - ]), - autoHeightMax: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.string - ]), - autoWidth: PropTypes.bool, - autoWidthMin: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.string - ]), - autoWidthMax: PropTypes.oneOfType([ - PropTypes.number, - PropTypes.string - ]), - universal: PropTypes.bool, - style: PropTypes.object, - children: PropTypes.node, - }, - - getDefaultProps() { - return { - renderView: renderViewDefault, - renderTrackHorizontal: renderTrackHorizontalDefault, - renderTrackVertical: renderTrackVerticalDefault, - renderThumbHorizontal: renderThumbHorizontalDefault, - renderThumbVertical: renderThumbVerticalDefault, - thumbMinSize: 30, - hideTracksWhenNotNeeded: false, - autoHide: false, - autoHideTimeout: 1000, - autoHideDuration: 200, - autoHeight: false, - autoHeightMin: 0, - autoHeightMax: 200, - autoWidth: false, - autoWidthMin: '100%', - autoWidthMax: '100%', - universal: false, - }; - }, +export default class Scrollbars extends React.Component { + + constructor(props, ...rest) { + super(props, ...rest); + + this.handleTrackMouseEnter = this.handleTrackMouseEnter.bind(this); + this.handleTrackMouseLeave = this.handleTrackMouseLeave.bind(this); + this.handleHorizontalTrackMouseDown = this.handleHorizontalTrackMouseDown.bind(this); + this.handleVerticalTrackMouseDown = this.handleVerticalTrackMouseDown.bind(this); + this.handleHorizontalThumbMouseDown = this.handleHorizontalThumbMouseDown.bind(this); + this.handleVerticalThumbMouseDown = this.handleVerticalThumbMouseDown.bind(this); + this.handleWindowResize = this.handleWindowResize.bind(this); + this.handleScroll = this.handleScroll.bind(this); + this.handleDrag = this.handleDrag.bind(this); + this.handleDragEnd = this.handleDragEnd.bind(this); + + this.state = this.getInitialState(); + } getInitialState() { return { didMountUniversal: false }; - }, + } componentDidMount() { this.addListeners(); this.update(); this.componentDidMountUniversal(); - }, + } componentDidMountUniversal() { // eslint-disable-line react/sort-comp const { universal } = this.props; if (!universal) return; this.setState({ didMountUniversal: true }); - }, + } componentDidUpdate() { this.update(); - }, + } componentWillUnmount() { this.removeListeners(); caf(this.requestFrame); clearTimeout(this.hideTracksTimeout); clearInterval(this.detectScrollingInterval); - }, + } getScrollLeft() { const { view } = this.refs; return view.scrollLeft; - }, + } getScrollTop() { const { view } = this.refs; return view.scrollTop; - }, + } getScrollWidth() { const { view } = this.refs; return view.scrollWidth - this.getPaddingWidth(); - }, + } getScrollHeight() { const { view } = this.refs; return view.scrollHeight - this.getPaddingHeight(); - }, + } getClientWidth() { const { view } = this.refs; return view.clientWidth - this.getPaddingWidth(); - }, + } getClientHeight() { const { view } = this.refs; return view.clientHeight - this.getPaddingHeight(); - }, + } getPaddingWidth() { return scrollbarSize; - }, + } getPaddingHeight() { return scrollbarSize; - }, + } getValues() { const { view } = this.refs; @@ -187,7 +142,7 @@ export default createClass({ clientWidth, clientHeight }; - }, + } getThumbHorizontalWidth() { const { thumbSize, thumbMinSize } = this.props; @@ -199,7 +154,7 @@ export default createClass({ if (scrollWidth <= clientWidth) return 0; if (thumbSize) return thumbSize; return Math.max(width, thumbMinSize); - }, + } getThumbVerticalHeight() { const { thumbSize, thumbMinSize } = this.props; @@ -211,7 +166,7 @@ export default createClass({ if (scrollHeight <= clientHeight) return 0; if (thumbSize) return thumbSize; return Math.max(height, thumbMinSize); - }, + } getScrollLeftForOffset(offset) { const { view, trackHorizontal } = this.refs; @@ -220,7 +175,7 @@ export default createClass({ const trackWidth = getInnerWidth(trackHorizontal); const thumbWidth = this.getThumbHorizontalWidth(); return offset / (trackWidth - thumbWidth) * (scrollWidth - clientWidth); - }, + } getScrollTopForOffset(offset) { const { view, trackVertical } = this.refs; @@ -229,37 +184,37 @@ export default createClass({ const trackHeight = getInnerHeight(trackVertical); const thumbHeight = this.getThumbVerticalHeight(); return offset / (trackHeight - thumbHeight) * (scrollHeight - clientHeight); - }, + } scrollLeft(left = 0) { const { view } = this.refs; view.scrollLeft = left; - }, + } scrollTop(top = 0) { const { view } = this.refs; view.scrollTop = top; - }, + } scrollToLeft() { const { view } = this.refs; view.scrollLeft = 0; - }, + } scrollToTop() { const { view } = this.refs; view.scrollTop = 0; - }, + } scrollToRight() { const { view } = this.refs; view.scrollLeft = view.scrollWidth - this.getPaddingWidth(); - }, + } scrollToBottom() { const { view } = this.refs; view.scrollTop = view.scrollHeight - this.getPaddingHeight(); - }, + } addListeners() { /* istanbul ignore if */ @@ -275,7 +230,7 @@ export default createClass({ thumbHorizontal.addEventListener('mousedown', this.handleHorizontalThumbMouseDown); thumbVertical.addEventListener('mousedown', this.handleVerticalThumbMouseDown); window.addEventListener('resize', this.handleWindowResize); - }, + } removeListeners() { /* istanbul ignore if */ @@ -293,7 +248,7 @@ export default createClass({ window.removeEventListener('resize', this.handleWindowResize); // Possibly setup by `handleDragStart` this.teardownDragging(); - }, + } handleScroll(event) { const { onScroll, onScrollFrame } = this.props; @@ -305,35 +260,35 @@ export default createClass({ if (onScrollFrame) onScrollFrame(values); }); this.detectScrolling(); - }, + } handleScrollStart() { const { onScrollStart } = this.props; if (onScrollStart) onScrollStart(); this.handleScrollStartAutoHide(); - }, + } handleScrollStartAutoHide() { const { autoHide } = this.props; if (!autoHide) return; this.showTracks(); - }, + } handleScrollStop() { const { onScrollStop } = this.props; if (onScrollStop) onScrollStop(); this.handleScrollStopAutoHide(); - }, + } handleScrollStopAutoHide() { const { autoHide } = this.props; if (!autoHide) return; this.hideTracks(); - }, + } handleWindowResize() { this.update(); - }, + } handleHorizontalTrackMouseDown() { const { view } = this.refs; @@ -342,7 +297,7 @@ export default createClass({ const thumbWidth = this.getThumbHorizontalWidth(); const offset = Math.abs(targetLeft - clientX) - thumbWidth / 2; view.scrollLeft = this.getScrollLeftForOffset(offset); - }, + } handleVerticalTrackMouseDown(event) { const { view } = this.refs; @@ -351,7 +306,7 @@ export default createClass({ const thumbHeight = this.getThumbVerticalHeight(); const offset = Math.abs(targetTop - clientY) - thumbHeight / 2; view.scrollTop = this.getScrollTopForOffset(offset); - }, + } handleHorizontalThumbMouseDown(event) { this.handleDragStart(event); @@ -359,7 +314,7 @@ export default createClass({ const { offsetWidth } = target; const { left } = target.getBoundingClientRect(); this.prevPageX = offsetWidth - (clientX - left); - }, + } handleVerticalThumbMouseDown(event) { this.handleDragStart(event); @@ -367,27 +322,27 @@ export default createClass({ const { offsetHeight } = target; const { top } = target.getBoundingClientRect(); this.prevPageY = offsetHeight - (clientY - top); - }, + } setupDragging() { css(document.body, disableSelectStyle); document.addEventListener('mousemove', this.handleDrag); document.addEventListener('mouseup', this.handleDragEnd); document.onselectstart = returnFalse; - }, + } teardownDragging() { css(document.body, disableSelectStyleReset); document.removeEventListener('mousemove', this.handleDrag); document.removeEventListener('mouseup', this.handleDragEnd); document.onselectstart = undefined; - }, + } handleDragStart(event) { this.dragging = true; event.stopImmediatePropagation(); this.setupDragging(); - }, + } handleDrag(event) { if (this.prevPageX) { @@ -409,49 +364,49 @@ export default createClass({ view.scrollTop = this.getScrollTopForOffset(offset); } return false; - }, + } handleDragEnd() { this.dragging = false; this.prevPageX = this.prevPageY = 0; this.teardownDragging(); this.handleDragEndAutoHide(); - }, + } handleDragEndAutoHide() { const { autoHide } = this.props; if (!autoHide) return; this.hideTracks(); - }, + } handleTrackMouseEnter() { this.trackMouseOver = true; this.handleTrackMouseEnterAutoHide(); - }, + } handleTrackMouseEnterAutoHide() { const { autoHide } = this.props; if (!autoHide) return; this.showTracks(); - }, + } handleTrackMouseLeave() { this.trackMouseOver = false; this.handleTrackMouseLeaveAutoHide(); - }, + } handleTrackMouseLeaveAutoHide() { const { autoHide } = this.props; if (!autoHide) return; this.hideTracks(); - }, + } showTracks() { const { trackHorizontal, trackVertical } = this.refs; clearTimeout(this.hideTracksTimeout); css(trackHorizontal, { opacity: 1 }); css(trackVertical, { opacity: 1 }); - }, + } hideTracks() { if (this.dragging) return; @@ -464,7 +419,7 @@ export default createClass({ css(trackHorizontal, { opacity: 0 }); css(trackVertical, { opacity: 0 }); }, autoHideTimeout); - }, + } detectScrolling() { if (this.scrolling) return; @@ -480,7 +435,7 @@ export default createClass({ this.lastViewScrollLeft = this.viewScrollLeft; this.lastViewScrollTop = this.viewScrollTop; }, 100); - }, + } raf(callback) { if (this.requestFrame) raf.cancel(this.requestFrame); @@ -488,11 +443,11 @@ export default createClass({ this.requestFrame = undefined; callback(); }); - }, + } update(callback) { this.raf(() => this._update(callback)); - }, + } _update(callback) { const { onUpdate, hideTracksWhenNotNeeded } = this.props; @@ -531,7 +486,7 @@ export default createClass({ if (onUpdate) onUpdate(values); if (typeof callback !== 'function') return; callback(values); - }, + } render() { const { @@ -657,4 +612,66 @@ export default createClass({ ); } -}); +} + +Scrollbars.propTypes = { + onScroll: PropTypes.func, + onScrollFrame: PropTypes.func, + onScrollStart: PropTypes.func, + onScrollStop: PropTypes.func, + onUpdate: PropTypes.func, + renderView: PropTypes.func, + renderTrackHorizontal: PropTypes.func, + renderTrackVertical: PropTypes.func, + renderThumbHorizontal: PropTypes.func, + renderThumbVertical: PropTypes.func, + tagName: PropTypes.string, + thumbSize: PropTypes.number, + thumbMinSize: PropTypes.number, + hideTracksWhenNotNeeded: PropTypes.bool, + autoHide: PropTypes.bool, + autoHideTimeout: PropTypes.number, + autoHideDuration: PropTypes.number, + autoHeight: PropTypes.bool, + autoHeightMin: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string + ]), + autoHeightMax: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string + ]), + autoWidth: PropTypes.bool, + autoWidthMin: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string + ]), + autoWidthMax: PropTypes.oneOfType([ + PropTypes.number, + PropTypes.string + ]), + universal: PropTypes.bool, + style: PropTypes.object, + children: PropTypes.node, +}; + +Scrollbars.defaultProps = { + renderView: renderViewDefault, + renderTrackHorizontal: renderTrackHorizontalDefault, + renderTrackVertical: renderTrackVerticalDefault, + renderThumbHorizontal: renderThumbHorizontalDefault, + renderThumbVertical: renderThumbVerticalDefault, + tagName: 'div', + thumbMinSize: 30, + hideTracksWhenNotNeeded: false, + autoHide: false, + autoHideTimeout: 1000, + autoHideDuration: 200, + autoHeight: false, + autoHeightMin: 0, + autoHeightMax: 200, + autoWidth: false, + autoWidthMin: '100%', + autoWidthMax: '100%', + universal: false, +}; diff --git a/test/Scrollbars/autoHeight.js b/test/Scrollbars/autoHeight.js index c3632ea0..ea92692d 100644 --- a/test/Scrollbars/autoHeight.js +++ b/test/Scrollbars/autoHeight.js @@ -1,6 +1,6 @@ import { Scrollbars } from 'react-custom-scrollbars'; import { render, unmountComponentAtNode, findDOMNode } from 'react-dom'; -import React, { createClass } from 'react'; +import React, { Component } from 'react'; export default function createTests(scrollbarWidth) { describe('autoHeight', () => { @@ -147,7 +147,7 @@ export default function createTests(scrollbarWidth) { describe('when using perecentages', () => { it('should use calc', done => { - const Root = createClass({ + class Root extends Component { render() { return (
@@ -161,7 +161,7 @@ export default function createTests(scrollbarWidth) {
); } - }); + } render(, node, function callback() { setTimeout(() => { const { scrollbars } = this.refs; diff --git a/test/Scrollbars/flexbox.js b/test/Scrollbars/flexbox.js index 7ab1bac0..1df9c18e 100644 --- a/test/Scrollbars/flexbox.js +++ b/test/Scrollbars/flexbox.js @@ -1,6 +1,6 @@ import { Scrollbars } from 'react-custom-scrollbars'; import { render, unmountComponentAtNode, findDOMNode } from 'react-dom'; -import React, { createClass } from 'react'; +import React, { Component } from 'react'; export default function createTests() { let node; @@ -14,7 +14,7 @@ export default function createTests() { }); describe('when scrollbars are in flexbox environment', () => { it('should still work', done => { - const Root = createClass({ + class Root extends Component { render() { return (
@@ -24,7 +24,7 @@ export default function createTests() {
); } - }); + } render(, node, function callback() { setTimeout(() => { const { scrollbars } = this.refs;