summaryrefslogtreecommitdiff
path: root/web/src/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/index.ts')
-rw-r--r--web/src/index.ts215
1 files changed, 1 insertions, 214 deletions
diff --git a/web/src/index.ts b/web/src/index.ts
index 97cfdf8..4c30907 100644
--- a/web/src/index.ts
+++ b/web/src/index.ts
@@ -1,214 +1 @@
-import Ratio from "./math/Ratio";
-import { Cell, CellRef, Doc, Grid, mapRowsInRange } from "./types";
-import { ActiveCellSelection, Selection } from "./selection";
-import renderGrid, {
- getRenderedCell,
- RenderedGrid,
-} from "./components/grid/renderGrid";
-
-function defaultDoc(): Doc {
- const defaultCells: Cell[] = Array.from({ length: 16 }, () => ({
- widthRatio: new Ratio(1, 16),
- }));
-
- return {
- grids: [
- {
- id: window.crypto.randomUUID(),
- baseCellSize: 42,
- baseCellWidthRatio: new Ratio(1, 16),
- parts: [
- {
- rows: Array.from({ length: 4 }, () => ({
- cells: [...defaultCells],
- })),
- },
- ],
- },
- {
- id: window.crypto.randomUUID(),
- baseCellSize: 42,
- baseCellWidthRatio: new Ratio(1, 16),
- parts: [
- {
- rows: Array.from({ length: 2 }, () => ({
- cells: [...defaultCells],
- })),
- },
- {
- rows: Array.from({ length: 2 }, () => ({
- cells: [...defaultCells],
- })),
- },
- ],
- },
- ],
- };
-}
-
-export default class Notive {
- #doc: Doc = defaultDoc();
-
- get doc() {
- return this.#doc;
- }
-
- #gridsById = Object.fromEntries(
- this.#doc.grids.map((grid) => [grid.id, renderGrid(grid)]),
- );
-
- getGrid(id: string): RenderedGrid | undefined {
- return this.#gridsById[id];
- }
-
- #selection?: Selection;
-
- get selection() {
- return this.#selection;
- }
-
- #pendingSelection?: Selection;
-
- get pendingSelection() {
- return this.#pendingSelection;
- }
-
- selectCell(gridId: string, cellRef: CellRef) {
- this.#selection = new ActiveCellSelection(gridId, cellRef);
- this.#dispatchSelectionChanged();
- }
-
- startSelecting(gridId: string, cellRef: CellRef) {
- this.#pendingSelection = new ActiveCellSelection(gridId, cellRef);
- this.#dispatchSelectionChanged();
- }
-
- extendSelection(cellRef: CellRef) {
- const newSelection = this.pendingSelection?.extend(cellRef);
-
- if (newSelection !== this.pendingSelection) {
- this.#pendingSelection = newSelection;
- this.#dispatchSelectionChanged();
- }
- }
-
- finishSelecting() {
- this.#selection = this.pendingSelection;
- this.#pendingSelection = undefined;
- this.#dispatchSelectionChanged();
- }
-
- #dispatchSelectionChanged() {
- window.dispatchEvent(new CustomEvent("ntv:selectionchange"));
- }
-
- subdivideSelection(subdivisions: number) {
- const selection = this.selection;
- if (!selection) return;
-
- const grid = this.getGrid(selection.gridId);
- if (!grid) return;
-
- const startCellRef = selection.startCellRef();
- const endCellRef = selection.endCellRef();
-
- const startCell = getRenderedCell(grid, startCellRef);
- const endCell = getRenderedCell(grid, endCellRef);
- if (!startCell || !endCell) return;
-
- const startRatio =
- startCell.startRatio.compare(endCell.startRatio) <= 0
- ? startCell.startRatio
- : endCell.startRatio;
-
- const endRatio =
- startCell.endRatio.compare(endCell.endRatio) >= 0
- ? startCell.endRatio
- : endCell.endRatio;
-
- const totalWidth = endRatio.subtract(startRatio);
- const subdivisionWidth = totalWidth.divideRatio(
- Ratio.fromInteger(subdivisions),
- );
-
- const newDoc = mapRowsInRange(
- this.doc,
- selection.gridId,
- startCellRef,
- endCellRef,
- (row, rowRef) => {
- const newCells: Cell[] = [];
- let currentRatio = Ratio.fromInteger(0);
-
- for (const cell of row.cells) {
- const cellStart = currentRatio;
- const cellEnd = currentRatio.add(cell.widthRatio);
-
- // Cell is entirely before selection
- if (cellEnd.compare(startRatio) <= 0) {
- newCells.push(cell);
- currentRatio = cellEnd;
- continue;
- }
-
- // Cell is entirely after selection
- if (cellStart.compare(endRatio) >= 0) {
- newCells.push(cell);
- currentRatio = cellEnd;
- continue;
- }
-
- // First cell that overlaps - insert subdivisions
- if (newCells.length === 0 || currentRatio.compare(startRatio) < 0) {
- for (let i = 0; i < subdivisions; i++) {
- newCells.push({ widthRatio: subdivisionWidth });
- }
- }
-
- currentRatio = cellEnd;
- }
-
- return { ...row, cells: newCells };
- },
- );
-
- this.#doc = newDoc;
-
- this.#gridsById = Object.fromEntries(
- this.#doc.grids.map((grid) => [grid.id, renderGrid(grid)]),
- );
-
- window.dispatchEvent(
- new CustomEvent("ntv:grid:change", {
- detail: { gridId: selection.gridId },
- }),
- );
- }
-
- setCellValue(gridId: string, cellRef: CellRef, value: string | undefined) {
- const grid = this.doc.grids.find((grid) => grid.id === gridId);
-
- if (!grid) return;
-
- const cell =
- grid.parts[cellRef.partIndex].rows[cellRef.rowIndex].cells[
- cellRef.cellIndex
- ];
-
- grid.parts[cellRef.partIndex].rows[cellRef.rowIndex].cells[
- cellRef.cellIndex
- ] = { ...cell, value };
-
- this.#gridsById = Object.fromEntries(
- this.#doc.grids.map((grid) => [grid.id, renderGrid(grid)]),
- );
-
- window.dispatchEvent(
- new CustomEvent("ntv:grid:change", {
- detail: { gridId },
- }),
- );
- }
-}
-
-window.notive = new Notive();
+import "./components";