Notification.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
  2. import _defineProperty from 'babel-runtime/helpers/defineProperty';
  3. import Vue from 'vue';
  4. import PropTypes from '../_util/vue-types';
  5. import { getStyle, getComponentFromProp } from '../_util/props-util';
  6. import BaseMixin from '../_util/BaseMixin';
  7. import createChainedFunction from '../_util/createChainedFunction';
  8. import getTransitionProps from '../_util/getTransitionProps';
  9. import Notice from './Notice';
  10. import Base from '../base';
  11. function noop() {}
  12. var seed = 0;
  13. var now = Date.now();
  14. function getUuid() {
  15. return 'rcNotification_' + now + '_' + seed++;
  16. }
  17. var Notification = {
  18. mixins: [BaseMixin],
  19. props: {
  20. prefixCls: PropTypes.string.def('rc-notification'),
  21. transitionName: PropTypes.string,
  22. animation: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).def('fade'),
  23. maxCount: PropTypes.number,
  24. closeIcon: PropTypes.any
  25. },
  26. data: function data() {
  27. return {
  28. notices: []
  29. };
  30. },
  31. methods: {
  32. getTransitionName: function getTransitionName() {
  33. var props = this.$props;
  34. var transitionName = props.transitionName;
  35. if (!transitionName && props.animation) {
  36. transitionName = props.prefixCls + '-' + props.animation;
  37. }
  38. return transitionName;
  39. },
  40. add: function add(notice) {
  41. var key = notice.key = notice.key || getUuid();
  42. var maxCount = this.$props.maxCount;
  43. this.setState(function (previousState) {
  44. var notices = previousState.notices;
  45. var noticeIndex = notices.map(function (v) {
  46. return v.key;
  47. }).indexOf(key);
  48. var updatedNotices = notices.concat();
  49. if (noticeIndex !== -1) {
  50. updatedNotices.splice(noticeIndex, 1, notice);
  51. } else {
  52. if (maxCount && notices.length >= maxCount) {
  53. // XXX, use key of first item to update new added (let React to move exsiting
  54. // instead of remove and mount). Same key was used before for both a) external
  55. // manual control and b) internal react 'key' prop , which is not that good.
  56. notice.updateKey = updatedNotices[0].updateKey || updatedNotices[0].key;
  57. updatedNotices.shift();
  58. }
  59. updatedNotices.push(notice);
  60. }
  61. return {
  62. notices: updatedNotices
  63. };
  64. });
  65. },
  66. remove: function remove(key) {
  67. this.setState(function (previousState) {
  68. return {
  69. notices: previousState.notices.filter(function (notice) {
  70. return notice.key !== key;
  71. })
  72. };
  73. });
  74. }
  75. },
  76. render: function render(h) {
  77. var _this = this;
  78. var prefixCls = this.prefixCls,
  79. notices = this.notices,
  80. remove = this.remove,
  81. getTransitionName = this.getTransitionName;
  82. var transitionProps = getTransitionProps(getTransitionName());
  83. var noticeNodes = notices.map(function (notice, index) {
  84. var update = Boolean(index === notices.length - 1 && notice.updateKey);
  85. var key = notice.updateKey ? notice.updateKey : notice.key;
  86. var content = notice.content,
  87. duration = notice.duration,
  88. closable = notice.closable,
  89. onClose = notice.onClose,
  90. style = notice.style,
  91. className = notice['class'];
  92. var close = createChainedFunction(remove.bind(_this, notice.key), onClose);
  93. var noticeProps = {
  94. props: {
  95. prefixCls: prefixCls,
  96. duration: duration,
  97. closable: closable,
  98. update: update,
  99. closeIcon: getComponentFromProp(_this, 'closeIcon')
  100. },
  101. on: {
  102. close: close,
  103. click: notice.onClick || noop
  104. },
  105. style: style,
  106. 'class': className,
  107. key: key
  108. };
  109. return h(
  110. Notice,
  111. noticeProps,
  112. [typeof content === 'function' ? content(h) : content]
  113. );
  114. });
  115. var className = _defineProperty({}, prefixCls, 1);
  116. var style = getStyle(this);
  117. return h(
  118. 'div',
  119. {
  120. 'class': className,
  121. style: style || {
  122. top: '65px',
  123. left: '50%'
  124. }
  125. },
  126. [h(
  127. 'transition-group',
  128. transitionProps,
  129. [noticeNodes]
  130. )]
  131. );
  132. }
  133. };
  134. Notification.newInstance = function newNotificationInstance(properties, callback) {
  135. var _ref = properties || {},
  136. getContainer = _ref.getContainer,
  137. style = _ref.style,
  138. className = _ref['class'],
  139. props = _objectWithoutProperties(_ref, ['getContainer', 'style', 'class']);
  140. var div = document.createElement('div');
  141. if (getContainer) {
  142. var root = getContainer();
  143. root.appendChild(div);
  144. } else {
  145. document.body.appendChild(div);
  146. }
  147. var V = Base.Vue || Vue;
  148. new V({
  149. el: div,
  150. mounted: function mounted() {
  151. var self = this;
  152. this.$nextTick(function () {
  153. callback({
  154. notice: function notice(noticeProps) {
  155. self.$refs.notification.add(noticeProps);
  156. },
  157. removeNotice: function removeNotice(key) {
  158. self.$refs.notification.remove(key);
  159. },
  160. component: self,
  161. destroy: function destroy() {
  162. self.$destroy();
  163. self.$el.parentNode.removeChild(self.$el);
  164. }
  165. });
  166. });
  167. },
  168. render: function render() {
  169. var h = arguments[0];
  170. var p = {
  171. props: props,
  172. ref: 'notification',
  173. style: style,
  174. 'class': className
  175. };
  176. return h(Notification, p);
  177. }
  178. });
  179. };
  180. export default Notification;