UNPKG

cheetah-grid

Version:

Cheetah Grid is a high performance grid engine that works on canvas

151 lines (138 loc) 4.53 kB
import { EventHandler } from "../../internal/EventHandler"; import type { ListGridAPI } from "../../ts-types"; import { createElement } from "../../internal/dom"; const CLASSNAME = "cheetah-grid__tooltip-element"; const CONTENT_CLASSNAME = `${CLASSNAME}__content`; const HIDDEN_CLASSNAME = `${CLASSNAME}--hidden`; const SHOWN_CLASSNAME = `${CLASSNAME}--shown`; function createTooltipDomElement(): HTMLElement { require("@/tooltip/internal/TooltipElement.css"); const rootElement = createElement("div", { classList: [CLASSNAME, HIDDEN_CLASSNAME], }); const messageElement = createElement("pre", { classList: [CONTENT_CLASSNAME], }); rootElement.appendChild(messageElement); return rootElement; } export class TooltipElement<T> { private _handler: EventHandler; private _rootElement: HTMLElement; private _messageElement: HTMLElement; constructor() { this._handler = new EventHandler(); const rootElement = (this._rootElement = createTooltipDomElement()); this._messageElement = rootElement.querySelector( `.${CONTENT_CLASSNAME}` ) as HTMLElement; } dispose(): void { this.detach(); const rootElement = this._rootElement; if (rootElement.parentElement) { rootElement.parentElement.removeChild(rootElement); } this._handler.dispose(); // @ts-expect-error -- ignore delete this._rootElement; // @ts-expect-error -- ignore delete this._messageElement; } attach( grid: ListGridAPI<T>, col: number, row: number, content: string ): void { const rootElement = this._rootElement; const messageElement = this._messageElement; rootElement.classList.remove(SHOWN_CLASSNAME); rootElement.classList.add(HIDDEN_CLASSNAME); if (this._attachCell(grid, col, row)) { rootElement.classList.add(SHOWN_CLASSNAME); rootElement.classList.remove(HIDDEN_CLASSNAME); messageElement.textContent = content; } else { this._detach(); } } move(grid: ListGridAPI<T>, col: number, row: number): void { const rootElement = this._rootElement; if (this._attachCell(grid, col, row)) { rootElement.classList.add(SHOWN_CLASSNAME); rootElement.classList.remove(HIDDEN_CLASSNAME); } else { this._detach(); } } detach(): void { this._detach(); } _detach(): void { const rootElement = this._rootElement; if (rootElement.parentElement) { // rootElement.parentElement.removeChild(rootElement); rootElement.classList.remove(SHOWN_CLASSNAME); rootElement.classList.add(HIDDEN_CLASSNAME); } } _attachCell(grid: ListGridAPI<T>, col: number, row: number): boolean { const rootElement = this._rootElement; const { element, rect } = grid.getAttachCellsArea( grid.getCellRange(col, row) ); const { bottom: top, left, width } = rect; const { frozenRowCount, frozenColCount } = grid; if (row >= frozenRowCount && frozenRowCount > 0) { const { rect: frozenRect } = grid.getAttachCellsArea( grid.getCellRange(col, frozenRowCount - 1) ); if (top < frozenRect.bottom) { return false; //範囲外 } } else { if (top < 0) { return false; //範囲外 } } if (col >= frozenColCount && frozenColCount > 0) { const { rect: frozenRect } = grid.getAttachCellsArea( grid.getCellRange(frozenColCount - 1, row) ); if (left < frozenRect.right) { return false; //範囲外 } } else { if (left < 0) { return false; //範囲外 } } const { height: offsetHeight, width: offsetWidth, left: elementLeft, right: elementRight, } = element.getBoundingClientRect(); if (offsetHeight < top) { return false; //範囲外 } if (offsetWidth < left) { return false; //範囲外 } const cellCenter = left + width / 2; rootElement.style.top = `${top.toFixed()}px`; rootElement.style.left = `${cellCenter.toFixed()}px`; rootElement.style.minWidth = `${width.toFixed()}px`; const maxWidthForLeft = (elementLeft + cellCenter) * 2; const winWidth = window.innerWidth; const maxWidthForRight = (offsetWidth - cellCenter + (winWidth - elementRight)) * 2; const maxWidth = Math.min(maxWidthForLeft, maxWidthForRight); rootElement.style.maxWidth = `${maxWidth.toFixed()}px`; if (rootElement.parentElement !== element) { element.appendChild(rootElement); } return true; } }