BackTop.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. "use client";
  2. var __rest = this && this.__rest || function (s, e) {
  3. var t = {};
  4. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  5. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  6. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  7. }
  8. return t;
  9. };
  10. import React, { useContext, useEffect, useState } from 'react';
  11. import VerticalAlignTopOutlined from "@ant-design/icons/es/icons/VerticalAlignTopOutlined";
  12. import classNames from 'classnames';
  13. import CSSMotion from 'rc-motion';
  14. import { composeRef } from "rc-util/es/ref";
  15. import getScroll from '../_util/getScroll';
  16. import scrollTo from '../_util/scrollTo';
  17. import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
  18. import { ConfigContext } from '../config-provider';
  19. import { useComponentConfig } from '../config-provider/context';
  20. import FloatButtonGroupContext from './context';
  21. import FloatButton, { floatButtonPrefixCls } from './FloatButton';
  22. const defaultIcon = /*#__PURE__*/React.createElement(VerticalAlignTopOutlined, null);
  23. const BackTop = /*#__PURE__*/React.forwardRef((props, ref) => {
  24. var _a;
  25. const {
  26. backTopIcon: contextIcon
  27. } = useComponentConfig('floatButton');
  28. const {
  29. prefixCls: customizePrefixCls,
  30. className,
  31. type = 'default',
  32. shape = 'circle',
  33. visibilityHeight = 400,
  34. icon,
  35. target,
  36. onClick,
  37. duration = 450
  38. } = props,
  39. restProps = __rest(props, ["prefixCls", "className", "type", "shape", "visibilityHeight", "icon", "target", "onClick", "duration"]);
  40. const mergedIcon = (_a = icon !== null && icon !== void 0 ? icon : contextIcon) !== null && _a !== void 0 ? _a : defaultIcon;
  41. const [visible, setVisible] = useState(visibilityHeight === 0);
  42. const internalRef = React.useRef(null);
  43. React.useImperativeHandle(ref, () => ({
  44. nativeElement: internalRef.current
  45. }));
  46. const getDefaultTarget = () => {
  47. var _a;
  48. return ((_a = internalRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument) || window;
  49. };
  50. const handleScroll = throttleByAnimationFrame(e => {
  51. const scrollTop = getScroll(e.target);
  52. setVisible(scrollTop >= visibilityHeight);
  53. });
  54. useEffect(() => {
  55. const getTarget = target || getDefaultTarget;
  56. const container = getTarget();
  57. handleScroll({
  58. target: container
  59. });
  60. container === null || container === void 0 ? void 0 : container.addEventListener('scroll', handleScroll);
  61. return () => {
  62. handleScroll.cancel();
  63. container === null || container === void 0 ? void 0 : container.removeEventListener('scroll', handleScroll);
  64. };
  65. }, [target]);
  66. const scrollToTop = e => {
  67. scrollTo(0, {
  68. getContainer: target || getDefaultTarget,
  69. duration
  70. });
  71. onClick === null || onClick === void 0 ? void 0 : onClick(e);
  72. };
  73. const {
  74. getPrefixCls
  75. } = useContext(ConfigContext);
  76. const prefixCls = getPrefixCls(floatButtonPrefixCls, customizePrefixCls);
  77. const rootPrefixCls = getPrefixCls();
  78. const groupShape = useContext(FloatButtonGroupContext);
  79. const mergedShape = groupShape || shape;
  80. const contentProps = Object.assign({
  81. prefixCls,
  82. icon: mergedIcon,
  83. type,
  84. shape: mergedShape
  85. }, restProps);
  86. return /*#__PURE__*/React.createElement(CSSMotion, {
  87. visible: visible,
  88. motionName: `${rootPrefixCls}-fade`
  89. }, ({
  90. className: motionClassName
  91. }, setRef) => (/*#__PURE__*/React.createElement(FloatButton, Object.assign({
  92. ref: composeRef(internalRef, setRef)
  93. }, contentProps, {
  94. onClick: scrollToTop,
  95. className: classNames(className, motionClassName)
  96. }))));
  97. });
  98. if (process.env.NODE_ENV !== 'production') {
  99. BackTop.displayName = 'BackTop';
  100. }
  101. export default BackTop;