UNPKG

@alifd/next

Version:

A configurable component library for web built on React.

507 lines (436 loc) 16.8 kB
'use strict'; exports.__esModule = true; var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties'); var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _class, _temp; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactLifecyclesCompat = require('react-lifecycles-compat'); var _overlay = require('../overlay'); var _overlay2 = _interopRequireDefault(_overlay); var _util = require('../util'); var _inner = require('./inner'); var _inner2 = _interopRequireDefault(_inner); var _alignMap = require('./alignMap'); var _util2 = require('./util'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var noop = _util.func.noop; var Popup = _overlay2.default.Popup; var alignList = ['t', 'r', 'b', 'l', 'tl', 'tr', 'bl', 'br', 'lt', 'lb', 'rt', 'rb']; var alignMap = _alignMap.normalMap; /** Balloon */ var Balloon = (_temp = _class = function (_React$Component) { (0, _inherits3.default)(Balloon, _React$Component); function Balloon(props, context) { (0, _classCallCheck3.default)(this, Balloon); var _this = (0, _possibleConstructorReturn3.default)(this, _React$Component.call(this, props, context)); _this.beforePosition = function (result, obj) { var placement = result.config.placement; if (placement !== _this.state.align) { _this.setState({ align: placement, innerAlign: true }); } if (_this.props.arrowPointToCenter) { var _obj$target = obj.target, width = _obj$target.width, height = _obj$target.height; if (placement.length === 2) { var offset = _alignMap.normalMap[placement].offset; switch (placement[0]) { case 'b': case 't': { var plus = offset[0] > 0 ? 1 : -1; result.style.left = result.style.left + plus * width / 2 - offset[0]; } break; case 'l': case 'r': { var _plus = offset[0] > 0 ? 1 : -1; result.style.top = result.style.top + _plus * height / 2 - offset[1]; } break; } } } return result; }; _this.state = { align: alignList.includes(props.align) ? props.align : 'b', visible: 'visible' in props ? props.visible : props.defaultVisible }; _this._onClose = _this._onClose.bind(_this); _this._onPosition = _this._onPosition.bind(_this); _this._onVisibleChange = _this._onVisibleChange.bind(_this); return _this; } Balloon.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, prevState) { var nextState = {}; if ('visible' in nextProps) { nextState.visible = nextProps.visible; } if (!prevState.innerAlign && 'align' in nextProps && alignList.includes(nextProps.align) && nextProps.align !== prevState.align) { nextState.align = nextProps.align; nextState.innerAlign = false; } return nextState; }; Balloon.prototype._onVisibleChange = function _onVisibleChange(visible, trigger) { // Not Controlled if (!('visible' in this.props)) { this.setState({ visible: visible }); } this.props.onVisibleChange(visible, trigger); if (!visible) { this.props.onClose(); } }; Balloon.prototype._onClose = function _onClose(e) { this._onVisibleChange(false, 'closeClick'); //必须加上preventDefault,否则单测IE下报错,出现full page reload 异常 e.preventDefault(); }; Balloon.prototype._onPosition = function _onPosition(res) { var rtl = this.props.rtl; alignMap = this.props.alignEdge ? _alignMap.edgeMap : _alignMap.normalMap; var newAlign = res.align.join(' '); var resAlign = void 0; var alignKey = 'align'; if (rtl) { alignKey = 'rtlAlign'; } for (var key in alignMap) { if (alignMap[key][alignKey] === newAlign) { resAlign = key; break; } } resAlign = resAlign || this.state.align; if (resAlign !== this.state.align) { this.setState({ align: resAlign, innerAlign: true }); } }; Balloon.prototype.render = function render() { var _props = this.props, id = _props.id, type = _props.type, prefix = _props.prefix, className = _props.className, title = _props.title, alignEdge = _props.alignEdge, trigger = _props.trigger, triggerType = _props.triggerType, children = _props.children, closable = _props.closable, shouldUpdatePosition = _props.shouldUpdatePosition, delay = _props.delay, needAdjust = _props.needAdjust, autoAdjust = _props.autoAdjust, safeId = _props.safeId, autoFocus = _props.autoFocus, safeNode = _props.safeNode, onClick = _props.onClick, onHover = _props.onHover, animation = _props.animation, offset = _props.offset, style = _props.style, container = _props.container, popupContainer = _props.popupContainer, cache = _props.cache, popupStyle = _props.popupStyle, popupClassName = _props.popupClassName, popupProps = _props.popupProps, followTrigger = _props.followTrigger, rtl = _props.rtl, v2 = _props.v2, arrowPointToCenter = _props.arrowPointToCenter, _props$placementOffse = _props.placementOffset, placementOffset = _props$placementOffse === undefined ? 0 : _props$placementOffse, others = (0, _objectWithoutProperties3.default)(_props, ['id', 'type', 'prefix', 'className', 'title', 'alignEdge', 'trigger', 'triggerType', 'children', 'closable', 'shouldUpdatePosition', 'delay', 'needAdjust', 'autoAdjust', 'safeId', 'autoFocus', 'safeNode', 'onClick', 'onHover', 'animation', 'offset', 'style', 'container', 'popupContainer', 'cache', 'popupStyle', 'popupClassName', 'popupProps', 'followTrigger', 'rtl', 'v2', 'arrowPointToCenter', 'placementOffset']); if (container) { _util.log.deprecated('container', 'popupContainer', 'Balloon'); } var align = this.state.align; alignMap = alignEdge || v2 ? _alignMap.edgeMap : _alignMap.normalMap; var _prefix = this.context.prefix || prefix; var trOrigin = 'trOrigin'; if (rtl) { trOrigin = 'rtlTrOrigin'; } var _offset = [alignMap[align].offset[0] + offset[0], alignMap[align].offset[1] + offset[1]]; var transformOrigin = alignMap[align][trOrigin]; var _style = (0, _extends3.default)({ transformOrigin: transformOrigin }, style); var content = _react2.default.createElement( _inner2.default, (0, _extends3.default)({}, _util.obj.pickOthers(Object.keys(Balloon.propTypes), others), { id: id, title: title, prefix: _prefix, closable: closable, onClose: this._onClose, className: className, style: _style, align: align, type: type, rtl: rtl, alignEdge: alignEdge, v2: v2 }), children ); var triggerProps = {}; triggerProps['aria-describedby'] = id; triggerProps.tabIndex = '0'; var ariaTrigger = id ? _react2.default.cloneElement(trigger, triggerProps) : trigger; var newTrigger = (0, _util2.getDisabledCompatibleTrigger)(_react2.default.isValidElement(ariaTrigger) ? ariaTrigger : _react2.default.createElement( 'span', null, ariaTrigger )); var otherProps = { delay: delay, shouldUpdatePosition: shouldUpdatePosition, needAdjust: needAdjust, align: alignMap[align].align, offset: _offset, safeId: safeId, onHover: onHover, onPosition: this._onPosition }; if (v2) { delete otherProps.align; delete otherProps.shouldUpdatePosition; delete otherProps.needAdjust; delete otherProps.offset; delete otherProps.safeId; delete otherProps.onHover; delete otherProps.onPosition; (0, _extends3.default)(otherProps, { placement: align, placementOffset: placementOffset + 12, v2: true, beforePosition: this.beforePosition, autoAdjust: autoAdjust }); } return _react2.default.createElement( Popup, (0, _extends3.default)({}, popupProps, { followTrigger: followTrigger, trigger: newTrigger, cache: cache, triggerType: triggerType, visible: this.state.visible, onClick: onClick, afterClose: this.props.afterClose, onVisibleChange: this._onVisibleChange, animation: animation, autoFocus: triggerType === 'focus' ? false : autoFocus, safeNode: safeNode, container: popupContainer || container, className: popupClassName, style: popupStyle, rtl: rtl }, otherProps), content ); }; return Balloon; }(_react2.default.Component), _class.contextTypes = { prefix: _propTypes2.default.string }, _class.propTypes = { prefix: _propTypes2.default.string, pure: _propTypes2.default.bool, rtl: _propTypes2.default.bool, /** * 自定义类名 */ className: _propTypes2.default.string, /** * 自定义内敛样式 */ style: _propTypes2.default.object, /** * 浮层的内容 */ children: _propTypes2.default.any, size: _propTypes2.default.string, /** * 样式类型 */ type: _propTypes2.default.oneOf(['normal', 'primary']), /** * 标题 * @version 1.23 */ title: _propTypes2.default.node, /** * 弹层当前显示的状态 */ visible: _propTypes2.default.bool, /** * 弹层默认显示的状态 */ defaultVisible: _propTypes2.default.bool, /** * 弹层在显示和隐藏触发的事件 * @param {Boolean} visible 弹层是否隐藏和显示 * @param {String} type 触发弹层显示或隐藏的来源, closeClick 表示由自带的关闭按钮触发; fromTrigger 表示由trigger的点击触发; docClick 表示由document的点击触发 */ onVisibleChange: _propTypes2.default.func, alignEdge: _propTypes2.default.bool, /** * 开启 v2 版本 * @version 1.25 */ v2: _propTypes2.default.bool, /** * [v2] 箭头是否指向目标元素的中心 * @version 1.25 */ arrowPointToCenter: _propTypes2.default.bool, /** * [v2] 弹层偏离触发元素的像素值 */ placementOffset: _propTypes2.default.number, /** * 是否显示关闭按钮 */ closable: _propTypes2.default.bool, /** * 弹出层位置 * @enumdesc 上, 右, 下, 左, 上左, 上右, 下左, 下右, 左上, 左下, 右上, 右下 */ align: _propTypes2.default.oneOf(alignList), /** * 弹层相对于trigger的定位的微调, 接收数组[hoz, ver], 表示弹层在 left / top 上的增量 * e.g. [100, 100] 表示往右(RTL 模式下是往左) 、下分布偏移100px */ offset: _propTypes2.default.array, /** * 触发元素 */ trigger: _propTypes2.default.any, /** * 触发行为 * 鼠标悬浮, 鼠标点击('hover','click')或者它们组成的数组,如 ['hover', 'click'], 强烈不建议使用'focus',若弹窗内容有复杂交互请使用click */ triggerType: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.array]), onClick: _propTypes2.default.func, /** * 任何visible为false时会触发的事件 */ onClose: _propTypes2.default.func, onHover: _propTypes2.default.func, /** * [v2] 是否进行自动位置调整,默认自动开启。 * @version 1.25 */ autoAdjust: _propTypes2.default.bool, needAdjust: _propTypes2.default.bool, /** * 弹层在触发以后的延时显示, 单位毫秒 ms */ delay: _propTypes2.default.number, /** * 浮层关闭后触发的事件, 如果有动画,则在动画结束后触发 */ afterClose: _propTypes2.default.func, shouldUpdatePosition: _propTypes2.default.bool, /** * 弹层出现后是否自动focus到内部第一个元素 */ autoFocus: _propTypes2.default.bool, /** * 安全节点:对于triggetType为click的浮层,会在点击除了浮层外的其它区域时关闭浮层.safeNode用于添加不触发关闭的节点, 值可以是dom节点的id或者是节点的dom对象 */ safeNode: _propTypes2.default.string, /** * 用来指定safeNode节点的id,和safeNode配合使用 */ safeId: _propTypes2.default.string, /** * 配置动画的播放方式,格式是{in: '', out: ''}, 常用的动画class请查看Animate组件文档 * @param {String} in 进场动画 * @param {String} out 出场动画 */ animation: _propTypes2.default.oneOfType([_propTypes2.default.object, _propTypes2.default.bool]), /** * 弹层的dom节点关闭时是否删除 */ cache: _propTypes2.default.bool, /** * 指定浮层渲染的父节点, 可以为节点id的字符串,也可以返回节点的函数。 */ popupContainer: _propTypes2.default.any, container: _propTypes2.default.any, /** * 弹层组件style,透传给Popup */ popupStyle: _propTypes2.default.object, /** * 弹层组件className,透传给Popup */ popupClassName: _propTypes2.default.string, /** * 弹层组件属性,透传给Popup */ popupProps: _propTypes2.default.object, /** * 是否跟随滚动 */ followTrigger: _propTypes2.default.bool, /** * 弹层id, 传入值才会支持无障碍 */ id: _propTypes2.default.string }, _class.defaultProps = { prefix: 'next-', pure: false, type: 'normal', closable: true, defaultVisible: false, size: 'medium', alignEdge: false, arrowPointToCenter: false, align: 'b', offset: [0, 0], trigger: _react2.default.createElement('span', null), onClose: noop, afterClose: noop, onVisibleChange: noop, needAdjust: false, triggerType: 'hover', safeNode: undefined, safeId: null, autoFocus: true, animation: { in: 'zoomIn zoomInBig', out: 'zoomOut zoomOutBig' }, cache: false, popupStyle: {}, popupClassName: '', popupProps: {} }, _temp); Balloon.displayName = 'Balloon'; exports.default = (0, _reactLifecyclesCompat.polyfill)(Balloon); module.exports = exports['default'];