react-ctxmenu-trigger
Version:
base abstract ctx menu trigger component for react
374 lines (311 loc) • 11.6 kB
JavaScript
'use strict';
exports.__esModule = true;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _rcAlign = require('rc-align');
var _rcAlign2 = _interopRequireDefault(_rcAlign);
var _rcAnimate = require('rc-animate');
var _rcAnimate2 = _interopRequireDefault(_rcAnimate);
var _PopupInner = require('./PopupInner');
var _PopupInner2 = _interopRequireDefault(_PopupInner);
var _LazyRenderBox = require('./LazyRenderBox');
var _LazyRenderBox2 = _interopRequireDefault(_LazyRenderBox);
var _utils = require('./utils');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var Popup = function (_Component) {
_inherits(Popup, _Component);
function Popup(props) {
_classCallCheck(this, Popup);
var _this = _possibleConstructorReturn(this, _Component.call(this, props));
_initialiseProps.call(_this);
_this.state = {
// Used for stretch
stretchChecked: false,
targetWidth: undefined,
targetHeight: undefined
};
_this.savePopupRef = _utils.saveRef.bind(_this, 'popupInstance');
_this.saveAlignRef = _utils.saveRef.bind(_this, 'alignInstance');
return _this;
}
Popup.prototype.componentDidMount = function componentDidMount() {
this.rootNode = this.getPopupDomNode();
this.setStretchSize();
};
Popup.prototype.componentDidUpdate = function componentDidUpdate() {
this.setStretchSize();
};
// Record size if stretch needed
Popup.prototype.getPopupDomNode = function getPopupDomNode() {
return _reactDom2['default'].findDOMNode(this.popupInstance);
};
// `target` on `rc-align` can accept as a function to get the bind element or a point.
// ref: https://www.npmjs.com/package/rc-align
Popup.prototype.getMaskTransitionName = function getMaskTransitionName() {
var props = this.props;
var transitionName = props.maskTransitionName;
var animation = props.maskAnimation;
if (!transitionName && animation) {
transitionName = props.prefixCls + '-' + animation;
}
return transitionName;
};
Popup.prototype.getTransitionName = function getTransitionName() {
var props = this.props;
var transitionName = props.transitionName;
if (!transitionName && props.animation) {
transitionName = props.prefixCls + '-' + props.animation;
}
return transitionName;
};
Popup.prototype.getClassName = function getClassName(currentAlignClassName) {
return this.props.prefixCls + ' ' + this.props.className + ' ' + currentAlignClassName;
};
Popup.prototype.getPopupElement = function getPopupElement() {
var _this2 = this;
var savePopupRef = this.savePopupRef;
var _state = this.state,
stretchChecked = _state.stretchChecked,
targetHeight = _state.targetHeight,
targetWidth = _state.targetWidth;
var _props = this.props,
align = _props.align,
visible = _props.visible,
prefixCls = _props.prefixCls,
style = _props.style,
getClassNameFromAlign = _props.getClassNameFromAlign,
destroyPopupOnHide = _props.destroyPopupOnHide,
stretch = _props.stretch,
children = _props.children,
onMouseEnter = _props.onMouseEnter,
onMouseLeave = _props.onMouseLeave,
onMouseDown = _props.onMouseDown,
onTouchStart = _props.onTouchStart;
var className = this.getClassName(this.currentAlignClassName || getClassNameFromAlign(align));
var hiddenClassName = prefixCls + '-hidden';
if (!visible) {
this.currentAlignClassName = null;
}
var sizeStyle = {};
if (stretch) {
// Stretch with target
if (stretch.indexOf('height') !== -1) {
sizeStyle.height = targetHeight;
} else if (stretch.indexOf('minHeight') !== -1) {
sizeStyle.minHeight = targetHeight;
}
if (stretch.indexOf('width') !== -1) {
sizeStyle.width = targetWidth;
} else if (stretch.indexOf('minWidth') !== -1) {
sizeStyle.minWidth = targetWidth;
}
// Delay force align to makes ui smooth
if (!stretchChecked) {
sizeStyle.visibility = 'hidden';
setTimeout(function () {
if (_this2.alignInstance) {
_this2.alignInstance.forceAlign();
}
}, 0);
}
}
var newStyle = _extends({}, sizeStyle, style, this.getZIndexStyle());
var popupInnerProps = {
className: className,
prefixCls: prefixCls,
ref: savePopupRef,
onMouseEnter: onMouseEnter,
onMouseLeave: onMouseLeave,
onMouseDown: onMouseDown,
onTouchStart: onTouchStart,
style: newStyle
};
if (destroyPopupOnHide) {
return _react2['default'].createElement(
_rcAnimate2['default'],
{
component: '',
exclusive: true,
transitionAppear: true,
transitionName: this.getTransitionName()
},
visible ? _react2['default'].createElement(
_rcAlign2['default'],
{
target: this.getAlignTarget(),
key: 'popup',
ref: this.saveAlignRef,
monitorWindowResize: true,
align: align,
onAlign: this.onAlign
},
_react2['default'].createElement(
_PopupInner2['default'],
_extends({
visible: true
}, popupInnerProps),
children
)
) : null
);
}
return _react2['default'].createElement(
_rcAnimate2['default'],
{
component: '',
exclusive: true,
transitionAppear: true,
transitionName: this.getTransitionName(),
showProp: 'xVisible'
},
_react2['default'].createElement(
_rcAlign2['default'],
{
target: this.getAlignTarget(),
key: 'popup',
ref: this.saveAlignRef,
monitorWindowResize: true,
xVisible: visible,
childrenProps: { visible: 'xVisible' },
disabled: !visible,
align: align,
onAlign: this.onAlign
},
_react2['default'].createElement(
_PopupInner2['default'],
_extends({
hiddenClassName: hiddenClassName
}, popupInnerProps),
children
)
)
);
};
Popup.prototype.getZIndexStyle = function getZIndexStyle() {
var style = {};
var props = this.props;
if (props.zIndex !== undefined) {
style.zIndex = props.zIndex;
}
return style;
};
Popup.prototype.getMaskElement = function getMaskElement() {
var props = this.props;
var maskElement = void 0;
if (props.mask) {
var maskTransition = this.getMaskTransitionName();
maskElement = _react2['default'].createElement(_LazyRenderBox2['default'], {
style: this.getZIndexStyle(),
key: 'mask',
className: props.prefixCls + '-mask',
hiddenClassName: props.prefixCls + '-mask-hidden',
visible: props.visible
});
if (maskTransition) {
maskElement = _react2['default'].createElement(
_rcAnimate2['default'],
{
key: 'mask',
showProp: 'visible',
transitionAppear: true,
component: '',
transitionName: maskTransition
},
maskElement
);
}
}
return maskElement;
};
Popup.prototype.render = function render() {
return _react2['default'].createElement(
'div',
null,
this.getMaskElement(),
this.getPopupElement()
);
};
return Popup;
}(_react.Component);
Popup.propTypes = {
visible: _propTypes2['default'].bool,
style: _propTypes2['default'].object,
getClassNameFromAlign: _propTypes2['default'].func,
onAlign: _propTypes2['default'].func,
getRootDomNode: _propTypes2['default'].func,
align: _propTypes2['default'].any,
destroyPopupOnHide: _propTypes2['default'].bool,
className: _propTypes2['default'].string,
prefixCls: _propTypes2['default'].string,
onMouseEnter: _propTypes2['default'].func,
onMouseLeave: _propTypes2['default'].func,
onMouseDown: _propTypes2['default'].func,
onTouchStart: _propTypes2['default'].func,
stretch: _propTypes2['default'].string,
children: _propTypes2['default'].node,
point: _propTypes2['default'].shape({
pageX: _propTypes2['default'].number,
pageY: _propTypes2['default'].number
})
};
var _initialiseProps = function _initialiseProps() {
var _this3 = this;
this.onAlign = function (popupDomNode, align) {
var props = _this3.props;
var currentAlignClassName = props.getClassNameFromAlign(align);
// FIX: https://github.com/react-component/trigger/issues/56
// FIX: https://github.com/react-component/tooltip/issues/79
if (_this3.currentAlignClassName !== currentAlignClassName) {
_this3.currentAlignClassName = currentAlignClassName;
popupDomNode.className = _this3.getClassName(currentAlignClassName);
}
props.onAlign(popupDomNode, align);
};
this.setStretchSize = function () {
var _props2 = _this3.props,
stretch = _props2.stretch,
getRootDomNode = _props2.getRootDomNode,
visible = _props2.visible;
var _state2 = _this3.state,
stretchChecked = _state2.stretchChecked,
targetHeight = _state2.targetHeight,
targetWidth = _state2.targetWidth;
if (!stretch || !visible) {
if (stretchChecked) {
_this3.setState({ stretchChecked: false });
}
return;
}
var $ele = getRootDomNode();
if (!$ele) return;
var height = $ele.offsetHeight;
var width = $ele.offsetWidth;
if (targetHeight !== height || targetWidth !== width || !stretchChecked) {
_this3.setState({
stretchChecked: true,
targetHeight: height,
targetWidth: width
});
}
};
this.getTargetElement = function () {
return _this3.props.getRootDomNode();
};
this.getAlignTarget = function () {
var point = _this3.props.point;
if (point) {
return point;
}
return _this3.getTargetElement;
};
};
exports['default'] = Popup;
module.exports = exports['default'];