@atlaskit/editor-core
Version:
A package contains Atlassian editor core functionality
102 lines • 4.67 kB
JavaScript
import * as tslib_1 from "tslib";
import * as React from 'react';
import { PureComponent } from 'react';
import { akEditorFloatingPanelZIndex } from '../../styles';
import Portal from '../Portal';
import { calculatePosition, calculatePlacement, findOverflowScrollParent } from './utils';
var Popup = (function (_super) {
tslib_1.__extends(Popup, _super);
function Popup() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.state = {
overflowScrollParent: false
};
_this.debounced = null;
_this.placement = ['', ''];
_this.handleRef = function (popup) {
if (!popup) {
return;
}
_this.initPopup(popup);
};
_this.handleResize = function () {
if (_this.debounced) {
clearTimeout(_this.debounced);
_this.debounced = null;
}
_this.debounced = setTimeout(function () {
_this.debounced = null;
var popup = _this.state.popup;
_this.updatePosition(_this.props, popup);
}, 200);
};
return _this;
}
/**
* Calculates new popup position
*/
Popup.prototype.updatePosition = function (props, popup) {
var target = props.target, fitHeight = props.fitHeight, fitWidth = props.fitWidth, boundariesElement = props.boundariesElement, offset = props.offset, onPositionCalculated = props.onPositionCalculated, onPlacementChanged = props.onPlacementChanged, alignX = props.alignX, alignY = props.alignY;
if (!target || !popup) {
return;
}
var placement = calculatePlacement(target, boundariesElement, fitWidth, fitHeight, alignX, alignY);
if (onPlacementChanged && this.placement.join('') !== placement.join('')) {
onPlacementChanged(placement);
this.placement = placement;
}
var position = calculatePosition({ placement: placement, target: target, popup: popup, offset: offset });
position = onPositionCalculated ? onPositionCalculated(position) : position;
this.setState({ position: position });
};
/**
* Popup initialization.
* Checks whether it's possible to position popup along given target, and if it's not throws an error.
*/
Popup.prototype.initPopup = function (popup) {
var _this = this;
var target = this.props.target;
var overflowScrollParent = findOverflowScrollParent(popup);
if (popup.offsetParent && !popup.offsetParent.contains(target)) {
throw new Error('Popup\'s offset parent doesn\'t contain target which means it\'s impossible to correctly position popup along with given target.');
}
if (overflowScrollParent && !overflowScrollParent.contains(popup.offsetParent)) {
throw new Error('Popup is inside "overflow: scroll" container, but its offset parent isn\'t. Currently Popup isn\'t capable of position itself correctly in such case. Add "position: relative" to "overflow: scroll" container or to some other FloatingPanel wrapper inside it.');
}
this.setState({ popup: popup, overflowScrollParent: overflowScrollParent }, function () {
_this.updatePosition(_this.props, popup);
});
};
Popup.prototype.componentWillReceiveProps = function (newProps) {
var popup = this.state.popup;
this.updatePosition(newProps, popup);
};
Popup.prototype.componentDidMount = function () {
window.addEventListener('resize', this.handleResize);
};
Popup.prototype.componentWillUnmount = function () {
window.removeEventListener('resize', this.handleResize);
};
Popup.prototype.renderPopup = function () {
var position = this.state.position;
return (React.createElement("div", { ref: this.handleRef, style: tslib_1.__assign({ position: 'absolute', zIndex: akEditorFloatingPanelZIndex }, position) }, this.props.children));
};
Popup.prototype.render = function () {
if (!this.props.target) {
return null;
}
if (this.props.mountTo) {
return React.createElement(Portal, { mountTo: this.props.mountTo }, this.renderPopup());
}
// Without mountTo property renders popup as is,
// which means it will be croped by "overflow: hidden" container.
return this.renderPopup();
};
return Popup;
}(PureComponent));
export default Popup;
Popup.defaultProps = {
offset: [0, 0],
boundariesElement: document.body
};
//# sourceMappingURL=index.js.map