confirm.tsx 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 { IconAlertCircle, IconAlertTriangle, IconHelpCircle, IconInfoCircle, IconTickCircle } from '@douyinfe/semi-icons';
  7. import { omit } from "lodash";
  8. import { type ButtonProps } from "../button";
  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. if (fn === close) {
  25. destroyFns.splice(i, 1);
  26. break;
  27. }
  28. }
  29. };
  30. function render(renderProps: ConfirmProps) {
  31. const { afterClose } = renderProps;
  32. //@ts-ignore
  33. ReactDOM.render(<ConfirmModal {...renderProps} afterClose={(...args: any) => {
  34. //@ts-ignore
  35. afterClose?.(...args);
  36. destroy();
  37. }} motion={props.motion}/>, div);
  38. }
  39. function close() {
  40. currentConfig = {
  41. ...currentConfig,
  42. visible: false,
  43. };
  44. render(currentConfig);
  45. }
  46. function update(newConfig: T extends { type: Exclude<ConfirmProps['type'], 'confirm'> } ? ModalReactProps : ConfirmProps) {
  47. currentConfig = {
  48. ...currentConfig,
  49. ...newConfig,
  50. };
  51. render(currentConfig);
  52. }
  53. render(currentConfig);
  54. destroyFns.push(close);
  55. return {
  56. destroy: close,
  57. update,
  58. };
  59. }
  60. export function withInfo(props: ModalReactProps) {
  61. return {
  62. type: 'info' as const,
  63. icon: <IconInfoCircle/>,
  64. ...props
  65. };
  66. }
  67. export function withSuccess(props: ModalReactProps) {
  68. return {
  69. type: 'success' as const,
  70. icon: <IconTickCircle/>,
  71. ...props
  72. };
  73. }
  74. export function withWarning(props: ModalReactProps) {
  75. return {
  76. type: 'warning' as const,
  77. icon: <IconAlertTriangle/>,
  78. ...props
  79. };
  80. }
  81. export function withError(props: ModalReactProps) {
  82. return {
  83. type: 'error' as const,
  84. icon: <IconAlertCircle/>,
  85. okButtonProps: { type: 'danger' as ButtonProps['type'], ...props.okButtonProps },
  86. ...(omit(props, ['okButtonProps']))
  87. };
  88. }
  89. export function withConfirm(props: ModalReactProps) {
  90. return {
  91. type: 'confirm' as const,
  92. icon: <IconHelpCircle/>,
  93. ...props
  94. };
  95. }