Notifications.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
  3. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  4. import * as React from 'react';
  5. import { createPortal } from 'react-dom';
  6. import NoticeList from "./NoticeList";
  7. // ant-notification ant-notification-topRight
  8. var Notifications = /*#__PURE__*/React.forwardRef(function (props, ref) {
  9. var _props$prefixCls = props.prefixCls,
  10. prefixCls = _props$prefixCls === void 0 ? 'rc-notification' : _props$prefixCls,
  11. container = props.container,
  12. motion = props.motion,
  13. maxCount = props.maxCount,
  14. className = props.className,
  15. style = props.style,
  16. onAllRemoved = props.onAllRemoved,
  17. stack = props.stack,
  18. renderNotifications = props.renderNotifications;
  19. var _React$useState = React.useState([]),
  20. _React$useState2 = _slicedToArray(_React$useState, 2),
  21. configList = _React$useState2[0],
  22. setConfigList = _React$useState2[1];
  23. // ======================== Close =========================
  24. var onNoticeClose = function onNoticeClose(key) {
  25. var _config$onClose;
  26. // Trigger close event
  27. var config = configList.find(function (item) {
  28. return item.key === key;
  29. });
  30. config === null || config === void 0 || (_config$onClose = config.onClose) === null || _config$onClose === void 0 || _config$onClose.call(config);
  31. setConfigList(function (list) {
  32. return list.filter(function (item) {
  33. return item.key !== key;
  34. });
  35. });
  36. };
  37. // ========================= Refs =========================
  38. React.useImperativeHandle(ref, function () {
  39. return {
  40. open: function open(config) {
  41. setConfigList(function (list) {
  42. var clone = _toConsumableArray(list);
  43. // Replace if exist
  44. var index = clone.findIndex(function (item) {
  45. return item.key === config.key;
  46. });
  47. var innerConfig = _objectSpread({}, config);
  48. if (index >= 0) {
  49. var _list$index;
  50. innerConfig.times = (((_list$index = list[index]) === null || _list$index === void 0 ? void 0 : _list$index.times) || 0) + 1;
  51. clone[index] = innerConfig;
  52. } else {
  53. innerConfig.times = 0;
  54. clone.push(innerConfig);
  55. }
  56. if (maxCount > 0 && clone.length > maxCount) {
  57. clone = clone.slice(-maxCount);
  58. }
  59. return clone;
  60. });
  61. },
  62. close: function close(key) {
  63. onNoticeClose(key);
  64. },
  65. destroy: function destroy() {
  66. setConfigList([]);
  67. }
  68. };
  69. });
  70. // ====================== Placements ======================
  71. var _React$useState3 = React.useState({}),
  72. _React$useState4 = _slicedToArray(_React$useState3, 2),
  73. placements = _React$useState4[0],
  74. setPlacements = _React$useState4[1];
  75. React.useEffect(function () {
  76. var nextPlacements = {};
  77. configList.forEach(function (config) {
  78. var _config$placement = config.placement,
  79. placement = _config$placement === void 0 ? 'topRight' : _config$placement;
  80. if (placement) {
  81. nextPlacements[placement] = nextPlacements[placement] || [];
  82. nextPlacements[placement].push(config);
  83. }
  84. });
  85. // Fill exist placements to avoid empty list causing remove without motion
  86. Object.keys(placements).forEach(function (placement) {
  87. nextPlacements[placement] = nextPlacements[placement] || [];
  88. });
  89. setPlacements(nextPlacements);
  90. }, [configList]);
  91. // Clean up container if all notices fade out
  92. var onAllNoticeRemoved = function onAllNoticeRemoved(placement) {
  93. setPlacements(function (originPlacements) {
  94. var clone = _objectSpread({}, originPlacements);
  95. var list = clone[placement] || [];
  96. if (!list.length) {
  97. delete clone[placement];
  98. }
  99. return clone;
  100. });
  101. };
  102. // Effect tell that placements is empty now
  103. var emptyRef = React.useRef(false);
  104. React.useEffect(function () {
  105. if (Object.keys(placements).length > 0) {
  106. emptyRef.current = true;
  107. } else if (emptyRef.current) {
  108. // Trigger only when from exist to empty
  109. onAllRemoved === null || onAllRemoved === void 0 || onAllRemoved();
  110. emptyRef.current = false;
  111. }
  112. }, [placements]);
  113. // ======================== Render ========================
  114. if (!container) {
  115. return null;
  116. }
  117. var placementList = Object.keys(placements);
  118. return /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement(React.Fragment, null, placementList.map(function (placement) {
  119. var placementConfigList = placements[placement];
  120. var list = /*#__PURE__*/React.createElement(NoticeList, {
  121. key: placement,
  122. configList: placementConfigList,
  123. placement: placement,
  124. prefixCls: prefixCls,
  125. className: className === null || className === void 0 ? void 0 : className(placement),
  126. style: style === null || style === void 0 ? void 0 : style(placement),
  127. motion: motion,
  128. onNoticeClose: onNoticeClose,
  129. onAllNoticeRemoved: onAllNoticeRemoved,
  130. stack: stack
  131. });
  132. return renderNotifications ? renderNotifications(list, {
  133. prefixCls: prefixCls,
  134. key: placement
  135. }) : list;
  136. })), container);
  137. });
  138. if (process.env.NODE_ENV !== 'production') {
  139. Notifications.displayName = 'Notifications';
  140. }
  141. export default Notifications;