UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

317 lines (278 loc) 9.88 kB
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