qt-public-ui
Version:
新设计规范下业务组件库
90 lines (89 loc) • 3.63 kB
JavaScript
/* eslint-disable no-unused-expressions */
/* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useEffect, useCallback, useRef, useState } from 'react';
import { useUpdateEffect } from 'qt-public-hooks';
import raf from 'raf';
var Sticky = function Sticky(props) {
var children = props.children,
getContainer = props.getContainer,
_props$offset = props.offset,
offset = _props$offset === void 0 ? {
top: 0,
bottom: 0
} : _props$offset,
onStickyChange = props.onStickyChange,
_props$zIndex = props.zIndex,
zIndex = _props$zIndex === void 0 ? 0 : _props$zIndex,
_props$barHeight = props.barHeight,
barHeight = _props$barHeight === void 0 ? 56 : _props$barHeight;
var _useState = useState(false),
sticky = _useState[0],
setSticky = _useState[1];
var stickyRef = useRef(null);
var copyStickyRef = useRef(null);
var content = typeof children === 'function' ? children(sticky) : children;
var rafHandler = useRef();
var copyContent = React.cloneElement(content);
var copyInitOffsetTop = -barHeight || 56;
var notifySubscribers = useCallback(function () {
var _stickyRef$current;
var rect = (_stickyRef$current = stickyRef.current) === null || _stickyRef$current === void 0 ? void 0 : _stickyRef$current.getBoundingClientRect();
if (rect) {
setSticky((rect === null || rect === void 0 ? void 0 : rect.bottom) <= offset.top);
}
}, [offset]);
useUpdateEffect(function () {
var _stickyRef$current2;
onStickyChange && onStickyChange(sticky);
var rect = ((_stickyRef$current2 = stickyRef.current) === null || _stickyRef$current2 === void 0 ? void 0 : _stickyRef$current2.getBoundingClientRect()) || {
width: 0
};
if (sticky) {
// show animation
rafHandler.current = raf(function () {
if (copyStickyRef && copyStickyRef.current) {
copyStickyRef.current.style.top = -copyInitOffsetTop + "px";
copyStickyRef.current.style.width = rect.width + "px";
copyStickyRef.current.style.zIndex = "" + zIndex;
}
});
} else {
// hide animation
rafHandler.current = raf(function () {
if (copyStickyRef && copyStickyRef.current) {
copyStickyRef.current.style.top = copyInitOffsetTop + "px";
copyStickyRef.current.style.zIndex = 'unset';
// copyStickyRef.current.style.position = 'absolute';
}
});
}
}, [sticky]);
useEffect(function () {
var scrollContainer = typeof getContainer === 'function' && stickyRef ? getContainer(stickyRef === null || stickyRef === void 0 ? void 0 : stickyRef.current) : window;
scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.addEventListener('scroll', notifySubscribers);
return function () {
if (rafHandler.current) {
raf.cancel(rafHandler.current);
rafHandler.current = null;
}
scrollContainer === null || scrollContainer === void 0 ? void 0 : scrollContainer.removeEventListener('scroll', notifySubscribers);
};
}, [getContainer, notifySubscribers]);
return /*#__PURE__*/React.createElement("div", {
className: "umui-sticky-wrapper"
}, /*#__PURE__*/React.createElement("div", {
className: "umui-sticky-copy",
style: {
top: copyInitOffsetTop,
display: copyInitOffsetTop ? 'block' : 'none'
},
ref: copyStickyRef
}, copyContent), /*#__PURE__*/React.createElement("div", {
ref: stickyRef,
className: "umui-sticky"
}, content));
};
Sticky.defaultProps = {
getContainer: document.body
};
export default Sticky;