UNPKG

@visactor/vtable

Version:

canvas table width high performance

103 lines (97 loc) 6.59 kB
import { EventHandler } from "../../../../event/EventHandler"; import { createElement } from "../../../../tools/dom"; import { TABLE_EVENT_TYPE } from "../../../../core/TABLE_EVENT_TYPE"; const CLASSNAME = "vtable__menu-element", HIDDEN_CLASSNAME = `${CLASSNAME}--hidden`, SHOWN_CLASSNAME = `${CLASSNAME}--shown`; function createMenuDomElement() { return createElement("div", [ CLASSNAME, HIDDEN_CLASSNAME ]); } export class MenuContainer { constructor(table) { var _a, _b, _c; this._handler = new EventHandler, this._rootElement = createMenuDomElement(), this._rootElement.addEventListener("wheel", (e => { e.stopPropagation(); })), null === (_a = this._rootElement) || void 0 === _a || _a.addEventListener("mousedown", (e => { e.stopPropagation(), e.preventDefault(); })), null === (_b = this._rootElement) || void 0 === _b || _b.addEventListener("click", (e => { if (e.stopPropagation(), e.preventDefault(), this._rootElement.classList.contains(HIDDEN_CLASSNAME)) return; const {col: col, row: row, dropDownIndex: dropDownIndex, menuKey: menuKey, text: text, hasChildren: hasChildren} = e.target; if ("number" != typeof dropDownIndex || hasChildren) return void e.stopPropagation(); const field = table.isPivotTable() ? table.internalProps.layoutMap.getPivotDimensionInfo(col, row) : table.getHeaderField(col, row), highlight = table._dropDownMenuIsHighlight(col, row, dropDownIndex); table.fireListeners(TABLE_EVENT_TYPE.DROPDOWN_MENU_CLICK, { col: col, row: row, field: field, menuKey: menuKey, text: text, highlight: highlight, cellLocation: table.getCellLocation(col, row), event: e }), table.fireListeners(TABLE_EVENT_TYPE.DROPDOWN_MENU_CLEAR, null), table.fireListeners(TABLE_EVENT_TYPE.HIDE_MENU, null), e.stopPropagation(); })), null === (_c = this._rootElement) || void 0 === _c || _c.addEventListener("mousemove", (e => { this._rootElement.classList.contains(HIDDEN_CLASSNAME) || e.stopPropagation(); })); } get rootElement() { return this._rootElement; } release() { this.unbindFromCell(); const rootElement = this._rootElement; (null == rootElement ? void 0 : rootElement.parentElement) && rootElement.parentElement.removeChild(rootElement), this._handler.release(), delete this._rootElement; } bindToCell(table, col, row, menuInstanceInfo) { const rootElement = this._rootElement; if (this._menuInstanceInfo = menuInstanceInfo, null == rootElement || rootElement.classList.remove(SHOWN_CLASSNAME), null == rootElement || rootElement.classList.add(HIDDEN_CLASSNAME), this._canBindToCell(table, col, row)) { rootElement.innerHTML = "", rootElement.appendChild(menuInstanceInfo.content); if (this._bindCell(table, col, row, menuInstanceInfo.position, menuInstanceInfo.referencePosition)) return null == rootElement || rootElement.classList.add(SHOWN_CLASSNAME), null == rootElement || rootElement.classList.remove(HIDDEN_CLASSNAME), !0; } else this.unbindFromCell(); return !1; } unbindFromCell() { const rootElement = this._rootElement; this._menuInstanceInfo = void 0, (null == rootElement ? void 0 : rootElement.parentElement) && (rootElement.classList.remove(SHOWN_CLASSNAME), rootElement.classList.add(HIDDEN_CLASSNAME)); } _canBindToCell(table, col, row) { var _a; const rect = table.getCellRangeRelativeRect({ col: col, row: row }), element = null !== (_a = table.internalProps.menu.parentElement) && void 0 !== _a ? _a : table.getElement(), {top: top, bottom: bottom, left: left, right: right} = rect; if (table.isFrozenCell(col, row)) return !0; if (bottom < table.getFrozenRowsHeight() || right < table.getFrozenColsWidth() || left > table.tableNoFrameWidth - table.getRightFrozenColsWidth() || top > table.tableNoFrameHeight - table.getBottomFrozenRowsHeight()) return !1; const {offsetHeight: offsetHeight, offsetWidth: offsetWidth} = element; return !(offsetHeight < top) && !(offsetWidth < left); } _bindCell(table, col, row, position, referencePosition) { var _a; const rootElement = this._rootElement, element = null !== (_a = table.internalProps.menu.parentElement) && void 0 !== _a ? _a : table.getElement(), {width: containerWidth, height: containerHeight, left: containerLeft, top: containerTop} = element.getBoundingClientRect(); if (rootElement) { rootElement.parentElement !== element && element.appendChild(rootElement), rootElement.style.left = "0px"; const maxWidth = .8 * containerWidth; rootElement.style.maxWidth = `${maxWidth}px`; const rootElementWidth = rootElement.clientWidth, rootElementHeight = rootElement.clientHeight; let rootElementLeft, rootElementTop; position && (rootElementLeft = position.x, rootElementTop = position.y), referencePosition && (rootElementLeft = referencePosition.rect.right - rootElementWidth, rootElementTop = referencePosition.rect.bottom), rootElementTop + rootElementHeight > containerHeight && (rootElementTop = containerHeight - rootElementHeight, rootElementLeft += rootElementWidth - 2), rootElementTop < 0 && (rootElementTop /= 2); let deltaTop = 0, deltaLeft = 0; if (table.getElement() !== element) { const {left: left, top: top} = table.getElement().getBoundingClientRect(); deltaTop = top - containerTop, deltaLeft = left - containerLeft; } return rootElement.style.top = `${rootElementTop + deltaTop}px`, rootElementLeft < 0 ? rootElementLeft = 0 : rootElementLeft + rootElementWidth > containerWidth && (rootElementLeft = containerWidth - rootElementWidth), rootElement.style.left = `${rootElementLeft + deltaLeft}px`, !0; } return !1; } pointInMenuElement(x, y) { const rootElement = this._rootElement, {x: rootLeft, y: rootTop, width: rootWidth, height: rootHeight} = rootElement.getBoundingClientRect(); return x > rootLeft - 5 && x < rootLeft + rootWidth + 5 && y > rootTop - 5 && y < rootTop + rootHeight + 5; } } //# sourceMappingURL=MenuContainer.js.map