diff options
Diffstat (limited to 'web/src/components/grid/index.ts')
| -rw-r--r-- | web/src/components/grid/index.ts | 99 |
1 files changed, 48 insertions, 51 deletions
diff --git a/web/src/components/grid/index.ts b/web/src/components/grid/index.ts index 2c00eb8..6c7f735 100644 --- a/web/src/components/grid/index.ts +++ b/web/src/components/grid/index.ts @@ -1,4 +1,5 @@ -import h, { type CreateElement } from "../../html"; +import NotiveElement, { customElement, eventHandler } from "../../element"; +import h from "../../html"; import { ActiveCellSelection, Selection } from "../../selection"; import { CellRef } from "../../types"; import cellAtCoord from "./cellAtCoord"; @@ -7,7 +8,8 @@ import drawSelection, { SelectionStyles } from "./drawSelection"; import "./index.css"; import { getRenderedCell, RenderedGrid } from "./renderGrid"; -export class NotiveGridElement extends HTMLElement { +@customElement("ntv-grid") +export class NotiveGridElement extends NotiveElement { #internals: ElementInternals = this.attachInternals(); grid?: RenderedGrid; @@ -23,28 +25,11 @@ export class NotiveGridElement extends HTMLElement { this.drawSelection(); } - #ongridselectionchange?: ((event: GridSelectionEvent) => any) | undefined; + @eventHandler("ntv:grid:selectionchange") + ongridselectionchange?: (event: GridSelectionEvent) => any; - get ongridselectionchange() { - return this.#ongridselectionchange; - } - - set ongridselectionchange( - handler: ((event: GridSelectionEvent) => any) | undefined, - ) { - if (this.#ongridselectionchange) { - this.removeEventListener( - "ntv:grid:selectionchange", - this.#ongridselectionchange, - ); - } - - this.#ongridselectionchange = handler; - - if (handler) { - this.addEventListener("ntv:grid:selectionchange", handler); - } - } + @eventHandler("ntv:grid:cellchange") + oncellchange?: (event: GridCellChangeEvent) => any; canvas: HTMLCanvasElement = h.canvas({ onmousedown: (event) => { @@ -53,6 +38,12 @@ export class NotiveGridElement extends HTMLElement { if (!cellRef) return; this.startSelecting(cellRef); }, + ondblclick: (event) => { + if (!this.grid) return; + const cellRef = this.#mouseEventCellRef(event); + if (!cellRef) return; + this.startEditing(cellRef); + }, }); selectionCanvas: HTMLCanvasElement = h.canvas({ @@ -188,11 +179,9 @@ export class NotiveGridElement extends HTMLElement { #editingCellRef?: CellRef; - #editInputEl: HTMLInputElement = h.input({ - dataset: { editCell: "true" }, - onblur: () => { - this.#finishEditing(); - }, + #editInput: HTMLInputElement = h.input({ + dataset: { edit: "true" }, + onblur: () => this.#finishEditing(), onkeydown: (event) => { switch (event.key) { case "Enter": @@ -206,50 +195,45 @@ export class NotiveGridElement extends HTMLElement { }, }); - #canvasDoubleClickCallback(this: NotiveGridElement, event: MouseEvent) { + startEditing(cellRef: CellRef) { if (!this.grid) return; - const cellRef = this.#mouseEventCellRef(event); - - if (!cellRef) return; - const cell = getRenderedCell(this.grid, cellRef); if (!cell) return; this.#editingCellRef = cellRef; - this.append(this.#editInputEl); + this.append(this.#editInput); - this.#editInputEl.value = cell.value || ""; - this.#editInputEl.style.left = cell.rect.topLeft.x + 2 + "px"; - this.#editInputEl.style.top = cell.rect.topLeft.y + 2 + "px"; - this.#editInputEl.style.width = cell.rect.width - 3 + "px"; - this.#editInputEl.style.height = cell.rect.height - 3 + "px"; - this.#editInputEl.focus(); + this.#editInput.value = cell.value || ""; + + Object.assign(this.#editInput.style, { + left: cell.rect.topLeft.x + 2 + "px", + top: cell.rect.topLeft.y + 2 + "px", + width: cell.rect.width - 3 + "px", + height: cell.rect.height - 3 + "px", + }); + + this.#editInput.focus(); } #cancelEditing() { - this.#editInputEl.remove(); + this.#editInput.remove(); } #finishEditing() { - this.#editInputEl.remove(); + this.#editInput.remove(); - if (!this.grid) return; + if (!this.grid || !this.#editingCellRef) return; - window.notive.setCellValue( - this.grid.id, - this.#editingCellRef!, - this.#editInputEl.value, + this.dispatchEvent( + new GridCellChangeEvent(this.#editingCellRef, this.#editInput.value), ); } } -customElements.define("ntv-grid", NotiveGridElement); - -export default ((...args: any[]): NotiveGridElement => - (h as any)["ntv-grid"](...args)) as CreateElement<NotiveGridElement>; +export default NotiveGridElement.makeFactory(); export class GridSelectionEvent extends Event { selection: Selection; @@ -260,8 +244,21 @@ export class GridSelectionEvent extends Event { } } +export class GridCellChangeEvent extends Event { + cellRef: CellRef; + value?: string; + + constructor(cellRef: CellRef, value: string | undefined) { + super("ntv:grid:cellchange"); + + this.cellRef = cellRef; + this.value = value; + } +} + declare global { interface HTMLElementEventMap { "ntv:grid:selectionchange": GridSelectionEvent; + "ntv:grid:cellchange": GridCellChangeEvent; } } |
