ConfirmModal.tsx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. /* eslint-disable react/destructuring-assignment */
  2. /* eslint-disable eqeqeq */
  3. import React, { useState, useCallback } from 'react';
  4. import cls from 'classnames';
  5. import { cssClasses } from '@douyinfe/semi-foundation/modal/constants';
  6. import Modal from './Modal';
  7. import { isSemiIcon } from '../_utils';
  8. import '@douyinfe/semi-foundation/modal/modal.scss';
  9. import { ConfirmProps } from './confirm';
  10. const ConfirmModal = (props: ConfirmProps) => {
  11. const [visible, setVisible] = useState<boolean>(true);
  12. const [confirmLoading, setConfirmLoading] = useState<boolean>();
  13. const [cancelLoading, setCancelLoading] = useState<boolean>();
  14. const { direction } = props;
  15. const { title, content, icon, type, onCancel, onOk, className, ...rest } = props;
  16. const handleOk = useCallback(
  17. (e: React.MouseEvent) => {
  18. const res = onOk && onOk(e);
  19. if (res && res.then) {
  20. setConfirmLoading(true);
  21. res.then(
  22. (...args) => {
  23. setVisible(false);
  24. setConfirmLoading(false);
  25. },
  26. err => {
  27. setConfirmLoading(false);
  28. }
  29. );
  30. } else {
  31. setVisible(false);
  32. }
  33. },
  34. [onOk]
  35. );
  36. const handleCancel = useCallback(
  37. e => {
  38. const res = onCancel && onCancel(e);
  39. if (res && res.then) {
  40. setCancelLoading(true);
  41. res.then(
  42. (...args) => {
  43. setVisible(false);
  44. setCancelLoading(false);
  45. },
  46. err => {
  47. setCancelLoading(false);
  48. }
  49. );
  50. } else {
  51. setVisible(false);
  52. }
  53. },
  54. [onCancel]
  55. );
  56. const confirmCls = `${cssClasses.DIALOG}-confirm`;
  57. const wrapperCls = cls(className, confirmCls, {
  58. [`${confirmCls}-rtl`]: direction === 'rtl',
  59. });
  60. const typeCls = cls(`${cssClasses.DIALOG}-${type}`);
  61. const iconNode = isSemiIcon(icon) ? React.cloneElement(icon as any, { className: `${confirmCls}-icon ${typeCls}-icon`, size: 'extra-large' }) : icon;
  62. const titleNode = title == null ? null : <span className={`${confirmCls}-title-text`}>{title}</span>;
  63. const contentCls = cls(`${confirmCls}-content`, {
  64. [`${confirmCls}-content-withIcon`]: props.icon,
  65. });
  66. return (
  67. <Modal
  68. className={wrapperCls}
  69. title={titleNode}
  70. confirmLoading={confirmLoading}
  71. cancelLoading={cancelLoading}
  72. onOk={handleOk}
  73. onCancel={handleCancel}
  74. icon={iconNode}
  75. visible={visible}
  76. {...rest}
  77. >
  78. <div className={contentCls}>{content}</div>
  79. </Modal>
  80. );
  81. };
  82. export default ConfirmModal;