react-concise-scrollbar
Version:
a React concise scrollbar component with macOS style
107 lines (96 loc) • 5.13 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _react = require("react");
var _react2 = _interopRequireDefault(_react);
require("./Scrollbar.css");
var _useDebounce = require("../hooks/useDebounce");
var _useThrottle = require("../hooks/useThrottle");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var ScrollBar = _react2.default.forwardRef(function (props, ref) {
var childrenRef = (0, _react.useRef)();
var thumbRef = (0, _react.useRef)();
var trackRef = (0, _react.useRef)();
var wrapperRef = (0, _react.useRef)();
var contentRef = (0, _react.useRef)();
if (ref) {
contentRef = ref;
}
var wrapperParentRef = (0, _react.useRef)();
var _useState = (0, _react.useState)(false),
_useState2 = _slicedToArray(_useState, 2),
thumbVisible = _useState2[0],
setThumbVisible = _useState2[1];
var delayHideScrollbar = (0, _useDebounce.useDebounce)(function () {
setThumbVisible(false);
}, 1000);
var throttleUpdateThumb = (0, _useThrottle.useThrottle)(function () {
setThumbVisible(true);thumbRef.current.style.top = contentRef.current.scrollTop * trackRef.current.offsetHeight / childrenRef.current.offsetHeight + 'px';
}, 8);
var updatePadding = function updatePadding() {
childrenRef.current.style.padding = getComputedStyle(wrapperParentRef, null).padding;
wrapperRef.current.style.top = "-" + getComputedStyle(wrapperParentRef, null).paddingTop;
wrapperRef.current.style.left = "-" + getComputedStyle(wrapperParentRef, null).paddingLeft;
wrapperRef.current.style.height = "calc(100% + " + getComputedStyle(wrapperParentRef, null).paddingTop + " + " + getComputedStyle(wrapperParentRef, null).paddingBottom + ")";
wrapperRef.current.style.width = "calc(100% + " + getComputedStyle(wrapperParentRef, null).paddingLeft + " + " + getComputedStyle(wrapperParentRef, null).paddingRight + ")";
};
var updateWrapper = (0, _useThrottle.useThrottle)(function () {
updatePadding();
}, 20);
var updateChildren = (0, _useThrottle.useThrottle)(function () {
if (childrenRef.current.offsetHeight > wrapperRef.current.offsetHeight) {
thumbRef.current.style.height = wrapperRef.current.offsetHeight * trackRef.current.offsetHeight / childrenRef.current.offsetHeight + 'px';
} else {
thumbRef.current.style.height = 0;
}
}, 20);
var resizeObserver = new ResizeObserver(function (entries) {
if (wrapperRef && wrapperRef.current) {
for (var i = 0; i < entries.length; i++) {
updateChildren();
if (entries[i].target === wrapperParentRef) {
if (childrenRef.current.style.padding !== getComputedStyle(wrapperParentRef, null).padding) {
updateWrapper();
}
}
}
}
});
(0, _react.useEffect)(function () {
wrapperParentRef = wrapperRef.current.parentNode;
wrapperParentRef.style.overflow = 'hidden';
resizeObserver.observe(childrenRef.current);
resizeObserver.observe(wrapperParentRef);
updatePadding();
return function () {
resizeObserver.disconnect();
};
}, [wrapperRef]);
var updateThumb = function updateThumb() {
throttleUpdateThumb();
delayHideScrollbar();
};
return _react2.default.createElement(
"div",
{ className: "scrollbar-wrapper", ref: wrapperRef, key: props.key },
_react2.default.createElement(
"div",
{ className: "scrollbar-content", key: props.key, ref: contentRef, style: { scrollBehavior: props.behavior }, onScroll: function onScroll() {
updateThumb();
} },
_react2.default.createElement(
"div",
{ className: "scrollbar-children", ref: childrenRef, key: props.key },
props.children
)
),
_react2.default.createElement(
"div",
{ ref: trackRef, className: "scrollbar-track", key: props.key },
_react2.default.createElement("div", { className: "scrollbar-thumb " + (thumbVisible ? 'thumb-show' : ''), key: props.key, ref: thumbRef })
)
);
});
exports.default = ScrollBar;