modalFoundation.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import BaseFoundation, { DefaultAdapter } from '../base/foundation';
  2. import isPromise from "../utils/isPromise";
  3. export type OKType = 'primary' | 'secondary' | 'tertiary' | 'warning' | 'danger';
  4. export type Size = 'small' | 'medium' | 'large' | 'full-width';
  5. export interface ModalAdapter extends DefaultAdapter<ModalProps, ModalState> {
  6. disabledBodyScroll: () => void;
  7. enabledBodyScroll: () => void;
  8. notifyCancel: (e: any) => void | Promise<any>;
  9. notifyOk: (e: any) => void | Promise<any>;
  10. notifyClose: () => void;
  11. toggleDisplayNone: (displayNone: boolean, callback?: (displayNone: boolean) => void) => void;
  12. notifyFullScreen: (isFullScreen: boolean) => void;
  13. getProps: () => ModalProps
  14. }
  15. export interface ModalProps {
  16. afterClose?: () => void;
  17. bodyStyle?: Record<string, any>;
  18. cancelButtonProps?: any;
  19. cancelText?: string;
  20. centered?: boolean;
  21. className?: string;
  22. closable?: boolean;
  23. confirmLoading?: boolean;
  24. cancelLoading?: boolean;
  25. content?: any;
  26. footer?: any;
  27. hasCancel?: boolean;
  28. header?: any;
  29. height?: string | number;
  30. mask?: boolean;
  31. maskClosable?: boolean;
  32. maskStyle?: Record<string, any>;
  33. maskFixed?: boolean;
  34. motion?: boolean;
  35. okButtonProps?: any;
  36. okText?: string;
  37. okType?: OKType;
  38. onCancel?: (e: any) => void | Promise<any>;
  39. onOk?: (e: any) => void | Promise<any>;
  40. style?: Record<string, any>;
  41. title?: any;
  42. visible?: boolean;
  43. width?: string | number;
  44. zIndex?: number;
  45. icon?: any;
  46. getPopupContainer?: () => HTMLElement;
  47. closeIcon?: any;
  48. closeOnEsc?: boolean;
  49. size?: Size;
  50. lazyRender?: boolean;
  51. keepDOM?: boolean;
  52. direction?: any;
  53. fullScreen?: boolean;
  54. preventScroll?: boolean
  55. }
  56. export interface ModalState {
  57. displayNone: boolean;
  58. isFullScreen: boolean;
  59. onOKReturnPromiseStatus?:"pending"|"fulfilled"|"rejected";
  60. onCancelReturnPromiseStatus?:"pending"|"fulfilled"|"rejected"
  61. }
  62. export default class ModalFoundation extends BaseFoundation<ModalAdapter> {
  63. constructor(adapter: ModalAdapter) {
  64. super({
  65. ...adapter,
  66. });
  67. }
  68. destroy() {
  69. this.afterHide();
  70. }
  71. handleCancel(e: any) {
  72. const result = this._adapter.notifyCancel(e);
  73. if (isPromise(result)) {
  74. this._adapter.setState({ onCancelReturnPromiseStatus: "pending" });
  75. (result as Promise<any>)?.then(()=>{
  76. this._adapter.setState({ onCancelReturnPromiseStatus: "fulfilled" });
  77. })?.catch(e=>{
  78. this._adapter.setState({ onCancelReturnPromiseStatus: "rejected" });
  79. throw e;
  80. });
  81. }
  82. }
  83. handleOk(e: any) {
  84. const result = this._adapter.notifyOk(e);
  85. if (isPromise(result)){
  86. this._adapter.setState({ onOKReturnPromiseStatus: "pending" });
  87. (result as Promise<any>)?.then(()=>{
  88. this._adapter.setState({ onOKReturnPromiseStatus: "fulfilled" });
  89. })?.catch(e=>{
  90. this._adapter.setState({ onOKReturnPromiseStatus: "rejected" });
  91. throw e;
  92. });
  93. }
  94. }
  95. beforeShow() {
  96. this._adapter.disabledBodyScroll();
  97. }
  98. afterHide() {
  99. this._adapter.enabledBodyScroll();
  100. this._adapter.notifyClose();
  101. }
  102. // afterClose() {
  103. // this._adapter.notifyClose();
  104. // }
  105. toggleDisplayNone = (displayNone: boolean, callback?: (displayNone: boolean) => void) => {
  106. this._adapter.toggleDisplayNone(displayNone, callback);
  107. };
  108. // // eslint-disable-next-line max-len
  109. // mergeMotionProp = (motion: Motion, prop: string, cb: () => void) => {
  110. // const mergedMotion = typeof (motion) === 'undefined' || motion ? {
  111. // ...(motion as { [key: string]: (() => void) | boolean }),
  112. // [prop]: (...args: any) => {
  113. // const curr = get(motion, prop);
  114. // if (typeof curr === 'function') {
  115. // curr(...args);
  116. // }
  117. // cb();
  118. // }
  119. // } : false;
  120. // return mergedMotion;
  121. // };
  122. //
  123. // getMergedMotion() {
  124. // let { motion } = this._adapter.getProps();
  125. // const { keepDOM } = this._adapter.getProps();
  126. // motion = this.mergeMotionProp(motion, 'didLeave', this.afterClose.bind(this));
  127. // if (!keepDOM) {
  128. // return motion;
  129. // }
  130. // const mergedMotion = this.mergeMotionProp(motion, 'didLeave', this.toggleHidden.bind(this, true));
  131. // return mergedMotion;
  132. // }
  133. }