react-scrollbar-patch
Version:
A patch of souhe/reactScrollbar that fixes a significant bug preventing range sliders working (issue #42).
1,329 lines (1,143 loc) • 389 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("react"));
else if(typeof define === 'function' && define.amd)
define(["react"], factory);
else if(typeof exports === 'object')
exports["ScrollArea"] = factory(require("react"));
else
root["ScrollArea"] = factory(root["React"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_6__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
__webpack_require__(1);
var _ScrollArea = __webpack_require__(5);
var _ScrollArea2 = _interopRequireDefault(_ScrollArea);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = _ScrollArea2.default;
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
// style-loader: Adds some css to the DOM by adding a <style> tag
// load the styles
var content = __webpack_require__(2);
if(typeof content === 'string') content = [[module.id, content, '']];
// add the styles to the DOM
var update = __webpack_require__(4)(content, {});
if(content.locals) module.exports = content.locals;
// Hot Module Replacement
if(false) {
// When the styles change, update the <style> tags
if(!content.locals) {
module.hot.accept("!!../../node_modules/css-loader/index.js!../../node_modules/less-loader/index.js!./scrollArea.less", function() {
var newContent = require("!!../../node_modules/css-loader/index.js!../../node_modules/less-loader/index.js!./scrollArea.less");
if(typeof newContent === 'string') newContent = [[module.id, newContent, '']];
update(newContent);
});
}
// When the module is disposed, remove the <style> tags
module.hot.dispose(function() { update(); });
}
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(3)();
// imports
// module
exports.push([module.id, ".scrollarea-content {\n margin: 0;\n padding: 0;\n overflow: hidden;\n position: relative;\n}\n.scrollarea-content:focus {\n outline: 0;\n}\n.scrollarea {\n position: relative;\n overflow: hidden;\n}\n.scrollarea .scrollbar-container {\n position: absolute;\n background: none;\n opacity: .1;\n z-index: 9999;\n -webkit-transition: all .4s;\n -moz-transition: all .4s;\n -ms-transition: all .4s;\n -o-transition: all .4s;\n transition: all .4s;\n}\n.scrollarea .scrollbar-container.horizontal {\n width: 100%;\n height: 10px;\n left: 0;\n bottom: 0;\n}\n.scrollarea .scrollbar-container.horizontal .scrollbar {\n width: 20px;\n height: 8px;\n background: black;\n margin-top: 1px;\n}\n.scrollarea .scrollbar-container.vertical {\n width: 10px;\n height: 100%;\n right: 0;\n top: 0;\n}\n.scrollarea .scrollbar-container.vertical .scrollbar {\n width: 8px;\n height: 20px;\n background: black;\n margin-left: 1px;\n}\n.scrollarea .scrollbar-container:hover {\n background: gray;\n opacity: .6 !important;\n}\n.scrollarea .scrollbar-container.active {\n background: gray;\n opacity: .6 !important;\n}\n.scrollarea:hover .scrollbar-container {\n opacity: .3;\n}\n", ""]);
// exports
/***/ },
/* 3 */
/***/ function(module, exports) {
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function() {
var list = [];
// return the list of modules as css string
list.toString = function toString() {
var result = [];
for(var i = 0; i < this.length; i++) {
var item = this[i];
if(item[2]) {
result.push("@media " + item[2] + "{" + item[1] + "}");
} else {
result.push(item[1]);
}
}
return result.join("");
};
// import a list of modules into the list
list.i = function(modules, mediaQuery) {
if(typeof modules === "string")
modules = [[null, modules, ""]];
var alreadyImportedModules = {};
for(var i = 0; i < this.length; i++) {
var id = this[i][0];
if(typeof id === "number")
alreadyImportedModules[id] = true;
}
for(i = 0; i < modules.length; i++) {
var item = modules[i];
// skip already imported module
// this implementation is not 100% perfect for weird media query combinations
// when a module is imported multiple times with different media queries.
// I hope this will never occur (Hey this way we have smaller bundles)
if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
if(mediaQuery && !item[2]) {
item[2] = mediaQuery;
} else if(mediaQuery) {
item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
}
list.push(item);
}
}
};
return list;
};
/***/ },
/* 4 */
/***/ function(module, exports, __webpack_require__) {
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var stylesInDom = {},
memoize = function(fn) {
var memo;
return function () {
if (typeof memo === "undefined") memo = fn.apply(this, arguments);
return memo;
};
},
isOldIE = memoize(function() {
return /msie [6-9]\b/.test(self.navigator.userAgent.toLowerCase());
}),
getHeadElement = memoize(function () {
return document.head || document.getElementsByTagName("head")[0];
}),
singletonElement = null,
singletonCounter = 0,
styleElementsInsertedAtTop = [];
module.exports = function(list, options) {
if(false) {
if(typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
}
options = options || {};
// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
// tags it will allow on a page
if (typeof options.singleton === "undefined") options.singleton = isOldIE();
// By default, add <style> tags to the bottom of <head>.
if (typeof options.insertAt === "undefined") options.insertAt = "bottom";
var styles = listToStyles(list);
addStylesToDom(styles, options);
return function update(newList) {
var mayRemove = [];
for(var i = 0; i < styles.length; i++) {
var item = styles[i];
var domStyle = stylesInDom[item.id];
domStyle.refs--;
mayRemove.push(domStyle);
}
if(newList) {
var newStyles = listToStyles(newList);
addStylesToDom(newStyles, options);
}
for(var i = 0; i < mayRemove.length; i++) {
var domStyle = mayRemove[i];
if(domStyle.refs === 0) {
for(var j = 0; j < domStyle.parts.length; j++)
domStyle.parts[j]();
delete stylesInDom[domStyle.id];
}
}
};
}
function addStylesToDom(styles, options) {
for(var i = 0; i < styles.length; i++) {
var item = styles[i];
var domStyle = stylesInDom[item.id];
if(domStyle) {
domStyle.refs++;
for(var j = 0; j < domStyle.parts.length; j++) {
domStyle.parts[j](item.parts[j]);
}
for(; j < item.parts.length; j++) {
domStyle.parts.push(addStyle(item.parts[j], options));
}
} else {
var parts = [];
for(var j = 0; j < item.parts.length; j++) {
parts.push(addStyle(item.parts[j], options));
}
stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
}
}
}
function listToStyles(list) {
var styles = [];
var newStyles = {};
for(var i = 0; i < list.length; i++) {
var item = list[i];
var id = item[0];
var css = item[1];
var media = item[2];
var sourceMap = item[3];
var part = {css: css, media: media, sourceMap: sourceMap};
if(!newStyles[id])
styles.push(newStyles[id] = {id: id, parts: [part]});
else
newStyles[id].parts.push(part);
}
return styles;
}
function insertStyleElement(options, styleElement) {
var head = getHeadElement();
var lastStyleElementInsertedAtTop = styleElementsInsertedAtTop[styleElementsInsertedAtTop.length - 1];
if (options.insertAt === "top") {
if(!lastStyleElementInsertedAtTop) {
head.insertBefore(styleElement, head.firstChild);
} else if(lastStyleElementInsertedAtTop.nextSibling) {
head.insertBefore(styleElement, lastStyleElementInsertedAtTop.nextSibling);
} else {
head.appendChild(styleElement);
}
styleElementsInsertedAtTop.push(styleElement);
} else if (options.insertAt === "bottom") {
head.appendChild(styleElement);
} else {
throw new Error("Invalid value for parameter 'insertAt'. Must be 'top' or 'bottom'.");
}
}
function removeStyleElement(styleElement) {
styleElement.parentNode.removeChild(styleElement);
var idx = styleElementsInsertedAtTop.indexOf(styleElement);
if(idx >= 0) {
styleElementsInsertedAtTop.splice(idx, 1);
}
}
function createStyleElement(options) {
var styleElement = document.createElement("style");
styleElement.type = "text/css";
insertStyleElement(options, styleElement);
return styleElement;
}
function createLinkElement(options) {
var linkElement = document.createElement("link");
linkElement.rel = "stylesheet";
insertStyleElement(options, linkElement);
return linkElement;
}
function addStyle(obj, options) {
var styleElement, update, remove;
if (options.singleton) {
var styleIndex = singletonCounter++;
styleElement = singletonElement || (singletonElement = createStyleElement(options));
update = applyToSingletonTag.bind(null, styleElement, styleIndex, false);
remove = applyToSingletonTag.bind(null, styleElement, styleIndex, true);
} else if(obj.sourceMap &&
typeof URL === "function" &&
typeof URL.createObjectURL === "function" &&
typeof URL.revokeObjectURL === "function" &&
typeof Blob === "function" &&
typeof btoa === "function") {
styleElement = createLinkElement(options);
update = updateLink.bind(null, styleElement);
remove = function() {
removeStyleElement(styleElement);
if(styleElement.href)
URL.revokeObjectURL(styleElement.href);
};
} else {
styleElement = createStyleElement(options);
update = applyToTag.bind(null, styleElement);
remove = function() {
removeStyleElement(styleElement);
};
}
update(obj);
return function updateStyle(newObj) {
if(newObj) {
if(newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap)
return;
update(obj = newObj);
} else {
remove();
}
};
}
var replaceText = (function () {
var textStore = [];
return function (index, replacement) {
textStore[index] = replacement;
return textStore.filter(Boolean).join('\n');
};
})();
function applyToSingletonTag(styleElement, index, remove, obj) {
var css = remove ? "" : obj.css;
if (styleElement.styleSheet) {
styleElement.styleSheet.cssText = replaceText(index, css);
} else {
var cssNode = document.createTextNode(css);
var childNodes = styleElement.childNodes;
if (childNodes[index]) styleElement.removeChild(childNodes[index]);
if (childNodes.length) {
styleElement.insertBefore(cssNode, childNodes[index]);
} else {
styleElement.appendChild(cssNode);
}
}
}
function applyToTag(styleElement, obj) {
var css = obj.css;
var media = obj.media;
if(media) {
styleElement.setAttribute("media", media)
}
if(styleElement.styleSheet) {
styleElement.styleSheet.cssText = css;
} else {
while(styleElement.firstChild) {
styleElement.removeChild(styleElement.firstChild);
}
styleElement.appendChild(document.createTextNode(css));
}
}
function updateLink(linkElement, obj) {
var css = obj.css;
var sourceMap = obj.sourceMap;
if(sourceMap) {
// http://stackoverflow.com/a/26603875
css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
}
var blob = new Blob([css], { type: "text/css" });
var oldSrc = linkElement.href;
linkElement.href = URL.createObjectURL(blob);
if(oldSrc)
URL.revokeObjectURL(oldSrc);
}
/***/ },
/* 5 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
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 _react = __webpack_require__(6);
var _react2 = _interopRequireDefault(_react);
var _Scrollbar = __webpack_require__(7);
var _Scrollbar2 = _interopRequireDefault(_Scrollbar);
var _utils = __webpack_require__(32);
var _lineHeight2 = __webpack_require__(33);
var _lineHeight3 = _interopRequireDefault(_lineHeight2);
var _reactMotion = __webpack_require__(8);
var _propTypes = __webpack_require__(18);
var _propTypes2 = _interopRequireDefault(_propTypes);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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 eventTypes = {
wheel: 'wheel',
api: 'api',
touch: 'touch',
touchEnd: 'touchEnd',
mousemove: 'mousemove',
keyPress: 'keypress'
};
var ScrollArea = function (_React$Component) {
_inherits(ScrollArea, _React$Component);
function ScrollArea(props) {
_classCallCheck(this, ScrollArea);
var _this = _possibleConstructorReturn(this, (ScrollArea.__proto__ || Object.getPrototypeOf(ScrollArea)).call(this, props));
_this.state = {
topPosition: 0,
leftPosition: 0,
realHeight: 0,
containerHeight: 0,
realWidth: 0,
containerWidth: 0
};
_this.scrollArea = {
refresh: function refresh() {
_this.setSizesToState();
},
scrollTop: function scrollTop() {
_this.scrollTop();
},
scrollBottom: function scrollBottom() {
_this.scrollBottom();
},
scrollYTo: function scrollYTo(position) {
_this.scrollYTo(position);
},
scrollLeft: function scrollLeft() {
_this.scrollLeft();
},
scrollRight: function scrollRight() {
_this.scrollRight();
},
scrollXTo: function scrollXTo(position) {
_this.scrollXTo(position);
}
};
_this.evntsPreviousValues = {
clientX: 0,
clientY: 0,
deltaX: 0,
deltaY: 0
};
_this.bindedHandleWindowResize = _this.handleWindowResize.bind(_this);
return _this;
}
_createClass(ScrollArea, [{
key: 'getChildContext',
value: function getChildContext() {
return {
scrollArea: this.scrollArea
};
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
if (this.props.contentWindow) {
this.props.contentWindow.addEventListener("resize", this.bindedHandleWindowResize);
}
this.lineHeightPx = (0, _lineHeight3.default)((0, _utils.findDOMNode)(this.content));
this.setSizesToState();
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
if (this.props.contentWindow) {
this.props.contentWindow.removeEventListener("resize", this.bindedHandleWindowResize);
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
this.setSizesToState();
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
children = _props.children,
className = _props.className,
contentClassName = _props.contentClassName,
ownerDocument = _props.ownerDocument;
var withMotion = this.props.smoothScrolling && (this.state.eventType === eventTypes.wheel || this.state.eventType === eventTypes.api || this.state.eventType === eventTypes.touchEnd || this.state.eventType === eventTypes.keyPress);
var scrollbarY = this.canScrollY() ? _react2.default.createElement(_Scrollbar2.default, {
ownerDocument: ownerDocument,
realSize: this.state.realHeight,
containerSize: this.state.containerHeight,
position: this.state.topPosition,
onMove: this.handleScrollbarMove.bind(this),
onPositionChange: this.handleScrollbarYPositionChange.bind(this),
containerStyle: this.props.verticalContainerStyle,
scrollbarStyle: this.props.verticalScrollbarStyle,
smoothScrolling: withMotion,
minScrollSize: this.props.minScrollSize,
onFocus: this.focusContent.bind(this),
type: 'vertical' }) : null;
var scrollbarX = this.canScrollX() ? _react2.default.createElement(_Scrollbar2.default, {
ownerDocument: ownerDocument,
realSize: this.state.realWidth,
containerSize: this.state.containerWidth,
position: this.state.leftPosition,
onMove: this.handleScrollbarMove.bind(this),
onPositionChange: this.handleScrollbarXPositionChange.bind(this),
containerStyle: this.props.horizontalContainerStyle,
scrollbarStyle: this.props.horizontalScrollbarStyle,
smoothScrolling: withMotion,
minScrollSize: this.props.minScrollSize,
onFocus: this.focusContent.bind(this),
type: 'horizontal' }) : null;
if (typeof children === 'function') {
(0, _utils.warnAboutFunctionChild)();
children = children();
} else {
(0, _utils.warnAboutElementChild)();
}
var classes = 'scrollarea ' + (className || '');
var contentClasses = 'scrollarea-content ' + (contentClassName || '');
var contentStyle = {
marginTop: -this.state.topPosition,
marginLeft: -this.state.leftPosition
};
var springifiedContentStyle = withMotion ? (0, _utils.modifyObjValues)(contentStyle, function (x) {
return (0, _reactMotion.spring)(x);
}) : contentStyle;
return _react2.default.createElement(
_reactMotion.Motion,
{ style: springifiedContentStyle },
function (style) {
return _react2.default.createElement(
'div',
{
ref: function ref(x) {
return _this2.wrapper = x;
},
className: classes,
style: _this2.props.style,
onWheel: _this2.handleWheel.bind(_this2)
},
_react2.default.createElement(
'div',
{
ref: function ref(x) {
return _this2.content = x;
},
style: _extends({}, _this2.props.contentStyle, style),
className: contentClasses,
onTouchStart: _this2.handleTouchStart.bind(_this2),
onTouchMove: _this2.handleTouchMove.bind(_this2),
onTouchEnd: _this2.handleTouchEnd.bind(_this2),
onKeyDown: _this2.handleKeyDown.bind(_this2),
tabIndex: _this2.props.focusableTabIndex
},
children
),
scrollbarY,
scrollbarX
);
}
);
}
}, {
key: 'setStateFromEvent',
value: function setStateFromEvent(newState, eventType) {
if (this.props.onScroll) {
this.props.onScroll(newState);
}
this.setState(_extends({}, newState, { eventType: eventType }));
}
}, {
key: 'handleTouchStart',
value: function handleTouchStart(e) {
var touches = e.touches;
if (touches.length === 1) {
var _touches$ = touches[0],
clientX = _touches$.clientX,
clientY = _touches$.clientY;
this.eventPreviousValues = _extends({}, this.eventPreviousValues, {
clientY: clientY,
clientX: clientX,
timestamp: Date.now()
});
}
}
}, {
key: 'handleTouchMove',
value: function handleTouchMove(e) {
e.preventDefault();
e.stopPropagation();
var touches = e.touches;
if (touches.length === 1) {
var _touches$2 = touches[0],
clientX = _touches$2.clientX,
clientY = _touches$2.clientY;
var deltaY = this.eventPreviousValues.clientY - clientY;
var deltaX = this.eventPreviousValues.clientX - clientX;
this.eventPreviousValues = _extends({}, this.eventPreviousValues, {
deltaY: deltaY,
deltaX: deltaX,
clientY: clientY,
clientX: clientX,
timestamp: Date.now()
});
this.setStateFromEvent(this.composeNewState(-deltaX, -deltaY));
}
}
}, {
key: 'handleTouchEnd',
value: function handleTouchEnd(e) {
var _eventPreviousValues = this.eventPreviousValues,
deltaX = _eventPreviousValues.deltaX,
deltaY = _eventPreviousValues.deltaY,
timestamp = _eventPreviousValues.timestamp;
if (typeof deltaX === 'undefined') deltaX = 0;
if (typeof deltaY === 'undefined') deltaY = 0;
if (Date.now() - timestamp < 200) {
this.setStateFromEvent(this.composeNewState(-deltaX * 10, -deltaY * 10), eventTypes.touchEnd);
}
this.eventPreviousValues = _extends({}, this.eventPreviousValues, {
deltaY: 0,
deltaX: 0
});
}
}, {
key: 'handleScrollbarMove',
value: function handleScrollbarMove(deltaY, deltaX) {
this.setStateFromEvent(this.composeNewState(deltaX, deltaY));
}
}, {
key: 'handleScrollbarXPositionChange',
value: function handleScrollbarXPositionChange(position) {
this.scrollXTo(position);
}
}, {
key: 'handleScrollbarYPositionChange',
value: function handleScrollbarYPositionChange(position) {
this.scrollYTo(position);
}
}, {
key: 'handleWheel',
value: function handleWheel(e) {
var deltaY = e.deltaY;
var deltaX = e.deltaX;
if (this.props.swapWheelAxes) {
var _ref = [deltaX, deltaY];
deltaY = _ref[0];
deltaX = _ref[1];
}
/*
* WheelEvent.deltaMode can differ between browsers and must be normalized
* e.deltaMode === 0: The delta values are specified in pixels
* e.deltaMode === 1: The delta values are specified in lines
* https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaMode
*/
if (e.deltaMode === 1) {
deltaY = deltaY * this.lineHeightPx;
deltaX = deltaX * this.lineHeightPx;
}
deltaY = deltaY * this.props.speed;
deltaX = deltaX * this.props.speed;
var newState = this.composeNewState(-deltaX, -deltaY);
if (newState.topPosition && this.state.topPosition !== newState.topPosition || newState.leftPosition && this.state.leftPosition !== newState.leftPosition || this.props.stopScrollPropagation) {
e.preventDefault();
e.stopPropagation();
}
this.setStateFromEvent(newState, eventTypes.wheel);
this.focusContent();
}
}, {
key: 'handleKeyDown',
value: function handleKeyDown(e) {
// only handle if scroll area is in focus
if (e.target.tagName.toLowerCase() !== 'input') {
var deltaY = 0;
var deltaX = 0;
var _lineHeight = this.lineHeightPx ? this.lineHeightPx : 10;
switch (e.keyCode) {
case 33:
// page up
deltaY = this.state.containerHeight - _lineHeight;
break;
case 34:
// page down
deltaY = -this.state.containerHeight + _lineHeight;
break;
case 37:
// left
deltaX = _lineHeight;
break;
case 38:
// up
deltaY = _lineHeight;
break;
case 39:
// right
deltaX = -_lineHeight;
break;
case 40:
// down
deltaY = -_lineHeight;
break;
}
// only compose new state if key code matches those above
if (deltaY !== 0 || deltaX !== 0) {
var newState = this.composeNewState(deltaX, deltaY);
e.preventDefault();
e.stopPropagation();
this.setStateFromEvent(newState, eventTypes.keyPress);
}
}
}
}, {
key: 'handleWindowResize',
value: function handleWindowResize() {
var newState = this.computeSizes();
newState = this.getModifiedPositionsIfNeeded(newState);
this.setStateFromEvent(newState);
}
}, {
key: 'composeNewState',
value: function composeNewState(deltaX, deltaY) {
var newState = this.computeSizes();
if (this.canScrollY(newState)) {
newState.topPosition = this.computeTopPosition(deltaY, newState);
} else {
newState.topPosition = 0;
}
if (this.canScrollX(newState)) {
newState.leftPosition = this.computeLeftPosition(deltaX, newState);
}
return newState;
}
}, {
key: 'computeTopPosition',
value: function computeTopPosition(deltaY, sizes) {
var newTopPosition = this.state.topPosition - deltaY;
return this.normalizeTopPosition(newTopPosition, sizes);
}
}, {
key: 'computeLeftPosition',
value: function computeLeftPosition(deltaX, sizes) {
var newLeftPosition = this.state.leftPosition - deltaX;
return this.normalizeLeftPosition(newLeftPosition, sizes);
}
}, {
key: 'normalizeTopPosition',
value: function normalizeTopPosition(newTopPosition, sizes) {
if (newTopPosition > sizes.realHeight - sizes.containerHeight) {
newTopPosition = sizes.realHeight - sizes.containerHeight;
}
if (newTopPosition < 0) {
newTopPosition = 0;
}
return newTopPosition;
}
}, {
key: 'normalizeLeftPosition',
value: function normalizeLeftPosition(newLeftPosition, sizes) {
if (newLeftPosition > sizes.realWidth - sizes.containerWidth) {
newLeftPosition = sizes.realWidth - sizes.containerWidth;
} else if (newLeftPosition < 0) {
newLeftPosition = 0;
}
return newLeftPosition;
}
}, {
key: 'computeSizes',
value: function computeSizes() {
var realHeight = this.content.offsetHeight;
var containerHeight = this.wrapper.offsetHeight;
var realWidth = this.content.offsetWidth;
var containerWidth = this.wrapper.offsetWidth;
return {
realHeight: realHeight,
containerHeight: containerHeight,
realWidth: realWidth,
containerWidth: containerWidth
};
}
}, {
key: 'setSizesToState',
value: function setSizesToState() {
var sizes = this.computeSizes();
if (sizes.realHeight !== this.state.realHeight || sizes.realWidth !== this.state.realWidth) {
this.setStateFromEvent(this.getModifiedPositionsIfNeeded(sizes));
}
}
}, {
key: 'scrollTop',
value: function scrollTop() {
this.scrollYTo(0);
}
}, {
key: 'scrollBottom',
value: function scrollBottom() {
this.scrollYTo(this.state.realHeight - this.state.containerHeight);
}
}, {
key: 'scrollLeft',
value: function scrollLeft() {
this.scrollXTo(0);
}
}, {
key: 'scrollRight',
value: function scrollRight() {
this.scrollXTo(this.state.realWidth - this.state.containerWidth);
}
}, {
key: 'scrollYTo',
value: function scrollYTo(topPosition) {
if (this.canScrollY()) {
var position = this.normalizeTopPosition(topPosition, this.computeSizes());
this.setStateFromEvent({ topPosition: position }, eventTypes.api);
}
}
}, {
key: 'scrollXTo',
value: function scrollXTo(leftPosition) {
if (this.canScrollX()) {
var position = this.normalizeLeftPosition(leftPosition, this.computeSizes());
this.setStateFromEvent({ leftPosition: position }, eventTypes.api);
}
}
}, {
key: 'canScrollY',
value: function canScrollY() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
var scrollableY = state.realHeight > state.containerHeight;
return scrollableY && this.props.vertical;
}
}, {
key: 'canScrollX',
value: function canScrollX() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
var scrollableX = state.realWidth > state.containerWidth;
return scrollableX && this.props.horizontal;
}
}, {
key: 'getModifiedPositionsIfNeeded',
value: function getModifiedPositionsIfNeeded(newState) {
var bottomPosition = newState.realHeight - newState.containerHeight;
if (this.state.topPosition >= bottomPosition) {
newState.topPosition = this.canScrollY(newState) ? (0, _utils.positiveOrZero)(bottomPosition) : 0;
}
var rightPosition = newState.realWidth - newState.containerWidth;
if (this.state.leftPosition >= rightPosition) {
newState.leftPosition = this.canScrollX(newState) ? (0, _utils.positiveOrZero)(rightPosition) : 0;
}
return newState;
}
}, {
key: 'focusContent',
value: function focusContent() {
if (this.content) {
(0, _utils.findDOMNode)(this.content).focus();
}
}
}]);
return ScrollArea;
}(_react2.default.Component);
exports.default = ScrollArea;
ScrollArea.childContextTypes = {
scrollArea: _propTypes2.default.object
};
ScrollArea.propTypes = {
className: _propTypes2.default.string,
style: _propTypes2.default.object,
speed: _propTypes2.default.number,
contentClassName: _propTypes2.default.string,
contentStyle: _propTypes2.default.object,
vertical: _propTypes2.default.bool,
verticalContainerStyle: _propTypes2.default.object,
verticalScrollbarStyle: _propTypes2.default.object,
horizontal: _propTypes2.default.bool,
horizontalContainerStyle: _propTypes2.default.object,
horizontalScrollbarStyle: _propTypes2.default.object,
onScroll: _propTypes2.default.func,
contentWindow: _propTypes2.default.any,
ownerDocument: _propTypes2.default.any,
smoothScrolling: _propTypes2.default.bool,
minScrollSize: _propTypes2.default.number,
swapWheelAxes: _propTypes2.default.bool,
stopScrollPropagation: _propTypes2.default.bool,
focusableTabIndex: _propTypes2.default.number
};
ScrollArea.defaultProps = {
speed: 1,
vertical: true,
horizontal: true,
smoothScrolling: false,
swapWheelAxes: false,
contentWindow: (typeof window === 'undefined' ? 'undefined' : _typeof(window)) === "object" ? window : undefined,
ownerDocument: (typeof document === 'undefined' ? 'undefined' : _typeof(document)) === "object" ? document : undefined,
focusableTabIndex: 1
};
/***/ },
/* 6 */
/***/ function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_6__;
/***/ },
/* 7 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _react = __webpack_require__(6);
var _react2 = _interopRequireDefault(_react);
var _reactMotion = __webpack_require__(8);
var _utils = __webpack_require__(32);
var _propTypes = __webpack_require__(18);
var _propTypes2 = _interopRequireDefault(_propTypes);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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 ScrollBar = function (_React$Component) {
_inherits(ScrollBar, _React$Component);
function ScrollBar(props) {
_classCallCheck(this, ScrollBar);
var _this = _possibleConstructorReturn(this, (ScrollBar.__proto__ || Object.getPrototypeOf(ScrollBar)).call(this, props));
var newState = _this.calculateState(props);
_this.state = {
position: newState.position,
scrollSize: newState.scrollSize,
isDragging: false,
lastClientPosition: 0
};
if (props.type === 'vertical') {
_this.bindedHandleMouseMove = _this.handleMouseMoveForVertical.bind(_this);
} else {
_this.bindedHandleMouseMove = _this.handleMouseMoveForHorizontal.bind(_this);
}
_this.bindedHandleMouseUp = _this.handleMouseUp.bind(_this);
return _this;
}
_createClass(ScrollBar, [{
key: 'componentDidMount',
value: function componentDidMount() {
if (this.props.ownerDocument) {
this.props.ownerDocument.addEventListener("mousemove", this.bindedHandleMouseMove);
this.props.ownerDocument.addEventListener("mouseup", this.bindedHandleMouseUp);
}
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
this.setState(this.calculateState(nextProps));
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
if (this.props.ownerDocument) {
this.props.ownerDocument.removeEventListener("mousemove", this.bindedHandleMouseMove);
this.props.ownerDocument.removeEventListener("mouseup", this.bindedHandleMouseUp);
}
}
}, {
key: 'calculateFractionalPosition',
value: function calculateFractionalPosition(realContentSize, containerSize, contentPosition) {
var relativeSize = realContentSize - containerSize;
return 1 - (relativeSize - contentPosition) / relativeSize;
}
}, {
key: 'calculateState',
value: function calculateState(props) {
var fractionalPosition = this.calculateFractionalPosition(props.realSize, props.containerSize, props.position);
var proportionalToPageScrollSize = props.containerSize * props.containerSize / props.realSize;
var scrollSize = proportionalToPageScrollSize < props.minScrollSize ? props.minScrollSize : proportionalToPageScrollSize;
var scrollPosition = (props.containerSize - scrollSize) * fractionalPosition;
return {
scrollSize: scrollSize,
position: Math.round(scrollPosition)
};
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
smoothScrolling = _props.smoothScrolling,
isDragging = _props.isDragging,
type = _props.type,
scrollbarStyle = _props.scrollbarStyle,
containerStyle = _props.containerStyle;
var isVoriziontal = type === 'horizontal';
var isVertical = type === 'vertical';
var scrollStyles = this.createScrollStyles();
var springifiedScrollStyles = smoothScrolling ? (0, _utils.modifyObjValues)(scrollStyles, function (x) {
return (0, _reactMotion.spring)(x);
}) : scrollStyles;
var scrollbarClasses = 'scrollbar-container ' + (isDragging ? 'active' : '') + ' ' + (isVoriziontal ? 'horizontal' : '') + ' ' + (isVertical ? 'vertical' : '');
return _react2.default.createElement(
_reactMotion.Motion,
{ style: springifiedScrollStyles },
function (style) {
return _react2.default.createElement(
'div',
{
className: scrollbarClasses,
style: containerStyle,
onMouseDown: _this2.handleScrollBarContainerClick.bind(_this2),
ref: function ref(x) {
return _this2.scrollbarContainer = x;
}
},
_react2.default.createElement('div', {
className: 'scrollbar',
style: _extends({}, scrollbarStyle, style),
onMouseDown: _this2.handleMouseDown.bind(_this2)
})
);
}
);
}
}, {
key: 'handleScrollBarContainerClick',
value: function handleScrollBarContainerClick(e) {
e.preventDefault();
var multiplier = this.computeMultiplier();
var clientPosition = this.isVertical() ? e.clientY : e.clientX;
var _scrollbarContainer$g = this.scrollbarContainer.getBoundingClientRect(),
top = _scrollbarContainer$g.top,
left = _scrollbarContainer$g.left;
var clientScrollPosition = this.isVertical() ? top : left;
var position = clientPosition - clientScrollPosition;
var proportionalToPageScrollSize = this.props.containerSize * this.props.containerSize / this.props.realSize;
this.setState({ isDragging: true, lastClientPosition: clientPosition });
this.props.onPositionChange((position - proportionalToPageScrollSize / 2) / multiplier);
}
}, {
key: 'handleMouseMoveForHorizontal',
value: function handleMouseMoveForHorizontal(e) {
var multiplier = this.computeMultiplier();
if (this.state.isDragging) {
e.preventDefault();
var deltaX = this.state.lastClientPosition - e.clientX;
this.setState({ lastClientPosition: e.clientX });
this.props.onMove(0, deltaX / multiplier);
}
}
}, {
key: 'handleMouseMoveForVertical',
value: function handleMouseMoveForVertical(e) {
var multiplier = this.computeMultiplier();
if (this.state.isDragging) {
e.preventDefault();
var deltaY = this.state.lastClientPosition - e.clientY;
this.setState({ lastClientPosition: e.clientY });
this.props.onMove(deltaY / multiplier, 0);
}
}
}, {
key: 'handleMouseDown',
value: function handleMouseDown(e) {
e.preventDefault();
e.stopPropagation();
var lastClientPosition = this.isVertical() ? e.clientY : e.clientX;
this.setState({ isDragging: true, lastClientPosition: lastClientPosition });
this.props.onFocus();
}
}, {
key: 'handleMouseUp',
value: function handleMouseUp(e) {
if (this.state.isDragging) {
e.preventDefault();
this.setState({ isDragging: false });
}
}
}, {
key: 'createScrollStyles',
value: function createScrollStyles() {
if (this.props.type === 'vertical') {
return {
height: this.state.scrollSize,
marginTop: this.state.position
};
} else {
return {
width: this.state.scrollSize,
marginLeft: this.state.position
};
}
}
}, {
key: 'computeMultiplier',
value: function computeMultiplier() {
return this.props.containerSize / this.props.realSize;
}
}, {
key: 'isVertical',
value: function isVertical() {
return this.props.type === 'vertical';
}
}]);
return ScrollBar;
}(_react2.default.Component);
ScrollBar.propTypes = {
onMove: _propTypes2.default.func,
onPositionChange: _propTypes2.default.func,
onFocus: _propTypes2.default.func,
realSize: _propTypes2.default.number,
containerSize: _propTypes2.default.number,
position: _propTypes2.default.number,
containerStyle: _propTypes2.default.object,
scrollbarStyle: _propTypes2.default.object,
type: _propTypes2.default.oneOf(['vertical', 'horizontal']),
ownerDocument: _propTypes2.default.any,
smoothScrolling: _propTypes2.default.bool,
minScrollSize: _propTypes2.default.number
};
ScrollBar.defaultProps = {
type: 'vertical',
smoothScrolling: false
};
exports.default = ScrollBar;
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
function _interopRequire(obj) { return obj && obj.__esModule ? obj['default'] : obj; }
var _Motion = __webpack_require__(9);
exports.Motion = _interopRequire(_Motion);
var _StaggeredMotion = __webpack_require__(26);
exports.StaggeredMotion = _interopRequire(_StaggeredMotion);
var _TransitionMotion = __webpack_require__(27);
exports.TransitionMotion = _interopRequire(_TransitionMotion);
var _spring = __webpack_require__(29);
exports.spring = _interopRequire(_spring);
var _presets = __webpack_require__(30);
exports.presets = _interopRequire(_presets);
var _stripStyle = __webpack_require__(11);
exports.stripStyle = _interopRequire(_stripStyle);
// deprecated, dummy warning function
var _reorderKeys = __webpack_require__(31);
exports.reorderKeys = _interopRequire(_reorderKeys);
/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key i