UNPKG

cheetah-grid

Version:

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

157 lines (152 loc) 4.15 kB
import type { CellRange, ListGridAPI } from "../ts-types"; import type { BaseTooltip } from "./BaseTooltip"; import { LG_EVENT_TYPE } from "../list-grid/LG_EVENT_TYPE"; import { Tooltip } from "./Tooltip"; import { cellInRange } from "../internal/utils"; const TOOLTIP_INSTANCE_FACTORY = { "overflow-text"<T>(grid: ListGridAPI<T>): BaseTooltip<T> { return new Tooltip(grid); }, }; function getTooltipInstanceInfo<T>( // eslint-disable-next-line @typescript-eslint/no-explicit-any grid: ListGridAPI<T>, col: number, row: number ): { type: "overflow-text"; content: string; } | null { // // overflow text tooltip const overflowText = grid.getCellOverflowText(col, row); if (overflowText) { return { type: "overflow-text", content: overflowText, }; } return null; } type AttachInfo<T> = { instance: BaseTooltip<T>; range: CellRange; }; export class TooltipHandler<T> { private _grid: ListGridAPI<T>; private _tooltipInstances: { [type: string]: BaseTooltip<T> }; private _attachInfo?: AttachInfo<T> | null; constructor(grid: ListGridAPI<T>) { this._grid = grid; this._tooltipInstances = {}; this._bindGridEvent(grid); } dispose(): void { const tooltipInstances = this._tooltipInstances; for (const k in tooltipInstances) { tooltipInstances[k].dispose(); } // @ts-expect-error -- ignore delete this._tooltipInstances; this._attachInfo = null; } _attach(col: number, row: number): void { const info = this._attachInfo; const instanceInfo = this._getTooltipInstanceInfo(col, row); if (info && (!instanceInfo || info.instance !== instanceInfo.instance)) { info.instance.detachTooltipElement(); this._attachInfo = null; } if (!instanceInfo) { return; } const { instance } = instanceInfo; instance.attachTooltipElement(col, row, instanceInfo.content); const range = this._grid.getCellRange(col, row); this._attachInfo = { range, instance }; } _move(col: number, row: number): void { const info = this._attachInfo; if (!info || !cellInRange(info.range, col, row)) { return; } const { instance } = info; instance.moveTooltipElement(col, row); } _detach(): void { const info = this._attachInfo; if (!info) { return; } const { instance } = info; instance.detachTooltipElement(); this._attachInfo = null; } _isAttachCell(col: number, row: number): boolean { const info = this._attachInfo; if (!info) { return false; } return cellInRange(info.range, col, row); } _bindGridEvent(grid: ListGridAPI<T>): void { grid.listen(LG_EVENT_TYPE.MOUSEOVER_CELL, (e) => { if (e.related) { if (this._isAttachCell(e.col, e.row)) { return; } } this._attach(e.col, e.row); }); grid.listen(LG_EVENT_TYPE.MOUSEOUT_CELL, (e) => { if (e.related) { if (this._isAttachCell(e.related.col, e.related.row)) { return; } } this._detach(); }); grid.listen(LG_EVENT_TYPE.SELECTED_CELL, (e) => { if (this._isAttachCell(e.col, e.row)) { this._detach(); } }); grid.listen(LG_EVENT_TYPE.SCROLL, () => { const info = this._attachInfo; if (!info) { return; } this._move(info.range.start.col, info.range.start.row); }); grid.listen(LG_EVENT_TYPE.CHANGED_VALUE, (e) => { if (this._isAttachCell(e.col, e.row)) { this._detach(); this._attach(e.col, e.row); } }); } _getTooltipInstanceInfo( col: number, row: number ): { instance: Tooltip<T>; type: string; content: string; } | null { const grid = this._grid; const tooltipInstances = this._tooltipInstances; const info = getTooltipInstanceInfo(grid, col, row); if (!info) { return null; } const { type } = info; const instance = tooltipInstances[type] || (tooltipInstances[type] = TOOLTIP_INSTANCE_FACTORY[type](grid)); return { instance, type, content: info.content, }; } }