"use strict";

exports.__esModule = true;
exports.default = void 0;

var _react = _interopRequireWildcard(require("react"));

var _clsx = _interopRequireDefault(require("clsx"));

var _useScrollParent = _interopRequireDefault(require("../hooks/use-scroll-parent"));

var _useEventListener = _interopRequireDefault(require("../hooks/use-event-listener"));

var _utils = require("../utils");

var _hooks = require("../hooks");

var _useRect = require("../hooks/use-rect");

var _ConfigProviderContext = _interopRequireDefault(require("../config-provider/ConfigProviderContext"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }

function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }

var Sticky = function Sticky(props) {
  var _useContext = (0, _react.useContext)(_ConfigProviderContext.default),
      prefixCls = _useContext.prefixCls,
      createNamespace = _useContext.createNamespace;

  var _createNamespace = createNamespace('sticky', prefixCls),
      bem = _createNamespace[0];

  var _useSetState = (0, _hooks.useSetState)({
    fixed: false,
    width: 0,
    // root width
    height: 0,
    // root height
    transform: 0
  }),
      state = _useSetState[0],
      updateState = _useSetState[1];

  var root = (0, _react.useRef)(null);
  var scrollParent = (0, _useScrollParent.default)(root);
  var offset = (0, _react.useMemo)(function () {
    return (0, _utils.unitToPx)(props.position === 'top' ? props.offsetTop : props.offsetBottom);
  }, [props.position, props.offsetTop, props.offsetBottom]);
  var rootStyle = (0, _react.useMemo)(function () {
    var fixed = state.fixed,
        height = state.height,
        width = state.width;

    if (fixed) {
      return {
        width: width + "px",
        height: height + "px"
      };
    }

    return null;
  }, [state.fixed, state.height, state.width]);
  var stickyStyle = (0, _react.useMemo)(function () {
    var _extend;

    if (!state.fixed) {
      return null;
    }

    var style = (0, _utils.extend)((0, _utils.getZIndexStyle)(props.zIndex), (_extend = {
      width: state.width + "px",
      height: state.height + "px"
    }, _extend[props.position] = offset + "px", _extend));

    if (state.transform) {
      style.transform = "translate3d(0, " + state.transform + "px, 0)";
    }

    return style;
  }, [props.position, state.fixed, offset, state.width, state.height, state.transform]);

  var emitScroll = function emitScroll(scrollTop, isFixed) {
    if (props.onScroll) {
      props.onScroll({
        scrollTop: scrollTop,
        isFixed: isFixed
      });
    }
  };

  var onScroll = function onScroll() {
    if (!root.current || (0, _utils.isHidden)(root.current)) {
      return;
    }

    var container = props.container,
        position = props.position;
    var rootRect = (0, _useRect.getRect)(root.current);
    var scrollTop = (0, _utils.getScrollTop)(window);
    var newState = {};
    newState.width = rootRect.width;
    newState.height = rootRect.height;

    if (position === 'top') {
      // The sticky component should be kept inside the container element
      if (container) {
        var containerRect = (0, _useRect.getRect)(container.current);
        var difference = containerRect.bottom - offset - newState.height;
        newState.fixed = offset > rootRect.top && containerRect.bottom > 0;
        newState.transform = difference < 0 ? difference : 0;
      } else {
        newState.fixed = offset > rootRect.top;
      }
    } else {
      var clientHeight = document.documentElement.clientHeight;

      if (container) {
        var _containerRect = (0, _useRect.getRect)(container.current);

        var _difference = clientHeight - _containerRect.top - offset - newState.height;

        newState.fixed = clientHeight - offset < rootRect.bottom && clientHeight > _containerRect.top;
        newState.transform = _difference < 0 ? -_difference : 0;
      } else {
        newState.fixed = clientHeight - offset < rootRect.bottom;
      }
    }

    updateState(newState);
    emitScroll(scrollTop, newState.fixed);
  };

  (0, _useEventListener.default)('scroll', onScroll, {
    target: scrollParent
  });
  (0, _hooks.useVisibilityChange)(root, onScroll);
  (0, _hooks.useUpdateEffect)(function () {
    props.onChange == null ? void 0 : props.onChange(state.fixed);
  }, [state.fixed]);
  return /*#__PURE__*/_react.default.createElement("div", {
    ref: root,
    style: rootStyle
  }, /*#__PURE__*/_react.default.createElement("div", {
    className: (0, _clsx.default)(bem({
      fixed: state.fixed
    })),
    style: stickyStyle
  }, props.children));
};

Sticky.defaultProps = {
  offsetTop: 0,
  offsetBottom: 0,
  position: 'top'
};
var _default = Sticky;
exports.default = _default;