sideSheetFoundation.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import BaseFoundation, { DefaultAdapter } from '../base/foundation';
  2. import { get, noop } from 'lodash';
  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. 'aria-label'?: string;
  31. }
  32. export interface SideSheetState {
  33. hidden: boolean;
  34. }
  35. export interface SideSheetAdapter extends DefaultAdapter<SideSheetProps, SideSheetState> {
  36. disabledBodyScroll: () => void;
  37. enabledBodyScroll: () => void;
  38. notifyCancel: (e: any) => void;
  39. notifyVisibleChange: (visible: boolean) => void;
  40. setOnKeyDownListener: () => void;
  41. removeKeyDownListener: () => void;
  42. toggleHidden: (hidden: boolean) => void;
  43. }
  44. export default class SideSheetFoundation extends BaseFoundation<SideSheetAdapter> {
  45. constructor(adapter: SideSheetAdapter) {
  46. super({ ...SideSheetFoundation.defaultAdapter, ...adapter });
  47. }
  48. get defaultAdapter() {
  49. return ({
  50. handleCancel: noop,
  51. beforeShow: noop,
  52. afterHide: noop,
  53. });
  54. }
  55. destroy() {
  56. this.afterHide();
  57. }
  58. handleCancel(e: any) {
  59. this._adapter.notifyCancel(e);
  60. }
  61. beforeShow() {
  62. const allowDisable = this.getProp('disableScroll');
  63. allowDisable && this._adapter.disabledBodyScroll();
  64. this._adapter.setOnKeyDownListener();
  65. }
  66. afterHide() {
  67. const allowDisable = this.getProp('disableScroll');
  68. allowDisable && this._adapter.enabledBodyScroll();
  69. this._adapter.removeKeyDownListener();
  70. }
  71. handleKeyDown(e: any) {
  72. const { closeOnEsc } = this.getProps();
  73. if (closeOnEsc && e.keyCode === KeyCode.ESC) {
  74. e.stopPropagation();
  75. this.handleCancel(e);
  76. return;
  77. }
  78. }
  79. mergeMotionProp = (motion: any, prop: string, cb: () => void) => {
  80. const mergedMotion = typeof (motion) === 'undefined' || motion ? {
  81. ...motion,
  82. [prop]: (...args: any) => {
  83. const curr = get(motion, prop);
  84. if (typeof curr === 'function') {
  85. curr(...args);
  86. }
  87. cb();
  88. },
  89. } : false;
  90. return mergedMotion;
  91. };
  92. getMergedMotion = () => {
  93. const {
  94. motion,
  95. visible,
  96. keepDOM,
  97. } = this.getProps();
  98. let mergedMotion = this.mergeMotionProp(motion, 'didEnter', (...args) => {
  99. const didEnter = get(motion, 'didEnter');
  100. if (typeof didEnter === 'function') {
  101. didEnter(...args);
  102. }
  103. this._adapter.notifyVisibleChange(visible);
  104. });
  105. mergedMotion = this.mergeMotionProp(mergedMotion, 'didLeave', (...args) => {
  106. const didLeave = get(motion, 'didLeave');
  107. if (typeof didLeave === 'function') {
  108. didLeave(...args);
  109. }
  110. this._adapter.notifyVisibleChange(visible);
  111. });
  112. if (keepDOM) {
  113. mergedMotion = this.mergeMotionProp(mergedMotion, 'didLeave', this._adapter.toggleHidden.bind(this, true));
  114. }
  115. return mergedMotion;
  116. };
  117. }