choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
234 lines (198 loc) • 7.1 kB
JavaScript
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _inherits from "@babel/runtime/helpers/inherits";
import _createSuper from "@babel/runtime/helpers/createSuper";
import _typeof from "@babel/runtime/helpers/typeof";
import { cloneElement, Component, isValidElement } from 'react';
import { findDOMNode } from 'react-dom';
import noop from 'lodash/noop';
import alignElement, { alignPoint } from './domAlign';
import EventManager from '../_util/EventManager';
import TaskRunner from '../_util/TaskRunner';
import { isSamePoint, isWindow } from './util';
function getElement(func) {
if (typeof func !== 'function' || !func) return null;
return func();
}
function getPoint(point) {
if (_typeof(point) !== 'object' || !point) return null;
return point;
}
function isChildrenFunction(fn) {
return typeof fn === 'function';
}
var Align = /*#__PURE__*/function (_Component) {
_inherits(Align, _Component);
var _super = _createSuper(Align);
function Align() {
var _this;
_classCallCheck(this, Align);
_this = _super.apply(this, arguments);
_this.saveSourceRef = function (node) {
_this.source = node;
var childrenRef = _this.props.childrenRef;
if (childrenRef) {
childrenRef(node);
}
};
return _this;
}
_createClass(Align, [{
key: "componentDidMount",
value: function componentDidMount() {
var _this$props = this.props,
hidden = _this$props.hidden,
monitorWindowResize = _this$props.monitorWindowResize;
this.forceAlign();
if (!hidden && monitorWindowResize) {
this.startMonitorWindowResize();
}
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
var _this$props2 = this.props,
hidden = _this$props2.hidden,
align = _this$props2.align,
target = _this$props2.target,
monitorWindowResize = _this$props2.monitorWindowResize;
var preHidden = prevProps.hidden,
preAlign = prevProps.align,
preTarget = prevProps.target;
var reAlign = false;
if (!hidden) {
var _this$source = this.source,
source = _this$source === void 0 ? findDOMNode(this) : _this$source;
var sourceRect = source ? source.getBoundingClientRect() : null;
if (preHidden || preAlign !== align) {
reAlign = true;
} else {
var lastElement = getElement(preTarget);
var currentElement = getElement(target);
var lastPoint = getPoint(preTarget);
var currentPoint = getPoint(target);
if (isWindow(lastElement) && isWindow(currentElement)) {
// Skip if is window
reAlign = false;
} else if (lastElement !== currentElement || // Element change
lastElement && !currentElement && currentPoint || // Change from element to point
lastPoint && currentPoint && currentElement || // Change from point to element
currentPoint && !isSamePoint(lastPoint, currentPoint)) {
reAlign = true;
} // If source element size changed
var preRect = this.sourceRect;
if (!reAlign && sourceRect && preRect && (preRect.width !== sourceRect.width || preRect.height !== sourceRect.height)) {
reAlign = true;
}
}
this.sourceRect = sourceRect;
}
if (reAlign) {
this.forceAlign();
}
if (monitorWindowResize && !hidden) {
this.startMonitorWindowResize();
} else {
this.stopMonitorWindowResize();
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.stopMonitorWindowResize();
}
}, {
key: "startMonitorWindowResize",
value: function startMonitorWindowResize() {
var monitorBufferTime = this.props.monitorBufferTime;
if (!this.resizeHandler) {
this.resizeHandler = new EventManager(window);
this.bufferMonitor = new TaskRunner();
this.resizeHandler.addEventListener('resize', this.bufferMonitor.delay.bind(this.bufferMonitor, monitorBufferTime, this.forceAlign.bind(this)));
}
}
}, {
key: "stopMonitorWindowResize",
value: function stopMonitorWindowResize() {
if (this.resizeHandler) {
if (this.bufferMonitor) {
this.bufferMonitor.cancel();
}
this.resizeHandler.clear();
this.resizeHandler = null;
}
}
}, {
key: "forceAlign",
value: function forceAlign() {
var _this$props3 = this.props,
hidden = _this$props3.hidden,
_this$props3$onAlign = _this$props3.onAlign,
onAlign = _this$props3$onAlign === void 0 ? noop : _this$props3$onAlign,
target = _this$props3.target,
align = _this$props3.align;
if (!hidden && target) {
var _this$source2 = this.source,
source = _this$source2 === void 0 ? findDOMNode(this) : _this$source2;
var result;
var element = getElement(target);
var point = getPoint(target);
if (element) {
result = alignElement(source, element, align);
} else if (point) {
result = alignPoint(source, point, align);
}
var translate = {
x: 0,
y: 0
};
var _result = result,
points = _result.points,
_result$overflow = _result.overflow,
adjustX = _result$overflow.adjustX,
adjustY = _result$overflow.adjustY;
if (source && element && (adjustX || adjustY) && (points.includes('bc') || points.includes('tc'))) {
var r1 = source.getBoundingClientRect();
var r2 = element.getBoundingClientRect();
if (adjustX) {
translate.x = r1.left + r1.width / 2 - r2.left - r2.width / 2;
}
if (adjustY) {
translate.y = r1.top + r1.height / 2 - r2.top - r2.height / 2;
}
}
onAlign(source, result, element, translate, point);
}
}
}, {
key: "render",
value: function render() {
var props = this.props;
var childrenProps = props.childrenProps,
children = props.children;
var node = isChildrenFunction(children) ? children(this.saveSourceRef) : children;
if (childrenProps && /*#__PURE__*/isValidElement(node)) {
var newProps = {};
Object.keys(childrenProps).forEach(function (prop) {
if ({}.hasOwnProperty.call(childrenProps, prop)) {
newProps[prop] = props[childrenProps[prop]];
}
});
return /*#__PURE__*/cloneElement(node, newProps);
}
return node;
}
}]);
return Align;
}(Component);
export { Align as default };
Align.displayName = 'Align';
Align.defaultProps = {
target: function target() {
return window;
},
monitorBufferTime: 50,
monitorWindowResize: false,
hidden: true
};
//# sourceMappingURL=Align.js.map