UNPKG

e-virt-table

Version:

A powerful data table based on canvas. You can use it as data grid、Microsoft Excel or Google sheets. It supports virtual scroll、cell edit etc.

137 lines 4.66 kB
import { computePosition, offset, flip, shift } from '@floating-ui/dom'; export default class ContextMenu { constructor(ctx) { Object.defineProperty(this, "ctx", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "contextMenuEl", { enumerable: true, configurable: true, writable: true, value: void 0 }); Object.defineProperty(this, "custom", { enumerable: true, configurable: true, writable: true, value: false }); this.ctx = ctx; if (this.ctx.contextMenuElement) { this.custom = true; this.contextMenuEl = this.ctx.contextMenuElement; } else { this.custom = false; this.contextMenuEl = document.createElement('div'); } this.createContextMenu(); this.init(); } init() { this.ctx.on('cellContextMenuClick', (cell, e) => { if (!this.ctx.config.ENABLE_CONTEXT_MENU) return; e.preventDefault(); const { xArr, yArr } = this.ctx.selector; const [minX, maxX] = xArr; const [minY, maxY] = yArr; const { rowIndex, colIndex } = cell; //判断是否在范围内 const isInRange = rowIndex >= minY && rowIndex <= maxY && colIndex >= minX && colIndex <= maxX; if (!isInRange) { this.ctx.emit('setSelectorCell', cell, e); } const virtualReference = { getBoundingClientRect: () => ({ width: 0, height: 0, top: e.clientY, left: e.clientX, right: e.clientX, bottom: e.clientY, x: e.clientX, y: e.clientY, }), contextElement: document.body, }; computePosition(virtualReference, this.contextMenuEl, { placement: 'right-start', middleware: [offset(), shift(), flip()], }).then(({ x, y }) => { this.show(x, y); }); }); this.ctx.on('click', this.hide.bind(this)); this.ctx.on('onScroll', this.hide.bind(this)); this.ctx.on('resize', this.hide.bind(this)); } //创建右键菜单,绑定子项点击事件 createContextMenu() { this.contextMenuEl.className = 'e-virt-table-context-menu'; this.ctx.containerElement.appendChild(this.contextMenuEl); // 如果是自定义右键菜单,则不创建默认子菜单 if (this.custom) return; const { CONTEXT_MENU } = this.ctx.config; this.createContextMenuItems(CONTEXT_MENU, (item) => { switch (item.value) { case 'copy': this.ctx.emit('contextMenuCopy'); break; case 'paste': this.ctx.emit('contextMenuPaste'); break; case 'cut': this.ctx.emit('contextMenuCut'); break; case 'clearSelected': this.ctx.emit('contextMenuClearSelected'); break; default: } this.hide(); }); } //创建右键菜单子项元素 createContextMenuItems(items, callback) { this.contextMenuEl.replaceChildren(); items.forEach((item) => { const menuItemEl = document.createElement('div'); menuItemEl.className = 'e-virt-table-context-menu-item'; menuItemEl.innerText = item.label; if (item.event) { menuItemEl.onclick = () => { item.event && item.event(); callback(item); }; } else { menuItemEl.onclick = () => callback(item); } this.contextMenuEl.appendChild(menuItemEl); }); } show(x, y) { Object.assign(this.contextMenuEl.style, { left: `${x}px`, top: `${y}px`, }); } hide() { Object.assign(this.contextMenuEl.style, { left: '-99999px', top: '-99999px', }); } updated() { this.createContextMenu(); } destroy() { this.contextMenuEl.remove(); } } //# sourceMappingURL=ContextMenu.js.map