ConfirmModal.tsx 2.9 KB

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