choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
317 lines (278 loc) • 9.88 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _createSuper from "@babel/runtime/helpers/createSuper";
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["getContainer"];
import React, { PureComponent } from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
import classNames from 'classnames';
import { NotificationManager } from 'choerodon-ui/shared';
import noop from 'lodash/noop';
import debounce from 'lodash/debounce';
import scrollIntoView from 'scroll-into-view-if-needed';
import Animate from '../animate';
import Notice from './Notice';
import { getNoticeLocale } from './locale';
import EventManager from '../_util/EventManager';
import { getStyle } from '../rc-components/util/Dom/css';
export function newNotificationInstance(properties, callback) {
var _ref = properties || {},
getContainer = _ref.getContainer,
props = _objectWithoutProperties(_ref, _excluded);
var div = document.createElement('div');
if (getContainer) {
var root = getContainer();
root.appendChild(div);
} else {
document.body.appendChild(div);
}
var called = false;
function ref(notification) {
if (called) {
return;
}
called = true;
callback({
notice: function notice(noticeProps) {
notification.add(noticeProps);
},
removeNotice: function removeNotice(key) {
notification.remove(key);
},
destroy: function destroy() {
unmountComponentAtNode(div);
var parentNode = div.parentNode;
if (parentNode) {
parentNode.removeChild(div);
}
}
});
}
render( /*#__PURE__*/React.createElement(Notification, _extends({}, props, {
ref: ref
})), div);
}
var Notification = /*#__PURE__*/function (_PureComponent) {
_inherits(Notification, _PureComponent);
var _super = _createSuper(Notification);
function Notification() {
var _this;
_classCallCheck(this, Notification);
_this = _super.apply(this, arguments);
_this.scrollRef = null;
_this.state = {
notices: [],
scrollHeight: 'auto',
totalHeight: 0,
offset: 0
};
_this.onAnimateEnd = function () {
var notices = _this.state.notices;
var foldCount = _this.props.foldCount;
if (foldCount) {
var _assertThisInitialize = _assertThisInitialized(_this),
scrollRef = _assertThisInitialize.scrollRef;
if (scrollRef) {
var childSpan = scrollRef.firstChild;
if (!childSpan) return;
var childNodes = childSpan.childNodes;
var lastNode = childNodes[childNodes.length - 1];
if (childNodes.length > foldCount && notices.length > foldCount) {
var totalHeight = 0;
for (var i = 0; i < childNodes.length; i += 1) {
var element = childNodes[i];
totalHeight += element.offsetHeight + getStyle(element, 'margin-bottom');
}
var scrollHeight = totalHeight / childNodes.length * (foldCount + 0.5);
_this.setState({
scrollHeight: scrollHeight,
totalHeight: totalHeight
}, function () {
if (!_this.isRemove) {
scrollIntoView(lastNode, {
block: 'center',
behavior: 'smooth',
scrollMode: 'if-needed',
boundary: scrollRef
});
}
});
} else {
_this.setState({
scrollHeight: 'auto'
});
}
}
}
};
_this.clearNotices = function () {
_this.setState({
notices: []
});
};
_this.handleNoticeClose = function (eventKey) {
var notices = _this.state.notices;
var notice = notices.find(function (_ref2) {
var key = _ref2.key;
return key === eventKey;
});
_this.remove(eventKey);
if (notice) {
var _notice$onClose = notice.onClose,
onClose = _notice$onClose === void 0 ? noop : _notice$onClose;
onClose(eventKey);
}
};
_this.saveScrollRef = function (dom) {
_this.scrollRef = dom;
if (dom) {
var debouncedResize = debounce(function (e) {
_this.setState({
offset: e.target.scrollTop
});
}, 200);
_this.scrollEvent = new EventManager(dom).addEventListener('scroll', debouncedResize);
} else {
_this.dispose();
}
};
return _this;
}
_createClass(Notification, [{
key: "dispose",
value: function dispose() {
var scrollEvent = this.scrollEvent;
if (scrollEvent) {
scrollEvent.clear();
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.dispose();
}
}, {
key: "getTransitionName",
value: function getTransitionName() {
var _this$props = this.props,
transitionName = _this$props.transitionName,
animation = _this$props.animation,
prefixCls = _this$props.prefixCls;
if (!transitionName && animation) {
return "".concat(prefixCls, "-").concat(animation);
}
return transitionName;
}
}, {
key: "add",
value: function add(notice) {
var _this2 = this;
if (!notice.key) {
notice.key = NotificationManager.getUuid();
}
var key = notice.key;
var maxCount = this.props.maxCount;
this.setState(function (previousState) {
var notices = previousState.notices;
if (!notices.filter(function (v) {
return v.key === key;
}).length) {
if (maxCount && notices && notices.length > 0 && notices.length >= maxCount) {
notices.shift();
}
_this2.isRemove = false;
return _objectSpread(_objectSpread({}, previousState), {}, {
notices: notices.concat(notice)
});
}
});
}
}, {
key: "remove",
value: function remove(key) {
var _this3 = this;
this.setState(function (previousState) {
_this3.isRemove = true;
var notices = previousState.notices.filter(function (notice) {
return notice.key !== key;
});
return {
notices: notices
};
});
}
}, {
key: "render",
value: function render() {
var _this4 = this,
_ref3;
var _this$state = this.state,
notices = _this$state.notices,
scrollHeight = _this$state.scrollHeight,
offset = _this$state.offset,
totalHeight = _this$state.totalHeight;
var _this$props2 = this.props,
contentClassName = _this$props2.contentClassName,
prefixCls = _this$props2.prefixCls,
closeIcon = _this$props2.closeIcon,
className = _this$props2.className,
style = _this$props2.style,
foldCount = _this$props2.foldCount;
var noticeNodes = notices.map(function (notice) {
return /*#__PURE__*/React.createElement(Notice, _extends({
prefixCls: prefixCls,
contentClassName: contentClassName
}, notice, {
onClose: _this4.handleNoticeClose,
closeIcon: closeIcon,
key: notice.key,
eventKey: notice.key,
foldable: !!foldCount,
offset: offset,
scrollHeight: scrollHeight,
totalHeight: totalHeight
}));
});
var cls = classNames("".concat(prefixCls), className, [(_ref3 = {}, _defineProperty(_ref3, "".concat(prefixCls, "-before-shadow"), !!foldCount && notices.length > foldCount && offset > 0), _defineProperty(_ref3, "".concat(prefixCls, "-after-shadow"), foldCount && notices.length > foldCount && totalHeight - (typeof scrollHeight === 'number' ? scrollHeight : 0) - offset > 15), _ref3)]);
var scrollCls = classNames(_defineProperty({}, "".concat(prefixCls, "-scroll"), !!foldCount && scrollHeight !== 'auto'));
var runtimeLocale = getNoticeLocale();
return /*#__PURE__*/React.createElement("div", {
className: cls,
style: style
}, /*#__PURE__*/React.createElement("div", {
className: scrollCls,
style: foldCount ? {
height: scrollHeight
} : undefined,
ref: foldCount ? this.saveScrollRef : undefined
}, /*#__PURE__*/React.createElement(Animate, {
onEnd: this.onAnimateEnd,
transitionName: this.getTransitionName()
}, noticeNodes)), foldCount && notices.length > foldCount && /*#__PURE__*/React.createElement("div", {
className: "".concat(prefixCls, "-alert")
}, /*#__PURE__*/React.createElement("div", {
className: "".concat(prefixCls, "-alert-message")
}, "".concat(runtimeLocale.total, " ").concat(notices.length, " ").concat(runtimeLocale.message)), /*#__PURE__*/React.createElement("div", {
className: "".concat(prefixCls, "-alert-close"),
onClick: this.clearNotices
}, "".concat(runtimeLocale.closeAll))));
}
}]);
return Notification;
}(PureComponent);
export { Notification as default };
Notification.defaultProps = {
prefixCls: 'c7n-notification',
animation: 'fade',
style: {
top: 65,
left: '50%'
}
};
Notification.newInstance = newNotificationInstance;
//# sourceMappingURL=Notification.js.map