confirm.tsx 3.0 KB

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