modalFoundation.ts 3.3 KB

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