Notification.js 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. exports.default = void 0;
  7. var _vue = require("vue");
  8. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  9. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  10. var _transition = require("../_util/transition");
  11. var _Notice = _interopRequireDefault(require("./Notice"));
  12. var _configProvider = _interopRequireWildcard(require("../config-provider"));
  13. var _classNames = _interopRequireDefault(require("../_util/classNames"));
  14. function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
  15. function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
  16. var __rest = void 0 && (void 0).__rest || function (s, e) {
  17. var t = {};
  18. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  19. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  20. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  21. }
  22. return t;
  23. };
  24. let seed = 0;
  25. const now = Date.now();
  26. function getUuid() {
  27. const id = seed;
  28. seed += 1;
  29. return `rcNotification_${now}_${id}`;
  30. }
  31. const Notification = (0, _vue.defineComponent)({
  32. name: 'Notification',
  33. inheritAttrs: false,
  34. props: ['prefixCls', 'transitionName', 'animation', 'maxCount', 'closeIcon', 'hashId'],
  35. setup(props, _ref) {
  36. let {
  37. attrs,
  38. expose,
  39. slots
  40. } = _ref;
  41. const hookRefs = new Map();
  42. const notices = (0, _vue.ref)([]);
  43. const transitionProps = (0, _vue.computed)(() => {
  44. const {
  45. prefixCls,
  46. animation = 'fade'
  47. } = props;
  48. let name = props.transitionName;
  49. if (!name && animation) {
  50. name = `${prefixCls}-${animation}`;
  51. }
  52. return (0, _transition.getTransitionGroupProps)(name);
  53. });
  54. const add = (originNotice, holderCallback) => {
  55. const key = originNotice.key || getUuid();
  56. const notice = (0, _extends2.default)((0, _extends2.default)({}, originNotice), {
  57. key
  58. });
  59. const {
  60. maxCount
  61. } = props;
  62. const noticeIndex = notices.value.map(v => v.notice.key).indexOf(key);
  63. const updatedNotices = notices.value.concat();
  64. if (noticeIndex !== -1) {
  65. updatedNotices.splice(noticeIndex, 1, {
  66. notice,
  67. holderCallback
  68. });
  69. } else {
  70. if (maxCount && notices.value.length >= maxCount) {
  71. // XXX, use key of first item to update new added (let React to move exsiting
  72. // instead of remove and mount). Same key was used before for both a) external
  73. // manual control and b) internal react 'key' prop , which is not that good.
  74. // eslint-disable-next-line no-param-reassign
  75. // zombieJ: Not know why use `updateKey`. This makes Notice infinite loop in jest.
  76. // Change to `updateMark` for compare instead.
  77. // https://github.com/react-component/notification/commit/32299e6be396f94040bfa82517eea940db947ece
  78. notice.key = updatedNotices[0].notice.key;
  79. notice.updateMark = getUuid();
  80. // zombieJ: That's why. User may close by key directly.
  81. // We need record this but not re-render to avoid upper issue
  82. // https://github.com/react-component/notification/issues/129
  83. notice.userPassKey = key;
  84. updatedNotices.shift();
  85. }
  86. updatedNotices.push({
  87. notice,
  88. holderCallback
  89. });
  90. }
  91. notices.value = updatedNotices;
  92. };
  93. const remove = removeKey => {
  94. notices.value = notices.value.filter(_ref2 => {
  95. let {
  96. notice: {
  97. key,
  98. userPassKey
  99. }
  100. } = _ref2;
  101. const mergedKey = userPassKey || key;
  102. return mergedKey !== removeKey;
  103. });
  104. };
  105. expose({
  106. add,
  107. remove,
  108. notices
  109. });
  110. return () => {
  111. var _a;
  112. const {
  113. prefixCls,
  114. closeIcon = (_a = slots.closeIcon) === null || _a === void 0 ? void 0 : _a.call(slots, {
  115. prefixCls
  116. })
  117. } = props;
  118. const noticeNodes = notices.value.map((_ref3, index) => {
  119. let {
  120. notice,
  121. holderCallback
  122. } = _ref3;
  123. const updateMark = index === notices.value.length - 1 ? notice.updateMark : undefined;
  124. const {
  125. key,
  126. userPassKey
  127. } = notice;
  128. const {
  129. content
  130. } = notice;
  131. const noticeProps = (0, _extends2.default)((0, _extends2.default)((0, _extends2.default)({
  132. prefixCls,
  133. closeIcon: typeof closeIcon === 'function' ? closeIcon({
  134. prefixCls
  135. }) : closeIcon
  136. }, notice), notice.props), {
  137. key,
  138. noticeKey: userPassKey || key,
  139. updateMark,
  140. onClose: noticeKey => {
  141. var _a;
  142. remove(noticeKey);
  143. (_a = notice.onClose) === null || _a === void 0 ? void 0 : _a.call(notice);
  144. },
  145. onClick: notice.onClick
  146. });
  147. if (holderCallback) {
  148. return (0, _vue.createVNode)("div", {
  149. "key": key,
  150. "class": `${prefixCls}-hook-holder`,
  151. "ref": div => {
  152. if (typeof key === 'undefined') {
  153. return;
  154. }
  155. if (div) {
  156. hookRefs.set(key, div);
  157. holderCallback(div, noticeProps);
  158. } else {
  159. hookRefs.delete(key);
  160. }
  161. }
  162. }, null);
  163. }
  164. return (0, _vue.createVNode)(_Notice.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, noticeProps), {}, {
  165. "class": (0, _classNames.default)(noticeProps.class, props.hashId)
  166. }), {
  167. default: () => [typeof content === 'function' ? content({
  168. prefixCls
  169. }) : content]
  170. });
  171. });
  172. const className = {
  173. [prefixCls]: 1,
  174. [attrs.class]: !!attrs.class,
  175. [props.hashId]: true
  176. };
  177. return (0, _vue.createVNode)("div", {
  178. "class": className,
  179. "style": attrs.style || {
  180. top: '65px',
  181. left: '50%'
  182. }
  183. }, [(0, _vue.createVNode)(_vue.TransitionGroup, (0, _objectSpread2.default)({
  184. "tag": "div"
  185. }, transitionProps.value), {
  186. default: () => [noticeNodes]
  187. })]);
  188. };
  189. }
  190. });
  191. Notification.newInstance = function newNotificationInstance(properties, callback) {
  192. const _a = properties || {},
  193. {
  194. name = 'notification',
  195. getContainer,
  196. appContext,
  197. prefixCls: customizePrefixCls,
  198. rootPrefixCls: customRootPrefixCls,
  199. transitionName: customTransitionName,
  200. hasTransitionName,
  201. useStyle
  202. } = _a,
  203. props = __rest(_a, ["name", "getContainer", "appContext", "prefixCls", "rootPrefixCls", "transitionName", "hasTransitionName", "useStyle"]);
  204. const div = document.createElement('div');
  205. if (getContainer) {
  206. const root = getContainer();
  207. root.appendChild(div);
  208. } else {
  209. document.body.appendChild(div);
  210. }
  211. const Wrapper = (0, _vue.defineComponent)({
  212. compatConfig: {
  213. MODE: 3
  214. },
  215. name: 'NotificationWrapper',
  216. setup(_props, _ref4) {
  217. let {
  218. attrs
  219. } = _ref4;
  220. const notiRef = (0, _vue.shallowRef)();
  221. const prefixCls = (0, _vue.computed)(() => _configProvider.globalConfigForApi.getPrefixCls(name, customizePrefixCls));
  222. const [, hashId] = useStyle(prefixCls);
  223. (0, _vue.onMounted)(() => {
  224. callback({
  225. notice(noticeProps) {
  226. var _a;
  227. (_a = notiRef.value) === null || _a === void 0 ? void 0 : _a.add(noticeProps);
  228. },
  229. removeNotice(key) {
  230. var _a;
  231. (_a = notiRef.value) === null || _a === void 0 ? void 0 : _a.remove(key);
  232. },
  233. destroy() {
  234. (0, _vue.render)(null, div);
  235. if (div.parentNode) {
  236. div.parentNode.removeChild(div);
  237. }
  238. },
  239. component: notiRef
  240. });
  241. });
  242. return () => {
  243. const global = _configProvider.globalConfigForApi;
  244. const rootPrefixCls = global.getRootPrefixCls(customRootPrefixCls, prefixCls.value);
  245. const transitionName = hasTransitionName ? customTransitionName : `${prefixCls.value}-${customTransitionName}`;
  246. return (0, _vue.createVNode)(_configProvider.default, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, global), {}, {
  247. "prefixCls": rootPrefixCls
  248. }), {
  249. default: () => [(0, _vue.createVNode)(Notification, (0, _objectSpread2.default)((0, _objectSpread2.default)({
  250. "ref": notiRef
  251. }, attrs), {}, {
  252. "prefixCls": prefixCls.value,
  253. "transitionName": transitionName,
  254. "hashId": hashId.value
  255. }), null)]
  256. });
  257. };
  258. }
  259. });
  260. const vm = (0, _vue.createVNode)(Wrapper, props);
  261. vm.appContext = appContext || vm.appContext;
  262. (0, _vue.render)(vm, div);
  263. };
  264. var _default = exports.default = Notification;