modern_spreadsheet/dist/main.cjs

6 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";var L=Object.defineProperty;var A=(r,e,t)=>e in r?L(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var s=(r,e,t)=>(A(r,typeof e!="symbol"?e+"":e,t),t);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class g{constructor(e,t){s(this,"x");s(this,"y");s(this,"width");s(this,"height");this.x=this.getXCoord(t.column,e),this.y=this.getYCoord(t.row,e),this.width=e.columns[t.column].width,this.height=e.rows[t.row].height}getXCoord(e,t){let o=0;for(let l=0;l<e;l++)o+=t.columns[l].width;return o}getYCoord(e,t){let o=0;for(let l=0;l<e;l++)o+=t.rows[l].height;return o}}class B{constructor(e){s(this,"element");s(this,"root");s(this,"handleKeydown",e=>{const{key:t}=e;switch(t){case"Escape":{this.hide();break}case"Enter":this.root.changeCellValues(this.root.selection.selectedCell,{value:this.element.value,displayValue:this.element.value}),this.hide()}});s(this,"handleClickOutside",e=>{const t=e.target;this.element.contains(t)||this.hide()});this.root=e;const t=document.createElement("input");t.classList.add(d+"editor"),this.element=t,this.hide()}hide(){this.element.style.display="none",this.element.classList.add("hide"),this.element.blur(),window.removeEventListener("click",this.handleClickOutside),this.element.removeEventListener("keydown",this.handleKeydown),this.root.focusTable()}show(e,t){const{height:o,width:l,x:n,y:i}=new g(this.root.config,e),c=this.root.getCell(e);this.element.classList.remove("hide"),this.element.style.top=i-this.root.viewport.top+"px",this.element.style.left=n-this.root.viewport.left+"px",this.element.style.width=l+"px",this.element.style.height=o+"px",this.element.style.display="block",window.addEventListener("click",this.handleClickOutside),this.element.addEventListener("keydown",this.handleKeydown),this.element.value=t||c.value,this.element.focus(),t||this.element.select()}}class D{constructor(e){s(this,"element");s(this,"root");this.root=e;const t=document.createElement("header");t.classList.add(),this.element=t}}class z{constructor(e){s(this,"element");s(this,"verticalScroller");s(this,"horizontalScroller");s(this,"root");s(this,"isSelecting",!1);s(this,"handleMouseMove",e=>{if(!this.isSelecting)return;const{offsetX:t,offsetY:o}=e,l=this.root.getCellByCoords(t,o);this.root.selection.selectedRange&&(this.root.selection.selectedRange.to=l),this.root.renderSheet()});s(this,"handleMouseUp",()=>{this.isSelecting=!1,this.root.selection.selectedRange&&this.root.selection.selectedRange.from.row===this.root.selection.selectedRange.to.row&&this.root.selection.selectedRange.from.column===this.root.selection.selectedRange.to.column&&(this.root.selection.selectedRange=null),this.root.renderSheet()});s(this,"handleDoubleClick",e=>{e.preventDefault();const t=this.root.getCellByCoords(e.offsetX,e.offsetY);this.root.showEditor(t)});s(this,"handleKeydown",e=>{if(console.log(e),["ArrowLeft","ArrowRight","ArrowUp","ArrowDown"].includes(e.key))switch(e.preventDefault(),this.root.selection.selectedRange=null,e.key){case"ArrowLeft":{this.root.selection.selectedCell&&this.root.selection.selectedCell.column>0&&(console.log("tick"),this.root.selection.selectedCell.column-=1,this.root.renderSheet());break}case"ArrowRight":{this.root.selection.selectedCell&&this.root.selection.selectedCell.column<this.root.config.columns.length-1&&(this.root.selection.selectedCell.column+=1,this.root.renderSheet());break}case"ArrowUp":{this.root.selection.selectedCell&&this.root.selection.selectedCell.row>0&&(this.root.selection.selectedCell.row-=1,this.root.renderSheet());break}case"ArrowDown":{this.root.selection.selectedCell&&this.root.selection.selectedCell.row<this.root.config.rows.length-1&&(this.root.selection.selectedCell.row+=1,this.root.renderSheet());break}}const t=/^([a-z]|[а-я])$/;if(!e.metaKey&&!e.ctrlKey){const o=t.test(e.key.toLowerCase());if(e.key==="F2"||o){if(e.preventDefault(),!this.root.selection.selectedCell)return;this.root.showEditor(this.root.selection.selectedCell,o?e.key:void 0)}}e.key==="Delete"&&(e.preventDefault(),this.root.deleteSelectedCellsValues(),this.root.renderSheet())});s(this,"handleClick",e=>{if(e.button!==0)return;const{offsetX:t,offsetY:o}=e,l=this.root.getCellByCoords(t,o);this.isSelecting=!0,this.root.selection.selectedRange={from:l,to:l},this.root.selection.selectedCell=l,this.root.renderSheet()});s(this,"handleScroll",()=>{const e=this.getViewportBoundlingRect();this.root.viewport.updateValues(e),this.root.renderSheet()});this.root=e;const{horizontalScroller:t,scroller:o,verticalScroller:l}=this.buildComponent();this.element=o,this.verticalScroller=l,this.horizontalScroller=t,this.element.style.height=this.root.config.view.height+"px",this.element.style.width=this.root.config.view.width+"px",this.element.tabIndex=-1,this.updateScrollerSize(),this.element.addEventListener("scroll",this.handleScroll),this.element.addEventListener("mousedown",this.handleClick),this.element.addEventListener("mousemove",this.handleMouseMove),this.element.addEventListener("mouseup",this.handleMouseUp),this.element.addEventListener("dblclick",this.handleDoubleClick),this.element.addEventListener("keydown",this.handleKeydown)}getViewportBoundlingRect(){const{scrollTop:e,scrollLeft:t}=this.element,{height:o,width:l}=this.element.getBoundingClientRect(),n=e+o,i=t+l;return{top:e,left:t,bottom:n,right:i}}buildComponent(){const e=document.createElement("div"),t=document.createElement("div"),o=document.createElement("div"),l=document.createElement("div"),n=document.createElement("div");return t.style.width="0px",t.style.pointerEvents="none",o.style.pointerEvents="none",l.style.display="flex",n.appendChild(t),n.appendChild(o),l.appendChild(n),this.verticalScroller=t,this.horizontalScroller=o,e.appendChild(l),e.classList.add(d+"scroller"),{scroller:e,verticalScroller:t,horizontalScroller:o}}getActualHeight(){return this.root.config.rows.reduce((e,t)=>(e+=t.height,e),0)}getActualWidth(){return this.root.config.columns.reduce((e,t)=>(e+=t.width,e),0)}updateScrollerSize(){const e=this.getActualHeight(),t=this.getActualWidth();this.setScrollerHeight(e),this.setScrollerWidth(t)}setScrollerHeight(e){this.verticalScroller.style.height=e+"px"}setScrollerWidth(e){this.horizontalScroller.style.width=e+"px"}}class S{constructor(e){s(this,"fontSize",16);s(this,"fontColor","black");s(this,"background","white");s(this,"borderColor","black");s(this,"selectedBackground","#4287f5");s(this,"selectedFontColor","#ffffff");e&&Object.assign(this,e)}}class v{constructor(e,t){s(this,"row");s(this,"column");this.row=e,this.column=t}}class R{constructor(e){s(this,"value");s(this,"displayValue");s(this,"resultValue");s(this,"position");s(this,"style");this.value=e.value,this.displayValue=e.displayValue,this.resultValue=e.resultValue,this.position=e.position,this.style=e.style}}class m{constructor(e){s(this,"value");s(this,"displayValue");s(this,"resultValue");s(this,"position");s(this,"style",null);this.value=e.value,this.displayValue=e.displayValue,this.resultValue=e.resultValue,this.position=e.position,this.style=e.style}getSerializableCell(){return new R({displayValue:this.displayValue,position:this.position,resultValue:this.resultValue,style:this.style,value:this.value})}changeStyles(e){this.style=e}changeValues(e){Object.assign(this,e)}isCellInRange(e){const{column:t,row:o}=this.position,{selectedRange:l}=e.selection;if(!l)return!1;const n=o>=Math.min(l.from.row,l.to.row)&&o<=Math.max(l.to.row,l.from.row);return t>=Math.min(l.from.column,l.to.column)&&t<=Math.max(l.to.column,l.from.column)&&n}render(e){var p;let{height:t,width:o,x:l,y:n}=new g(e.config,this.position);const{ctx:i}=e,c=((p=e.selection.selectedCell)==null?void 0:p.row)===this.position.row&&e.selection.selectedCell.column===this.position.column,h=this.isCellInRange(e);n-=e.viewport.top,l-=e.viewport.left;const a=this.style??e.styles.cells;i.clearRect(l,n,o,t),i.fillStyle=c||h?a.selectedBackground:a.background,i.strokeStyle="black",i.fillRect(l,n,o-1,t-1),i.strokeRect(l,n,o,t),i.fillStyle=c||h?a.selectedFontColor:a.fontColor,i.textAlign="left",i.font=`${a.fontSize}px Arial`,i.textBaseline="middle",i.fillText(this.displayValue,l+2,n+t/2)}}class M{constructor(e){s(this,"element");s(this,"ctx");s(this,"root");this.root=e;const t=document.createElement("canvas");t.classList.add(d+"sheet"),t.height=this.root.config.view.height,t.width=this.root.config.view.width,t.style.width=this.root.config.view.width+"px",t.style.height=this.root.config.view.height+"px",this.element=t;const o=this.element.getContext("2d");if(!o)throw new Error("Enable hardware acceleration");this.ctx=o}getCellByCoords(e,t){let o=0,l=0;for(;l<=t&&(l+=this.root.config.rows[o].height,!(l>=t));)o++;let n=0,i=0;for(;i<=e&&(i+=this.root.config.columns[n].width,!(i>=e));)n++;return new v(o,n)}renderCell(e){const{column:t,row:o}=e;this.root.data[o][t].render(this.root)}renderSheet(){const e=this.root.viewport.firstRow,t=this.root.viewport.lastCol+3,o=this.root.viewport.lastRow+3,l=this.root.viewport.firstCol;for(let n=e;n<=o;n++)for(let i=l;i<=t&&!(!this.root.config.columns[i]||!this.root.config.rows[n]);i++)this.renderCell({column:i,row:n})}}class P{constructor(e){s(this,"element");s(this,"root");this.root=e;const t=document.createElement("div");t.classList.add(d+"spreadsheet_container"),this.element=t,this.changeElementSizes(this.root.viewProps)}changeElementSizes(e){const{height:t,width:o}=e;this.element.style.width=o+"px",this.element.style.height=t+"px"}}class F{constructor(e){s(this,"element");s(this,"root");this.root=e;const t=document.createElement("div");t.classList.add(d+"toolbar"),this.element=t}}class u{constructor(e){s(this,"rows");s(this,"columns");s(this,"view",{width:800,height:600});this.columns=e.columns,this.rows=e.rows,this.view=e.view}}class x{constructor(){s(this,"selectedCell",null);s(this,"selectedRange",null)}}class b{constructor(){s(this,"cells");this.cells=new S}}class w{constructor(e,t){s(this,"root");s(this,"top");s(this,"left");s(this,"right");s(this,"bottom");s(this,"firstRow");s(this,"lastRow");s(this,"firstCol");s(this,"lastCol");this.root=e,this.top=t.top,this.left=t.left,this.right=t.right,this.bottom=t.bottom,this.firstRow=this.getFirstRow(),this.lastCol=this.getFirstRow();//!Temp
this.firstCol=this.getFirstRow();//!Temp
this.lastRow=this.getLastRow(),this.updateValues({top:0,left:0,right:this.root.viewProps.width,bottom:this.root.viewProps.height})}updateValues(e){this.top=e.top,this.left=e.left,this.right=e.right,this.bottom=e.bottom,this.firstRow=this.getFirstRow(),this.lastRow=this.getLastRow(),this.firstCol=this.getFirstCol(),this.lastCol=this.getLastCol()}getFirstRow(){return this.root.cache.getRowByYCoord(this.top)}getLastRow(){return this.root.cache.getRowByYCoord(this.bottom)}getFirstCol(){return this.root.cache.getColumnByXCoord(this.left)}getLastCol(){return this.root.cache.getColumnByXCoord(this.right)}}class f{constructor(e){s(this,"width");s(this,"title");this.width=e.width,this.title=e.title}}class C{constructor(e){s(this,"height");s(this,"title");this.height=e.height,this.title=e.title}}function y(r,e,t=!1){const o=[];for(let l=0;l<=r;l++){const n=[];for(let i=0;i<=e;i++){const c=t?`${l}:${i}`:"",h=new m({displayValue:c,resultValue:c,value:c,position:{column:i,row:l},style:null});n.push(h)}o.push(n)}return o}function k(r,e){const t=[];for(let n=0;n<=r;n++){const i=new C({height:40,title:String(n)});t.push(i)}const o=[];for(let n=0;n<=e;n++){const i=new f({title:String(n),width:150});o.push(i)}return new u({columns:o,rows:t,view:{height:600,width:800}})}function T(r,e){const t=y(r,e),o=k(r,e);return{data:t,config:o}}class V{constructor(e){s(this,"xPos");s(this,"colIdx");this.xPos=e.xPos,this.colIdx=e.colIdx}}class E{constructor(e){s(this,"yPos");s(this,"rowIdx");this.yPos=e.yPos,this.rowIdx=e.rowIdx}}class I{constructor(e){s(this,"columns");s(this,"rows");this.columns=e.columns,this.rows=e.rows}getRowByYCoord(e){let t=0;for(let o=0;o<this.rows.length;o++)if(e<=this.rows[o].yPos){t=o;break}return t}getColumnByXCoord(e){let t=0;for(let o=0;o<this.columns.length;o++)if(e<=this.columns[o].xPos){t=o;break}return t}}const d="modern_sc_";class X{constructor(e,t){s(this,"table");s(this,"scroller");s(this,"toolbar");s(this,"header");s(this,"sheet");s(this,"editor");s(this,"styles");s(this,"config");s(this,"data");s(this,"viewport");s(this,"selection");s(this,"cache");const o=y(40,40),l=this.makeConfigFromData(o,(t==null?void 0:t.view)??{height:600,width:800});t!=null&&t.view&&(l.view=t.view),this.config=new u(l),this.sheet=new M(this),this.table=new P(this),this.scroller=new z(this),this.toolbar=new F(this),this.header=new D(this),this.editor=new B(this),this.cache=this.getInitialCache(),this.viewport=new w(this,this.scroller.getViewportBoundlingRect()),this.selection=new x,this.data=o,this.styles=new b,this.buildComponent(),this.appendTableToTarget(e),this.renderSheet()}getInitialCache(){const e=[];let t=0;for(let i=0;i<=this.config.columns.length-1;i++){const c=this.config.columns[i];t+=c.width;const h=new V({xPos:t,colIdx:i});e.push(h)}const o=[];let l=0;for(let i=0;i<=this.config.rows.length-1;i++){const c=this.config.rows[i];l+=c.height;const h=new E({yPos:l,rowIdx:i});o.push(h)}const n=new I({columns:e,rows:o});return console.log("CACHE: ",n),console.log("CONFIG: ",this.config),n}buildComponent(){const e=document.createElement("div");e.appendChild(this.header.element),e.appendChild(this.sheet.element),e.classList.add(d+"content"),this.table.element.appendChild(this.toolbar.element),this.table.element.appendChild(e),this.table.element.appendChild(this.scroller.element),this.table.element.append(this.editor.element)}destroy(){this.table.element.remove()}appendTableToTarget(e){if(typeof e=="string"){const t=document.querySelector(e);if(!t)throw new Error(`Element with selector ${e} is not finded in DOM.
Make sure it exists.`);t==null||t.appendChild(this.table.element)}e instanceof HTMLElement&&e.append(this.table.element)}get ctx(){return this.sheet.ctx}get viewProps(){return this.config.view}focusTable(){this.scroller.element.focus()}getCellByCoords(e,t){return this.sheet.getCellByCoords(e,t)}getCell(e){const{column:t,row:o}=e;return this.data[o][t]}changeCellValues(e,t){const{column:o,row:l}=e;this.data[l][o].changeValues(t),this.renderCell(l,o)}changeCellStyles(e,t){const{column:o,row:l}=e;this.data[l][o].changeStyles(t),this.renderCell(l,o)}applyActionToRange(e,t){const o=Math.min(e.from.row,e.to.row),l=Math.max(e.from.row,e.to.row),n=Math.min(e.from.column,e.to.column),i=Math.max(e.from.column,e.to.column);for(let c=o;c<=l;c++)for(let h=n;h<=i;h++){const a=this.data[c][h];t(a)}}deleteSelectedCellsValues(){if(this.selection.selectedRange!==null)this.applyActionToRange(this.selection.selectedRange,e=>{this.changeCellValues(e.position,{displayValue:"",resultValue:"",value:""})});else{if(!this.selection.selectedCell)return;this.changeCellValues(this.selection.selectedCell,{displayValue:"",resultValue:"",value:""})}}showEditor(e,t){this.editor.show(e,t)}renderSheet(){this.sheet.renderSheet()}renderCell(e,t){this.data[e][t].render(this)}loadData(e){const t=e.length,o=e[0]?this.data[0].length:0;this.data=[];const l=[];for(let n=0;n<t;n++){const i=[];for(let c=0;c<o;c++){const h=e[n][c];i.push(new m({displayValue:h.displayValue,position:h.position,resultValue:h.resultValue,value:h.value,style:h.style}))}l.push(i)}return this.data=l,this.selection.selectedCell=null,this.selection.selectedRange=null,this.config=this.makeConfigFromData(l,this.config.view),this.cache=this.getInitialCache(),this.scroller.updateScrollerSize(),this.viewport=new w(this,this.scroller.getViewportBoundlingRect()),this.renderSheet(),this}makeConfigFromData(e,t){const o=e.length-1,l=e[0]?e[0].length:0,n=[];for(let h=0;h<o;h++)n.push(new C({height:40,title:String(h)}));const i=[];for(let h=0;h<l;h++)i.push(new f({width:150,title:String(h)}));return new u({view:t,rows:n,columns:i})}serializeData(){const e=this.data.length,t=this.data[0]?this.data[0].length:0,o=[];for(let l=0;l<e;l++){const n=[];for(let i=0;i<t;i++)n.push(this.data[l][i].getSerializableCell());o.push(n)}return o}}exports.CSS_PREFIX=d;exports.Cache=I;exports.CachedColumn=V;exports.CachedRow=E;exports.Cell=m;exports.CellStyles=S;exports.Column=f;exports.Config=u;exports.Position=v;exports.RenderBox=g;exports.Row=C;exports.Selection=x;exports.SerializableCell=R;exports.Styles=b;exports.Viewport=w;exports.createSampleConfig=k;exports.createSampleData=y;exports.default=X;exports.makeSpreadsheetConfigAndData=T;
//# sourceMappingURL=main.cjs.map