]> BookStack Code Mirror - bookstack/blob - resources/js/editor/menu/TableCreatorGrid.js
e545b3d0f5086229dd339198224a53a5f4bd8f20
[bookstack] / resources / js / editor / menu / TableCreatorGrid.js
1 import crel from "crelt"
2 import {prefix} from "./menu-utils";
3 import {insertTable} from "../commands";
4
5 class TableCreatorGrid {
6
7     constructor() {
8         this.gridItems = [];
9         this.size = 10;
10         this.label = null;
11     }
12
13     // :: (EditorView) → {dom: dom.Node, update: (EditorState) → bool}
14     // Renders the submenu.
15     render(view) {
16
17         for (let y = 0; y < this.size; y++) {
18             for (let x = 0; x < this.size; x++) {
19                 const elem = crel("div", {class: prefix + "-table-creator-grid-item"});
20                 this.gridItems.push(elem);
21                 elem.addEventListener('mouseenter', event => this.updateGridItemActiveStatus(elem));
22             }
23         }
24
25         const gridWrap = crel("div", {
26             class: prefix + "-table-creator-grid",
27             style: `grid-template-columns: repeat(${this.size}, 14px);`,
28         }, this.gridItems);
29
30         gridWrap.addEventListener('mouseleave', event => {
31             this.updateGridItemActiveStatus(null);
32         });
33         gridWrap.addEventListener('click', event => {
34             if (event.target.classList.contains(prefix + "-table-creator-grid-item")) {
35                 const {x, y} = this.getPositionOfGridItem(event.target);
36                 insertTable(y + 1, x + 1)(view.state, view.dispatch);
37             }
38         });
39
40         const gridLabel = crel("div", {class: prefix + "-table-creator-grid-label"});
41         this.label = gridLabel;
42         const wrap = crel("div", {class: prefix + "-table-creator-grid-container"}, [gridWrap, gridLabel]);
43
44         function update(state) {
45             return true;
46         }
47
48         return {dom: wrap, update}
49     }
50
51     /**
52      * @param {Element|null} newTarget
53      */
54     updateGridItemActiveStatus(newTarget) {
55         const {x: xPos, y: yPos} = this.getPositionOfGridItem(newTarget);
56
57         for (let y = 0; y < this.size; y++) {
58             for (let x = 0; x < this.size; x++) {
59                 const active = x <= xPos && y <= yPos;
60                 const index = (y * this.size) + x;
61                 this.gridItems[index].classList.toggle(prefix + "-table-creator-grid-item-active", active);
62             }
63         }
64
65         this.label.textContent = (xPos + yPos < 0) ? '' : `${xPos + 1} x ${yPos + 1}`;
66     }
67
68     /**
69      * @param {Element} gridItem
70      * @return {{x: number, y: number}}
71      */
72     getPositionOfGridItem(gridItem) {
73         const index = this.gridItems.indexOf(gridItem);
74         const y = Math.floor(index / this.size);
75         const x = index % this.size;
76         return {x, y};
77     }
78 }
79
80 export default TableCreatorGrid;