diff options
Diffstat (limited to 'apps/web/src/components/app/index.ts')
| -rw-r--r-- | apps/web/src/components/app/index.ts | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/apps/web/src/components/app/index.ts b/apps/web/src/components/app/index.ts new file mode 100644 index 0000000..a2c0c9d --- /dev/null +++ b/apps/web/src/components/app/index.ts @@ -0,0 +1,93 @@ +import { produce } from "immer"; +import defaultDoc from "../../defaultDoc"; +import NotiveElement, { customElement } from "../../element"; +import { + changeSelectedSubdivisions, + getSelectedSubdivisionsCount, +} from "../../grid"; +import { Doc } from "../../types"; +import ntvGrid, { NotiveGridElement } from "../grid"; +import renderGrid from "../grid/renderGrid"; +import { GridSelection } from "../grid/selection"; +import ntvToolbar from "../toolbar"; +import "./index.css"; + +@customElement("ntv-app") +export class NotiveAppElement extends NotiveElement { + doc: Doc = defaultDoc(); + + #selectedGridId?: string; + #selection?: GridSelection; + + setSelection(gridId: string, selection: GridSelection) { + const grid = this.doc.grids.find((grid) => grid.id === gridId); + if (!grid) throw new Error("Invalid grid ID"); + + this.#selectedGridId = gridId; + this.#selection = selection; + this.#updateGridSelections(); + + this.#toolbar.subdivisions = getSelectedSubdivisionsCount(grid, selection); + } + + clearSelection() { + this.#selectedGridId = undefined; + this.#selection = undefined; + this.#updateGridSelections(); + this.#toolbar.subdivisions = undefined; + } + + #updateGridSelections() { + this.querySelectorAll<NotiveGridElement>("ntv-grid").forEach((grid) => { + grid.selection = + this.#selectedGridId === grid.grid?.id ? this.#selection : undefined; + }); + } + + #toolbar = ntvToolbar({ + onsubdivisionschange: ({ subdivisions }) => { + if (!subdivisions) return; + + const gridId = this.#selectedGridId; + const selection = this.#selection; + + if (!gridId || !selection) return; + + const gridIndex = this.doc.grids.findIndex((grid) => grid.id === gridId); + + this.doc = produce(this.doc, (doc) => { + doc.grids[gridIndex] = changeSelectedSubdivisions( + this.doc.grids[gridIndex], + selection, + subdivisions, + ); + }); + + this.querySelector<NotiveGridElement>( + `ntv-grid[data-grid-id="${gridId}"]`, + )!.grid = renderGrid(this.doc.grids[gridIndex]); + + this.clearSelection(); + }, + }); + + connectedCallback() { + this.append( + this.#toolbar, + ...this.doc.grids.map((grid) => + ntvGrid({ + grid: renderGrid(grid), + dataset: { gridId: grid.id }, + ongridselectionchange: (event) => { + this.setSelection(grid.id, event.selection); + }, + oncellchange: (event) => { + console.log(event); + }, + }), + ), + ); + } +} + +export default NotiveAppElement.makeFactory(); |
