sideSheetFoundation.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import BaseFoundation, { DefaultAdapter } from '../base/foundation';
  2. import { get, noop } from 'lodash-es';
  3. import KeyCode from '../utils/keyCode';
  4. import { Motion } from '../utils/type';
  5. export interface SideSheetProps {
  6. afterVisibleChange?: (isVisible: boolean) => void;
  7. bodyStyle?: Record<string, any>;
  8. className?: string;
  9. closable?: boolean;
  10. closeOnEsc?: boolean;
  11. disableScroll?: boolean;
  12. footer?: any;
  13. getPopupContainer?: () => HTMLElement;
  14. headerStyle?: Record<string, any>;
  15. height?: number | string;
  16. keepDOM?: boolean;
  17. mask?: boolean;
  18. maskClosable?: boolean;
  19. maskStyle?: Record<string, any>;
  20. motion?: Motion;
  21. onCancel?: (e: any) => void;
  22. placement?: 'top' | 'bottom' | 'left' | 'right';
  23. size?: 'small' | 'medium' | 'large';
  24. style?: Record<string, any>;
  25. title?: any;
  26. visible?: boolean;
  27. width?: number | string;
  28. zIndex?: number;
  29. children?: any;
  30. }
  31. export interface SideSheetState{
  32. hidden: boolean;
  33. }
  34. export interface SideSheetAdapter extends DefaultAdapter<SideSheetProps, SideSheetState>{
  35. disabledBodyScroll: () => void;
  36. enabledBodyScroll: () => void;
  37. notifyCancel: (e: any) => void;
  38. notifyVisibleChange: (visible: boolean) => void;
  39. setOnKeyDownListener: () => void;
  40. removeKeyDownListener: () => void;
  41. toggleHidden: (hidden: boolean) => void;
  42. }
  43. export default class SideSheetFoundation extends BaseFoundation<SideSheetAdapter> {
  44. constructor(adapter: SideSheetAdapter) {
  45. super({ ...SideSheetFoundation.defaultAdapter, ...adapter });
  46. }
  47. get defaultAdapter() {
  48. return ({
  49. handleCancel: noop,
  50. beforeShow: noop,
  51. afterHide: noop,
  52. });
  53. }
  54. destroy() {
  55. this.afterHide();
  56. }
  57. handleCancel(e: any) {
  58. this._adapter.notifyCancel(e);
  59. }
  60. beforeShow() {
  61. const allowDisable = this.getProp('disableScroll');
  62. allowDisable && this._adapter.disabledBodyScroll();
  63. this._adapter.setOnKeyDownListener();
  64. }
  65. afterHide() {
  66. const allowDisable = this.getProp('disableScroll');
  67. allowDisable && this._adapter.enabledBodyScroll();
  68. this._adapter.removeKeyDownListener();
  69. }
  70. handleKeyDown(e: any) {
  71. const { closeOnEsc } = this.getProps();
  72. if (closeOnEsc && e.keyCode === KeyCode.ESC) {
  73. e.stopPropagation();
  74. this.handleCancel(e);
  75. return;
  76. }
  77. }
  78. mergeMotionProp = (motion: any, prop: string, cb: () => void) => {
  79. const mergedMotion = typeof (motion) === 'undefined' || motion ? {
  80. ...motion,
  81. [prop]: (...args: any) => {
  82. const curr = get(motion, prop);
  83. if (typeof curr === 'function') {
  84. curr(...args);
  85. }
  86. cb();
  87. },
  88. } : false;
  89. return mergedMotion;
  90. };
  91. getMergedMotion = () => {
  92. const {
  93. motion,
  94. visible,
  95. keepDOM,
  96. } = this.getProps();
  97. let mergedMotion = this.mergeMotionProp(motion, 'didEnter', (...args) => {
  98. const didEnter = get(motion, 'didEnter');
  99. if (typeof didEnter === 'function') {
  100. didEnter(...args);
  101. }
  102. this._adapter.notifyVisibleChange(visible);
  103. });
  104. mergedMotion = this.mergeMotionProp(mergedMotion, 'didLeave', (...args) => {
  105. const didLeave = get(motion, 'didLeave');
  106. if (typeof didLeave === 'function') {
  107. didLeave(...args);
  108. }
  109. this._adapter.notifyVisibleChange(visible);
  110. });
  111. if (keepDOM) {
  112. mergedMotion = this.mergeMotionProp(mergedMotion, 'didLeave', this._adapter.toggleHidden.bind(this, true));
  113. }
  114. return mergedMotion;
  115. };
  116. }