subNavFoundation.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import BaseFoundation, { DefaultAdapter } from '../base/foundation';
  2. const addKeys = function addKeys(originKeys: (string | number)[] = [], ...willAddKeys: (string | number)[]) {
  3. const keySet = new Set(originKeys);
  4. willAddKeys.forEach(key => key && keySet.add(key));
  5. return Array.from(keySet);
  6. };
  7. const removeKeys = function removeKeys(originKeys: (string | number)[] = [], ...willRemoveKeys: (string | number)[]) {
  8. const keySet = new Set(originKeys);
  9. willRemoveKeys.forEach(key => key && keySet.delete(key));
  10. return Array.from(keySet);
  11. };
  12. export interface OnOpenChangeData {
  13. itemKey: string | number;
  14. openKeys: (string | number)[];
  15. isOpen: boolean;
  16. }
  17. export interface OnClickData extends OnOpenChangeData {
  18. domEvent: any;
  19. }
  20. export interface OnSelectData extends OnOpenChangeData {
  21. domEvent: any;
  22. }
  23. export interface SubNavAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
  24. updateIsHovered(isHovered: boolean): void;
  25. getOpenKeys(): (string | number)[];
  26. getOpenKeysIsControlled(): boolean;
  27. getCanUpdateOpenKeys(): boolean;
  28. updateOpen(isOpen: boolean): void;
  29. notifyGlobalOpenChange(data: OnOpenChangeData): void;
  30. notifyGlobalOnSelect(data: OnSelectData): void;
  31. notifyGlobalOnClick(data: OnClickData): void;
  32. getIsSelected(itemKey: string | number): boolean;
  33. getIsOpen(): boolean;
  34. }
  35. export default class SubNavFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<SubNavAdapter<P, S>, P, S> {
  36. constructor(adapter: SubNavAdapter<P, S>) {
  37. super({ ...adapter });
  38. }
  39. _timer: number;
  40. init() {
  41. // this.log('invoke SubNavFoundation init()');
  42. this._timer = null;
  43. }
  44. destroy() {} // eslint-disable-line
  45. clearDelayTimer() {
  46. if (this._timer) {
  47. clearTimeout(this._timer);
  48. this._timer = null;
  49. }
  50. }
  51. isValidKey(itemKey: string | number) {
  52. // eslint-disable-next-line eqeqeq
  53. return itemKey != null && (typeof itemKey === 'number' || typeof itemKey === 'string');
  54. }
  55. handleDropdownVisibleChange(visible: boolean) {
  56. const itemKey = this.getProp('itemKey');
  57. const openKeysIsControlled = this._adapter.getOpenKeysIsControlled();
  58. const canUpdateOpenKeys = this._adapter.getCanUpdateOpenKeys();
  59. const rawOpenKeys = this._adapter.getOpenKeys();
  60. const openKeys = visible ? addKeys(rawOpenKeys, itemKey) : removeKeys(rawOpenKeys, itemKey);
  61. this.clearDelayTimer();
  62. if (!openKeysIsControlled) {
  63. if (canUpdateOpenKeys) {
  64. this._adapter.updateOpen(visible);
  65. }
  66. // this._adapter.updateIsHovered(visible);
  67. }
  68. this._adapter.notifyGlobalOpenChange({ itemKey, openKeys, isOpen: visible });
  69. }
  70. /**
  71. *
  72. * @param {Event} e
  73. * @param {HTMLElement} titleRef
  74. */
  75. handleClick(e: any, titleRef: any) {
  76. const { itemKey, disabled } = this.getProps();
  77. if (disabled) {
  78. return;
  79. }
  80. // this.log(e, titleRef, titleRef.contains(e.target));
  81. const clickedDomIsTitle = titleRef && titleRef.contains(e.target);
  82. let isOpen = Boolean(this._adapter.getIsOpen());
  83. if (!clickedDomIsTitle) {
  84. isOpen = false;
  85. } else {
  86. isOpen = !isOpen;
  87. }
  88. const openKeys = isOpen
  89. ? addKeys(this._adapter.getOpenKeys(), itemKey)
  90. : removeKeys(this._adapter.getOpenKeys(), itemKey);
  91. const cbVal = { itemKey, openKeys, isOpen, domEvent: e };
  92. const openKeysIsControlled = this._adapter.getOpenKeysIsControlled();
  93. const canUpdateOpenKeys = this._adapter.getCanUpdateOpenKeys();
  94. if (!openKeysIsControlled && canUpdateOpenKeys) {
  95. this._adapter.updateOpen(isOpen);
  96. }
  97. this._adapter.notifyGlobalOpenChange(cbVal);
  98. this._adapter.notifyGlobalOnClick(cbVal);
  99. }
  100. }