UNPKG

qt-public-ui

Version:

新设计规范下业务组件库

90 lines (89 loc) 3.63 kB
/* 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;