confirm.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import React from 'react';
  2. import ReactDOM from 'react-dom';
  3. import { destroyFns, ModalReactProps } from './Modal';
  4. import ConfirmModal from './ConfirmModal';
  5. import '@douyinfe/semi-foundation/modal/modal.scss';
  6. import { get } from 'lodash';
  7. import { IconAlertCircle, IconAlertTriangle, IconHelpCircle, IconInfoCircle, IconTickCircle } from '@douyinfe/semi-icons';
  8. import { Motion } from '../_base/base';
  9. export interface ConfirmProps extends ModalReactProps {
  10. type: 'success' | 'info' | 'warning' | 'error' | 'confirm';
  11. }
  12. export default function confirm<T>(props: ConfirmProps) {
  13. // create a dom in adapter?
  14. const div = document.createElement('div');
  15. document.body.appendChild(div);
  16. let currentConfig = { ...props };
  17. const destroy = () => {
  18. const unmountResult = ReactDOM.unmountComponentAtNode(div);
  19. if (unmountResult && div.parentNode) {
  20. div.parentNode.removeChild(div);
  21. }
  22. for (let i = 0; i < destroyFns.length; i++) {
  23. const fn = destroyFns[i];
  24. // eslint-disable-next-line @typescript-eslint/no-use-before-define
  25. if (fn === close) {
  26. destroyFns.splice(i, 1);
  27. break;
  28. }
  29. }
  30. };
  31. const mergedMotion: Motion = typeof (props.motion) === 'undefined' || props.motion ? {
  32. ...(props.motion as any),
  33. didLeave: (...args: any) => {
  34. const didLeave = get(props.motion, 'didLeave');
  35. if (typeof didLeave === 'function') {
  36. didLeave(...args);
  37. }
  38. destroy();
  39. }
  40. } : false;
  41. function render(renderProps: ConfirmProps) {
  42. ReactDOM.render(<ConfirmModal {...renderProps} motion={mergedMotion}/>, div);
  43. }
  44. function close() {
  45. currentConfig = {
  46. ...currentConfig,
  47. visible: false,
  48. };
  49. render(currentConfig);
  50. }
  51. function update(newConfig: T extends { type: Exclude<ConfirmProps['type'], 'confirm'> } ? ModalReactProps : ConfirmProps) {
  52. currentConfig = {
  53. ...currentConfig,
  54. ...newConfig,
  55. };
  56. render(currentConfig);
  57. }
  58. render(currentConfig);
  59. destroyFns.push(close);
  60. return {
  61. destroy: close,
  62. update,
  63. };
  64. }
  65. export function withInfo(props: ModalReactProps) {
  66. return {
  67. type: 'info' as const,
  68. icon: <IconInfoCircle/>,
  69. ...props
  70. };
  71. }
  72. export function withSuccess(props: ModalReactProps) {
  73. return {
  74. type: 'success' as const,
  75. icon: <IconTickCircle/>,
  76. ...props
  77. };
  78. }
  79. export function withWarning(props: ModalReactProps) {
  80. return {
  81. type: 'warning' as const,
  82. icon: <IconAlertTriangle/>,
  83. ...props
  84. };
  85. }
  86. export function withError(props: ModalReactProps) {
  87. return {
  88. type: 'error' as const,
  89. icon: <IconAlertCircle/>,
  90. ...props
  91. };
  92. }
  93. export function withConfirm(props: ModalReactProps) {
  94. return {
  95. type: 'confirm' as const,
  96. icon: <IconHelpCircle/>,
  97. ...props
  98. };
  99. }