linkmore-design
Version:
π πlmη»δ»ΆεΊγπ
155 lines (154 loc) β’ 5.44 kB
JavaScript
;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _classnames = _interopRequireDefault(require("classnames"));
var _addEventListener = _interopRequireDefault(require("rc-util/lib/Dom/addEventListener"));
var _css = require("rc-util/lib/Dom/css");
var _getScrollBarSize = _interopRequireDefault(require("rc-util/lib/getScrollBarSize"));
var React = _interopRequireWildcard(require("react"));
var _TableContext = _interopRequireDefault(require("./context/TableContext"));
var _ContextSelector = require("./ContextSelector");
var _useFrame = require("./hooks/useFrame");
const StickyScrollBar = ({
scrollBodyRef,
onScroll,
offsetScroll,
container
}, ref) => {
const prefixCls = (0, _ContextSelector.useContextSelector)(_TableContext.default, 'prefixCls');
const bodyScrollWidth = scrollBodyRef.current?.scrollWidth || 0;
const bodyWidth = scrollBodyRef.current?.clientWidth || 0;
const scrollBarWidth = bodyScrollWidth && bodyWidth * (bodyWidth / bodyScrollWidth);
const scrollBarRef = React.useRef();
const [scrollState, setScrollState] = (0, _useFrame.useLayoutState)({
scrollLeft: 0,
isHiddenScrollBar: false
});
const refState = React.useRef({
delta: 0,
x: 0
});
const [isActive, setActive] = React.useState(false);
const onMouseUp = () => {
setActive(false);
};
const onMouseDown = event => {
event.persist();
refState.current.delta = event.pageX - scrollState.scrollLeft;
refState.current.x = 0;
setActive(true);
event.preventDefault();
};
const onMouseMove = event => {
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
const {
buttons
} = event || window?.event;
if (!isActive || buttons === 0) {
// If out body mouse up, we can set isActive false when mouse move
if (isActive) {
setActive(false);
}
return;
}
let left = refState.current.x + event.pageX - refState.current.x - refState.current.delta;
if (left <= 0) {
left = 0;
}
if (left + scrollBarWidth >= bodyWidth) {
left = bodyWidth - scrollBarWidth;
}
onScroll({
scrollLeft: left / bodyWidth * (bodyScrollWidth + 2)
});
refState.current.x = event.pageX;
};
const onContainerScroll = () => {
if (!scrollBodyRef.current) {
return;
}
const tableOffsetTop = (0, _css.getOffset)(scrollBodyRef.current).top;
const tableBottomOffset = tableOffsetTop + scrollBodyRef.current.offsetHeight;
const currentClientOffset = container === window ? document.documentElement.scrollTop + window.innerHeight : (0, _css.getOffset)(container).top + container.clientHeight;
if (tableBottomOffset - (0, _getScrollBarSize.default)() <= currentClientOffset || tableOffsetTop >= currentClientOffset - offsetScroll) {
setScrollState(state => ({
...state,
isHiddenScrollBar: true
}));
} else {
setScrollState(state => ({
...state,
isHiddenScrollBar: false
}));
}
};
const setScrollLeft = left => {
setScrollState(state => {
return {
...state,
scrollLeft: left / bodyScrollWidth * bodyWidth || 0
};
});
};
React.useImperativeHandle(ref, () => ({
setScrollLeft
}));
React.useEffect(() => {
const onMouseUpListener = (0, _addEventListener.default)(document.body, 'mouseup', onMouseUp, false);
const onMouseMoveListener = (0, _addEventListener.default)(document.body, 'mousemove', onMouseMove, false);
onContainerScroll();
return () => {
onMouseUpListener.remove();
onMouseMoveListener.remove();
};
}, [scrollBarWidth, isActive]);
React.useEffect(() => {
const onScrollListener = (0, _addEventListener.default)(container, 'scroll', onContainerScroll, false);
const onResizeListener = (0, _addEventListener.default)(window, 'resize', onContainerScroll, false);
return () => {
onScrollListener.remove();
onResizeListener.remove();
};
}, [container]);
React.useEffect(() => {
if (!scrollState.isHiddenScrollBar) {
setScrollState(state => {
const bodyNode = scrollBodyRef.current;
if (!bodyNode) {
return state;
}
return {
...state,
scrollLeft: bodyNode.scrollLeft / bodyNode.scrollWidth * bodyNode.clientWidth
};
});
}
}, [scrollState.isHiddenScrollBar]);
if (bodyScrollWidth <= bodyWidth || !scrollBarWidth || scrollState.isHiddenScrollBar) {
return null;
}
return /*#__PURE__*/React.createElement("div", {
style: {
height: (0, _getScrollBarSize.default)(),
width: bodyWidth,
bottom: offsetScroll
},
className: `${prefixCls}-sticky-scroll`
}, /*#__PURE__*/React.createElement("div", {
onMouseDown: onMouseDown,
ref: scrollBarRef,
className: (0, _classnames.default)(`${prefixCls}-sticky-scroll-bar`, {
[`${prefixCls}-sticky-scroll-bar-active`]: isActive
}),
style: {
width: `${scrollBarWidth}px`,
transform: `translate3d(${scrollState.scrollLeft}px, 0, 0)`
}
}));
};
var _default = /*#__PURE__*/React.forwardRef(StickyScrollBar);
exports.default = _default;