js-spread-grid 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/core/render.js +26 -1
- package/src/core/state.js +28 -8
- package/src/index.js +65 -5
- package/src/state-utils/getCellPlacement.js +48 -0
- package/src/state-utils/getContextFormatting.js +5 -0
- package/src/state-utils/getFormattingRules.js +2 -2
- package/src/state-utils/getHighlightedCells.js +2 -2
- package/src/state-utils/getInputPlacement.js +2 -45
- package/src/state-utils/getOrder.js +5 -0
- package/src/state-utils/getOrdered.js +32 -0
- package/src/state-utils/getReducedFormatting.js +11 -11
- package/src/state-utils/getRenderFormatting.js +11 -1
- package/src/state-utils/getReordered.js +69 -0
- package/src/state-utils/getResizable.js +6 -2
- package/src/state-utils/getResolved.js +0 -1
- package/src/state-utils/getTooltip.js +19 -0
- package/src/state-utils/getTooltipPlacement.js +16 -0
- package/src/types/FormattingRules.js +8 -0
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SpreadGrid=t():e.SpreadGrid=t()}(self,(()=>(()=>{"use strict";var e={d:(t,o)=>{for(var n in o)e.o(o,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:o[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function o(e){return null===e?"null":Array.isArray(e)?`[${e.map(o).join(",")}]`:"object"==typeof e?(t=e,`{${Object.keys(t).sort().map((e=>`${e}:${o(t[e])}`)).join(",")}}`):JSON.stringify(e);var t}function n(e,t){return"FILTER"===e.type^"FILTER"===t.type?"FILTER":"DATA"}function i(e,t,i,r){return e.map((e=>{const s=o(e.columnId),l=o(e.rowId);if(!i.has(s))return null;if(!r.has(l))return null;const d=i.get(s),a=r.get(l);return{edit:t.resolve(a,d).edit,cell:e,type:n(d,a)}})).filter((e=>e?.edit))}function r(e,t){return Math.round(e*t)/t}function s(e,t,o){const n=e.state,i=e.canvases[`${t}-${o}`],s=n.sections[t],l=n.sections[o],d=l.columns,a=s.rows;if(0===a.length||0===d.length)return void(i.parentElement&&i.parentElement.removeChild(i));i.parentElement||e.element.appendChild(i);const u=i.getContext("2d",{alpha:!1}),c=n.scrollRect,h=n.textResolver,f=n.renderFormatResolver,p=n.borderWidth,m=s.showTopBorder,g=s.showBottomBorder,y=l.showLeftBorder,w=l.showRightBorder,x=p/2,b=a.length-1+(m?1:0)+(g?1:0),v=d.length-1+(y?1:0)+(w?1:0),R=a.map((e=>e.height)),A=d.map((e=>e.width)),E=A.reduce(((e,t)=>e+t),0)+v*p,k=R.reduce(((e,t)=>e+t),0)+b*p,C="center"===o?c.left:0,I="middle"===t?c.top:0,T="center"===o?c.width:l.width,L="middle"===t?c.height:s.height,B=A.reduce(((e,t,o)=>{const n=e[o]+t+p;return e.push(n),e}),[y?p:0]),D=R.reduce(((e,t,o)=>{const n=e[o]+t+p;return e.push(n),e}),[m?p:0]),M=B.slice(0,-1),F=D.slice(0,-1),S=Math.max(M.findLastIndex((e=>e<=C)),0),z=M.findLastIndex((e=>e<=C+T)),N=Math.max(F.findLastIndex((e=>e<=I)),0),O=F.findLastIndex((e=>e<=I+L)),K=Math.max(S,y?0:1),H=z+(w?1:0),P=Math.max(N,m?0:1),W=O+(g?1:0),$=Array.from({length:O-N+1},((e,t)=>{const o=a[t+N];return Array.from({length:z-S+1},((e,t)=>{const n=d[t+S];return f.resolve(o,n)}))})),q=(e,t)=>$[e-N][t-S];i.width=Math.round(T*devicePixelRatio),i.height=Math.round(L*devicePixelRatio),i.style.width=`${T}px`,i.style.height=`${L}px`,i.style.marginLeft=`${C}px`,i.style.marginTop=`${I}px`,i.style.marginRight=E-T-C+"px",i.style.marginBottom=k-L-I+"px",u.fillStyle="#E9E9E9",u.fillRect(0,0,i.width,i.height);const V=(e,t)=>{u.setTransform(devicePixelRatio,0,0,devicePixelRatio,(e-C)*devicePixelRatio,(t-I)*devicePixelRatio)},j=(e,t,o,n)=>{u.beginPath(),u.rect(e,t,o,n),u.clip()};for(let e=S;e<=z;e++){u.save(),V(B[e],0),j(0,0,A[e],k);for(let t=N;t<=O;t++){const o=q(t,e),n=o.style,i=D[t],s=B[e],l=A[e],d=R[t],a=o.text,c=n.textBaseline||"middle",f=o.padding;if(V(s,i),u.fillStyle=n.background||"white",u.fillRect(0,0,l,d),"draw"in o&&o.draw(u),n.highlight&&(u.fillStyle=n.highlight,u.fillRect(0,0,l,d)),n.corner&&(u.fillStyle=n.corner,u.beginPath(),u.moveTo(l-7,d),u.lineTo(l,d),u.lineTo(l,d-7),u.fill()),a){u.fillStyle=n.foreground||"black",u.font=o.font;const e=h.getFontMetrics(o.font),t="center"==n.textAlign&&h.measureWidth(a,o.font)>l-f.left-f.right?"left":n.textAlign||"left";u.textAlign=t;const i=r("left"===t?f.left:"center"===t?l/2:"right"===t?l-f.right:0,devicePixelRatio),s=r("top"===c?e.middle+e.topOffset+f.top:"middle"===c?d/2+e.middle:"bottom"===c?d+e.middle-e.bottomOffset-f.bottom:0,devicePixelRatio);s-e.middle-e.topOffset>=0&&s-e.middle+e.bottomOffset<=d?u.fillText(a,i,s):(u.strokeStyle="#E9E9E9",u.lineWidth=p,u.beginPath(),u.moveTo(0,p+x),u.lineTo(l,p+x),u.moveTo(0,d-p-x),u.lineTo(l,d-p-x),u.stroke(),u.save(),j(0,2*p,l,d-4*p),u.fillText(a,i,s),u.restore())}}u.restore()}V(0,0);const G=(e,t,o,n,i)=>{if(!i)return;if(0===i.width)return;const r=i.width/devicePixelRatio,s=t===n,l=e-(s?r/2:0),d=t-(s?0:r/2),a=o+(s?r/2:0),c=n+(s?0:r/2);u.strokeStyle=i.color||"black",u.lineWidth=r,i.dash?(u.setLineDash(i.dash.map((e=>e/devicePixelRatio))),u.lineDashOffset=s?l:d):u.setLineDash([]),u.beginPath(),u.moveTo(l,d),u.lineTo(a,c),u.stroke()},Y=(e,t)=>e?t?e.index>t.index?e:t:e:t;for(let e=P;e<=W;e++){const t=e-1,o=e;for(let e=S;e<=z;e++){const n=Y(t>=N?q(t,e).style.borderBottom:null,o<=O?q(o,e).style.borderTop:null);G(B[e]-x,D[o]-x,B[e+1]-x,D[o]-x,n)}}for(let e=K;e<=H;e++){const t=e-1,o=e;for(let e=N;e<=O;e++){const n=Y(t>=S?q(e,t).style.borderRight:null,o<=z?q(e,o).style.borderLeft:null);G(B[o]-x,D[e]-x,B[o]-x,D[e+1]-x,n)}}}function l(e){if(!e.error)try{!function(e){s(e,"top","left"),s(e,"top","center"),s(e,"top","right"),s(e,"middle","left"),s(e,"middle","center"),s(e,"middle","right"),s(e,"bottom","left"),s(e,"bottom","center"),s(e,"bottom","right"),function(e){const t=e.element,o=e.input,n=e.state,i=n.inputPlacement;if(!i){if(o.parentElement){const e=document.activeElement===o;o.parentElement.removeChild(o),e&&t.focus({preventScroll:!0})}return}const r=e.canvases[i.section];if(o.style.left="left"in i?`${i.left}px`:"0",o.style.top="top"in i?`${i.top}px`:"0",o.style.right="right"in i?`${i.right}px`:"0",o.style.bottom="bottom"in i?`${i.bottom}px`:"0",o.style.marginLeft="marginLeft"in i?`${i.marginLeft}px`:"0",o.style.marginTop="marginTop"in i?`${i.marginTop}px`:"0",o.style.width=`${i.width}px`,o.style.height=`${i.height}px`,o.style.gridArea=r.style.gridArea,o.style.zIndex=r.style.zIndex,o.style.backgroundColor=n.isTextValid?"white":"#eb3434",!o.parentElement){const e=document.activeElement===t;t.appendChild(o),e&&o.focus({preventScroll:!0})}}(e),function(e){const t=e.element,o=e.state;o.resizableColumn&&o.resizableRow?t.style.cursor="nwse-resize":o.resizableColumn?t.style.cursor="col-resize":o.resizableRow?t.style.cursor="row-resize":t.style.cursor="default"}(e)}(e)}catch(t){e.error=t}e.error&&function(e){if(e.errorRendered)return;e.errorRendered=!0;const t=e.element,o=e.error;t.style.backgroundColor="#9f0000",t.style.color="white",t.style.padding="20px",t.style.display="flex",t.style.flexDirection="column",t.style.userSelect="text",t.innerHTML=`\n <div style="font-size: 16px;">\n An error occurred while rendering the grid, please contact the support.\n </div>\n <div style="font-size: 20px; font-weight: bold; padding: 20px 0;">\n ${o.message}\n </div>\n <div style="font-size: 16px; white-space: pre-wrap;">${o.stack}</div>\n `}(e)}e.d(t,{default:()=>Ve});const d={value:({newValue:e})=>e||"",text:({newValue:e})=>e||"Search...",edit:{validate:()=>!0,parse:({string:e})=>e,autoCommit:!0}};function a(e,t,o){return[{column:{type:"DATA"},row:{type:"HEADER"},value:({column:e})=>void 0===e.header?e.id:e.header},{column:{type:"HEADER"},row:{type:"DATA"},value:({row:e})=>void 0===e.header?e.id:e.header},{column:{type:"HEADER"},row:{type:"SPECIAL"},value:""},{column:{type:"SPECIAL"},row:{type:"HEADER"},value:""},{column:{type:"DATA"},row:{type:"FILTER"},...d},{column:{type:"FILTER"},row:{type:"DATA"},...d},{column:{type:"DATA"},row:{type:"DATA"},value:t},...e,...o.map((({columnId:e,rowId:t,direction:n},i)=>({column:{id:e},row:{id:t},text:({value:e,text:t})=>`${o.length>1?i+1:""}${"ASC"===n?"⇣":"⇡"} ${t||e}`})))]}const u=["column","row","condition"];function c(e){return Object.keys(e).length>Object.keys(e).filter((e=>u.includes(e))).length}function h(e,t){const o=[...u,...t];return e.map((e=>function(e,t){const o={};for(const n of t)n in e&&(o[n]=e[n]);return o}(e,o))).filter(c)}function f(e){return h(e,["value","text","edit"])}function p(e,t){return t?e+"99":e+"33"}function m(e,t,n,i,r,s,l,d,a,u){const c=n?o(n.columnId):null,h=n?o(n.rowId):null,f=null!==a,m=null!==d||f,g=u+2,y=u+4,w=(e,t,o,n)=>{if(o<0||o>=e.length)return!1;if(n<0||n>=t.length)return!1;const r=e[o].key,s=t[n].key;return i.isKeySelected(r,s)},x=(e,t)=>e?[t]:[];return[{column:{type:"DATA"},row:{type:"FILTER"},style:({newValue:e})=>({background:"#FBFBFB",foreground:e?"black":"#cccccc",border:{width:1,color:"gray"}})},{column:{type:"FILTER"},row:{type:"DATA"},style:({newValue:e})=>({background:"#FBFBFB",foreground:e?"black":"#cccccc",border:{width:1,color:"gray"}})},{column:{type:"ANY"},row:{type:"HEADER"},style:{background:"#F5F5F5",border:{width:u,color:"gray"}}},{column:{type:"HEADER"},row:{type:"ANY"},style:{background:"#F5F5F5",border:{width:u,color:"gray"}}},{column:{type:"HEADER"},row:{type:"HEADER"},style:{background:"#E0E0E0"}},...e,...x(t&&!f,{column:{type:"ANY"},row:{id:t?.rowId},style:{highlight:"#81948133"}}),...x(t&&!m,{column:{id:t?.columnId},row:{id:t?.rowId},style:{highlight:"#81948188"}}),{column:{type:"ANY"},row:{type:"ANY"},condition:({rows:e,columns:t,row:o,column:n})=>w(e,t,o.index,n.index),style:({rows:e,columns:t,row:o,column:n,edit:i})=>({...w(e,t,o.index-1,n.index)?{}:{borderTop:{width:g,color:"#596959",index:Number.MAX_SAFE_INTEGER}},...w(e,t,o.index+1,n.index)?{}:{borderBottom:{width:g,color:"#596959",index:Number.MAX_SAFE_INTEGER}},...w(e,t,o.index,n.index-1)?{}:{borderLeft:{width:g,color:"#596959",index:Number.MAX_SAFE_INTEGER}},...w(e,t,o.index,n.index+1)?{}:{borderRight:{width:g,color:"#596959",index:Number.MAX_SAFE_INTEGER}},highlight:p(i?"#798d9c":"#819481",c!==n.key||h!==o.key)})},{column:{type:"ANY"},row:{type:"ANY"},condition:({row:e,column:t})=>r.isKeySelected(e.key,t.key),style:({row:e,column:t})=>({highlight:p("#93a8b8",c!==t.key||h!==e.key)})},...x(n,{column:{id:n?.columnId},row:{id:n?.rowId},style:{highlight:"#ffffffaa"}}),...l.map((({columnId:e,rowId:t,direction:o},n)=>({column:{id:e},row:{id:t},style:{highlight:"#0377fc44"}}))),{column:{type:"ANY"},row:{type:"ANY"},condition:({edit:e})=>e,style:{corner:"#77777720"}},{column:{type:"ANY"},row:{type:"ANY"},condition:({row:e,column:t})=>s.hasValueByKey(e.key,t.key),style:{corner:"darkgreen"}},...x(d,{column:{id:d},row:{type:"HEADER"},style:{borderRight:{width:y,color:"cornflowerblue"}}}),...x(a,{column:{type:"HEADER"},row:{id:a},style:{borderBottom:{width:y,color:"cornflowerblue"}}})]}function g(e,t){const o=t.filter((e=>"BEGIN"===e.pinned)).length,n=t.filter((e=>"END"===e.pinned)).length,i=t.length-o-n,r=e.filter((e=>"BEGIN"===e.pinned)).length,s=e.filter((e=>"END"===e.pinned)).length,l=e.length-r-s,d=t.slice(0,o),a=t.slice(t.length-n,t.length),u=t.slice(o,t.length-n),c=e.slice(0,r),h=e.slice(e.length-s,e.length),f=e.slice(r,e.length-s),p=o>0,m=r>0,g=!0,y=!0,w=i>0||!p,x=!0,b=!p,v=!(n>0),R=!0,A=!0,E=l>0||!m,k=!0,C=!m,I=!(s>0),T=(e,t,o)=>{if(0===e.length)return 0;const n=t?e.at(0).topWithBorder:e.at(0).top;return(o?e.at(-1).bottomWithBorder:e.at(-1).bottom)-n},L=(e,t,o)=>{if(0===e.length)return 0;const n=t?e.at(0).leftWithBorder:e.at(0).left;return(o?e.at(-1).rightWithBorder:e.at(-1).right)-n};return{top:{rows:d,showTopBorder:g,showBottomBorder:y,height:T(d,g,y)},bottom:{rows:a,showTopBorder:w,showBottomBorder:x,height:T(a,w,x)},middle:{rows:u,showTopBorder:b,showBottomBorder:v,height:T(u,b,v)},left:{columns:c,showLeftBorder:R,showRightBorder:A,width:L(c,R,A)},right:{columns:h,showLeftBorder:E,showRightBorder:k,width:L(h,E,k)},center:{columns:f,showLeftBorder:C,showRightBorder:I,width:L(f,C,I)}}}function y(e,t){return[...e,...t.map((e=>({columnId:e.columnId,rowId:e.rowId,value:e.expression})))]}class w{constructor(e){this.lookup=new Map,e.forEach((e=>{const t=o(e.rowId),n=o(e.columnId);this.lookup.has(t)||this.lookup.set(t,new Map),this.lookup.get(t).set(n,e.value)}))}hasValueByKey(e,t){return this.lookup.has(e)&&this.lookup.get(e).has(t)}getValueByKey(e,t){if(this.hasValueByKey(e,t))return this.lookup.get(e).get(t)}hasValueById(e,t){return this.hasValueByKey(o(e),o(t))}getValueById(e,t){return this.getValueByKey(o(e),o(t))}}function x(e){return new w(e)}class b{constructor(e){this.lookup=new Map,e.forEach((e=>{const t=o(e.rowId),n=o(e.columnId);this.lookup.has(t)||this.lookup.set(t,new Set),this.lookup.get(t).add(n)}))}isKeySelected(e,t){return this.lookup.has(e)&&this.lookup.get(e).has(t)}isIdSelected(e,t){return this.isKeySelected(o(e),o(t))}}function v(e){return new b(e)}function R(e,t){return"function"==typeof e?e(t):e}function A(e,t,o,n){return e<o?"BEGIN":e>=t-n?"END":void 0}function E(e,t,n){return e.map(((i,r)=>{const s="id"in i?i.id:i.type;return{...i,id:s,type:i.type||"DATA",index:r,key:o(s),pinned:A(r,e.length,t,n),header:"header"in i?i.header:s,labels:i.labels||[]}}))}function k(e,t,n,i){const r=new Map(i.map((({columnId:e,width:t})=>[o(e),t])));return E(e,t,n).map((e=>({...e,width:r.has(e.key)?r.get(e.key):"width"in e?e.width:"fit"})))}function C(e,t,n,i){const r=new Map(i.map((({rowId:e,height:t})=>[o(e),t])));return E(e,t,n).map((e=>({...e,height:r.has(e.key)?r.get(e.key):"height"in e?e.height:"fit"})))}function I(e,t,o){let n=o;return e.map(((e,i)=>{const s=r("width"in e?e.width:100,t),l={...e,index:i,width:s,leftWithBorder:n-o,left:n,right:n+s,rightWithBorder:n+s+o};return n+=l.width+o,l}))}function T(e,t,o){let n=o;return e.map(((e,i)=>{const s=r("height"in e?e.height:20,t),l={...e,index:i,height:s,topWithBorder:n-o,top:n,bottom:n+s,bottomWithBorder:n+s+o};return n+=l.height+o,l}))}const L="12px Calibri",B={top:2,right:5,bottom:2,left:5},D={HEADER:["HEADER"],FILTER:["FILTER"],DATA:["DATA"],CUSTOM:["CUSTOM"],ANY:["HEADER","DATA","FILTER","CUSTOM"],SPECIAL:["HEADER","FILTER","CUSTOM"],undefined:[]};class M{byKey=new Map;byIndex=new Map;byLabel=new Map;byType=new Map}class F{lookup=new M;hasRules=!1;addRule(e,t,n){if(this.hasRules=!0,Array.isArray(e))for(const o of e)this.addRule(o,t,n);else if(Array.isArray(t))for(const o of t)this.addRule(e,o,n);else{e=e?"id"in e?{key:o(e.id)}:e:{type:"DATA"},t=t?"id"in t?{key:o(t.id)}:t:{type:"DATA"},"key"in e&&r(this.lookup.byKey,e.key),"index"in e&&r(this.lookup.byIndex,e.index),"label"in e&&r(this.lookup.byLabel,e.label);for(const t of D[e.type])r(this.lookup.byType,t)}function i(e,t){e.has(t)||e.set(t,[]),e.get(t).push(n)}function r(e,o){e.has(o)||e.set(o,new M),"key"in t&&i(e.get(o).byKey,t.key),"index"in t&&i(e.get(o).byIndex,t.index),"label"in t&&i(e.get(o).byLabel,t.label);for(const n of D[t.type])i(e.get(o).byType,n)}}getRules(e,t){const o=[];if(!this.hasRules)return o;function n(e){for(const t of e)o.push(t)}function i(e){e.byKey.has(t.key)&&n(e.byKey.get(t.key)),e.byIndex.has(t.index)&&n(e.byIndex.get(t.index)),e.byType.has(t.type)&&n(e.byType.get(t.type));for(const o of t.labels)e.byLabel.has(o)&&n(e.byLabel.get(o))}this.lookup.byKey.has(e.key)&&i(this.lookup.byKey.get(e.key)),this.lookup.byIndex.has(e.index)&&i(this.lookup.byIndex.get(e.index)),this.lookup.byType.has(e.type)&&i(this.lookup.byType.get(e.type));for(const t of e.labels)this.lookup.byLabel.has(t)&&i(this.lookup.byLabel.get(t));return o}}const S=["borderTop","borderRight","borderBottom","borderLeft"],z={validate:()=>!0,parse:({string:e})=>e};function N(e,t){const o={...e};if("border"in o){for(const e of S)o[e]=o.border;delete o.border}for(const e of S)e in o&&(o[e]={...o[e],index:t});return o}function O(e,t){if(!1!==e.edit)return!0===e.edit?"edit"in t?t.edit:z:"edit"in t?{...t.edit,...e.edit}:{...z,...e.edit}}class K{constructor(e){this.rulesLookup=new F;for(const[t,o]of e.entries()){const e={index:t};"condition"in o&&(e.condition=o.condition),"style"in o&&(e.style="function"==typeof o.style?o.style:()=>o.style),"value"in o&&(e.value="function"==typeof o.value?o.value:()=>o.value),"text"in o&&(e.text="function"==typeof o.text?o.text:()=>o.text),"font"in o&&(e.font="function"==typeof o.font?o.font:()=>o.font),"padding"in o&&(e.padding="function"==typeof o.padding?o.padding:()=>o.padding),"edit"in o&&(e.edit=o.edit),"draw"in o&&(e.draw=o.draw),this.rulesLookup.addRule(o.column,o.row,e)}}resolve(e,t,o,n,i,r){const s=this.rulesLookup.getRules(i,n).sort(((e,t)=>e.index-t.index)).filter(((e,t,o)=>e.index!==o[t-1]?.index));let l,d={data:e,rows:t,columns:o,row:n,column:i},a={},u=B,c=L;r.hasValueByKey(n.key,i.key)&&(d={...d,newValue:r.getValueByKey(n.key,i.key)});for(const e of s)if((!("condition"in e)||e.condition(d))&&("value"in e&&(d={...d,value:e.value(d)}),"style"in e&&(a={...a,...N(e.style(d),e.index)}),"text"in e&&(d={...d,text:e.text(d)}),"font"in e&&(c=e.font(d)),"padding"in e&&(u={...u,...e.padding(d)}),"edit"in e&&(d={...d,edit:O(e,d)}),"draw"in e)){const t=d;l=o=>e.draw({...t,ctx:o})}const h=function(e){return"text"in e?`${e.text}`:"newValue"in e?`${e.newValue}`:void 0!==e.value?`${e.value}`:""}(d),f={style:a,visible:!0,text:h,padding:u,font:c};return"value"in d&&(f.value=d.value),"edit"in d&&void 0!==d.edit&&(f.edit=d.edit),void 0!==l&&(f.draw=l),f}}function H(e){return new K(e)}class P{constructor(e,t,o,n,i){this.formattingRules=e,this.data=t,this.rows=o,this.columns=n,this.edition=i}resolve(e,t){return this.formattingRules.resolve(this.data,this.rows,this.columns,e,t,this.edition)}}function W(e,t,o,n,i){return new P(e,t,o,n,i)}function $(e,t,n){const i=new Map;for(const r of e){const e=o(r[t]),s=o(r[n]);i.has(e)||i.set(e,new Map),i.get(e).set(s,r.expression)}return i}function q(e,t,o,n,i,r,s){if(0===e.length)return i;const l=$(e,"columnId","rowId"),d=r.filter((e=>"FILTER"!==e.type&&l.has(e.key)));return 0===d.length?i:i.filter((e=>{for(const a of d){const d=o.resolve(n,i,r,e,a,s),u=l.get(a.key);if(!t.resolve(n,i,r,e,a,d.value,d.text,u))return!1}return!0}))}function V(e,t,o,n,i,r,s){if(0===e.length)return r;const l=$(e,"rowId","columnId"),d=i.filter((e=>"FILTER"!==e.type&&l.has(e.key)));return 0===d.length?r:r.filter((e=>{for(const a of d){const d=o.resolve(n,i,r,a,e,s),u=l.get(a.key);if(!t.resolve(n,i,r,a,e,d.value,d.text,u))return!1}return!0}))}function j(e,t,o,n){return{top:e,bottom:t,left:o,right:n}}function G(e,t){return{width:e.length?e.at(-1).rightWithBorder:0,height:t.length?t.at(-1).bottomWithBorder:0}}class Y{constructor(){this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),this.fontMetrics=new Map}measureWidth(e,t){if(!e)return 0;const o=this.context;return o.font=t||L,o.measureText(e).width}measureHeight(e,t){let o=1;for(const t of e)"\n"===t&&o++;return o*this.getFontMetrics(t).height}getFontMetrics(e){const t=e;if(this.fontMetrics.has(t))return this.fontMetrics.get(t);const o=this.context;o.font=e||L;const n=o.measureText("X"),i=(n.actualBoundingBoxDescent-n.actualBoundingBoxAscent)/2,r={topOffset:i+n.fontBoundingBoxAscent,middle:-i,bottomOffset:n.fontBoundingBoxDescent-i,height:n.fontBoundingBoxAscent+n.fontBoundingBoxDescent};return this.fontMetrics.set(t,r),r}}function U(){return new Y}function _(e,t){return t.top>=e.top&&t.left>=e.left&&t.top+t.height<=e.top+e.height&&t.left+t.width<=e.left+e.width}function X(e,t){const o={top:Math.max(e.top,t.top),left:Math.max(e.left,t.left),width:Math.min(e.left+e.width,t.left+t.width)-Math.max(e.left,t.left),height:Math.min(e.top+e.height,t.top+t.height)-Math.max(e.top,t.top)};return o.width>=0&&o.height>=0?o:{top:e.top,left:e.left,width:0,height:0}}function J(e,t){return{top:e.top-t,left:e.left-t,width:e.width+2*t,height:e.height+2*t}}function Q(e){return e.width*e.height}function Z(e,t){return{top:e.top,left:e.left,width:Math.max(0,e.width-t.left-t.right),height:Math.max(0,e.height-t.top-t.bottom)}}const ee=200,te=400,oe={left:0,top:0,width:0,height:0};function ne(e,t,o,n){const i=t.x,r=t.y,s=e.scrollLeft,l=e.scrollTop,d=e.clientWidth,a=e.clientHeight;return{x:i<=o.left?i:i>=d?i+s:i>=d-o.right?n.width-d+i:i+s,y:r<=o.top?r:r>=a?r+l:r>=a-o.bottom?n.height-a+r:r+l}}function ie(e){return e.reduce(((e,t)=>e.set(t.key,t)),new Map)}function re(e,t,n,i,r,s,l,d){if(!e)return[];if(t)return[];if(!i)return[];if(!n)return[];const a=o(n.columnId),u=o(n.rowId),c=o(i.columnId),h=o(i.rowId);if(!l.has(a))return[];if(!d.has(u))return[];if(!l.has(c))return[];if(!d.has(h))return[];const f=Math.min(l.get(a).index,l.get(c).index),p=Math.max(l.get(a).index,l.get(c).index),m=Math.min(d.get(u).index,d.get(h).index),g=Math.max(d.get(u).index,d.get(h).index);return r.slice(f,p+1).flatMap((e=>s.slice(m,g+1).map((t=>({rowId:t.id,columnId:e.id})))))}function se(e,t){const o=function(e){return"BEGIN"===e.pinned?"top":"END"===e.pinned?"bottom":"middle"}(t),n=function(e){return"BEGIN"===e.pinned?"left":"END"===e.pinned?"right":"center"}(e);return`${o}-${n}`}function le(e,t,n,i,r){if(!t)return null;const s=o(t.columnId),l=o(t.rowId);if(!n.has(s))return null;if(!i.has(l))return null;const d=n.get(s),a=i.get(l);if(0===e.length)return null;const u={width:d.width,height:a.height,section:se(d,a)};switch(a.pinned){case"BEGIN":u.top=a.top;break;case"END":u.bottom=r.top.height+r.middle.height+r.bottom.height-a.top-a.height;break;default:u.marginTop=a.top-r.top.height}switch(d.pinned){case"BEGIN":u.left=d.left;break;case"END":u.right=r.left.width+r.center.width+r.right.width-d.left-d.width;break;default:u.marginLeft=d.left-r.left.width}return u}function de(e,t){return t.every((t=>t.edit.validate({string:e})))}function ae(e){return Array.isArray(e)?e.map(((e,t)=>t)):Object.keys(e)}function ue(e){return ae(e)}function ce(e){const t=new Set;if(Array.isArray(e))for(const o of e)for(const e of ae(o))t.add(e);else for(const o in e)for(const n of ae(e[o]))t.add(n);return[...t]}function he(e,t){if(!e.some((e=>"DATA-BLOCK"===e.type)))return e;const o=[];for(const n of e)if("DATA-BLOCK"===n.type){const e="selector"in n?n.selector(t):ce(t);for(const t of e)o.push({...n,id:t,type:"DATA"})}else o.push(n);return o}function fe(e,t){if(!e.some((e=>"DATA-BLOCK"===e.type)))return e;const o=[];for(const n of e)if("DATA-BLOCK"===n.type){const e="selector"in n?n.selector(t):ue(t);for(const t of e)o.push({...n,id:t,type:"DATA"})}else o.push(n);return o}const pe=({text:e,expression:t})=>e.includes(t);class me{constructor(e){this.rulesLookup=new F;for(const t of e){const e={by:o("by"in t?t.by:"FILTER"),condition:t.condition||pe};this.rulesLookup.addRule(t.column,t.row,e)}}resolve(e,t,o,n,i,r,s,l){const d=this.rulesLookup.getRules(i,n);if(0===d.length)return"DATA"!==n.type||"DATA"!==i.type||!l.has('"FILTER"')||pe({text:s,expression:l.get('"FILTER"')});let a={data:e,rows:t,columns:o,row:n,column:i,value:r,text:s};for(const e of d){if(!l.has(e.by))continue;const t={...a,expression:l.get(e.by)};if(!e.condition(t))return!1}return!0}}function ge(e){return new me(e)}function ye(e){return h(e,["value","text"])}function we(e){return h(e,["value","text","font","padding"])}function xe(e,t,o,n,i,r){if(e.every((e=>"number"==typeof e.width)))return e;const s=e=>{const r=e.width;if("number"==typeof r)return r;if(i.has(e.key)){const t=i.get(e.key);if("fit-once"===r&&!t.dataOnly)return t.width;if("fit-data-once"===r&&t.dataOnly)return t.width}let s=0;for(const i of t){if("DATA"!==i.type&&"fit-data-once"===r)continue;if("DATA"!==i.type&&"fit-data"===r)continue;const t=n.resolve(i,e),l=t.text,d=t.font,a=t.padding.left+t.padding.right,u=o.measureWidth(l,d)+a;s=Math.max(s,u)}return i.set(e.key,{width:s,dataOnly:"fit-data-once"===r}),s};for(const e of i.keys())r.has(e)||i.delete(e);return e.map((e=>({...e,width:s(e)})))}function be(e,t,o,n,i,r){if(t.every((e=>"number"==typeof e.height)))return t;const s=t=>{const r=t.height;if("number"==typeof r)return r;if(i.has(t.key)){const e=i.get(t.key);if("fit-once"===r&&!e.dataOnly)return e.height;if("fit-data-once"===r&&e.dataOnly)return e.height}let s=0;for(const i of e){if("DATA"!==i.type&&"fit-data-once"===r)continue;if("DATA"!==i.type&&"fit-data"===r)continue;const e=n.resolve(t,i),l=e.text,d=e.font,a=e.padding.top+e.padding.bottom,u=o.measureHeight(l,d)+a;s=Math.max(s,u)}return i.set(t.key,{height:s,dataOnly:"fit-data-once"===r}),s};for(const e of i.keys())r.has(e)||i.delete(e);return t.map((e=>({...e,height:s(e)})))}function ve(e){return new Set(e.map((e=>e.key)))}function Re(e){return h(e,["value","text"])}function Ae(e,t){return null!=e.value&&(null==t.value||e.value<t.value)}function Ee(e,t){return null!=e.value&&(null==t.value||e.value>t.value)}class ke{constructor(e){this.rulesLookup=new F;for(const t of e){const e=t.comparator?(e,o)=>t.comparator(e,o):(e,t)=>Ae(e,t),n=t.comparator?(e,o)=>!t.comparator(e,o):(e,t)=>Ee(e,t),i={by:o("by"in t?t.by:"HEADER"),comparatorAsc:e,comparatorDesc:n};this.rulesLookup.addRule(t.column,t.row,i)}}resolve(e,t,o){const n=this.rulesLookup.getRules(e,t);if(0===n.length)return"DATA"!==t.type||"DATA"!==e.type?null:o.has('"HEADER"')?"ASC"===o.get('"HEADER"')?Ae:Ee:null;if(n.length>1)throw new Error("Multiple sorting rules for the same cell");const i=n[0];return o.has(i.by)?"ASC"===o.get(i.by)?i.comparatorAsc:i.comparatorDesc:null}}function Ce(e){return new ke(e)}function Ie(e,t,n){const i=new Map;for(const r of e){const e=o(r[t]),s=o(r[n]);i.has(e)||i.set(e,new Map),i.get(e).set(s,r.direction)}return i}function Te(e,t){e.sort(((e,t)=>{const o=e.comparator(e.cell,t.cell);return"number"==typeof o?o:o?-1:1})),t.push(...e.map((e=>e.entity))),e.length=0}function Le(e,t,n,i,r,s,l){if(0===e.length)return r;const d=Ie(e,"columnId","rowId"),a=new Map(s.map((e=>[e.key,e]))),u=e.map((e=>o(e.columnId))).filter((e=>a.has(e))).map((e=>a.get(e))).reverse();if(0===u.length)return r;for(const e of u){const o=[],a=[];for(const u of r){const c=t.resolve(e,u,d.get(e.key));if(!c){Te(a,o),o.push(u);continue}const h={entity:u,comparator:c,cell:n.resolve(i,r,s,u,e,l)};0!==a.length&&a[0].comparator!==c?(Te(a,o),a.push(h)):a.push(h)}Te(a,o),r=o}return r}function Be(e,t,n,i,r,s,l){if(0===e.length)return s;const d=Ie(e,"rowId","columnId"),a=new Map(r.map((e=>[e.key,e]))),u=e.map((e=>o(e.rowId))).filter((e=>a.has(e))).map((e=>a.get(e))).reverse();if(0===u.length)return s;for(const e of u){const o=[],a=[];for(const u of s){const c=t.resolve(u,e,d.get(e.key));if(!c){Te(a,o),o.push(u);continue}const h={entity:u,comparator:c,cell:n.resolve(i,r,s,e,u,l)};0!==a.length&&a[0].comparator!==c?(Te(a,o),a.push(h)):a.push(h)}Te(a,o),s=o}return s}const De=5;function Me(e,t,n,i,r,s,l,d){if(!i)return null;const a=t.get(o(i.columnId));if("HEADER"!==n.get(o(i.rowId)).type)return null;const u=ne(r,s,l,d);if(!u)return null;const c=u.x;return c>=a.right-De&&c<=a.right+De?a.id:0===a.index||c<a.left-De||c>a.left+De?null:e[a.index-1].id}function Fe(e,t,n,i,r,s,l,d){if(!i)return null;const a=t.get(o(i.columnId)),u=n.get(o(i.rowId));if("HEADER"!==a.type)return null;const c=ne(r,s,l,d);if(!c)return null;const h=c.y;return h>=u.bottom-De&&h<=u.bottom+De?u.id:0===u.index||h<u.top-De||h>u.top+De?null:e[u.index-1].id}function Se(e){return e.map((e=>({columnId:"columnId"in e?e.columnId:"HEADER",rowId:"rowId"in e?e.rowId:"HEADER",direction:e.direction})))}function ze(e){return e.map((e=>({columnId:"columnId"in e?e.columnId:"FILTER",rowId:"rowId"in e?e.rowId:"FILTER",expression:e.expression})))}function Ne(e,t){return function(e,t){const o=e.filter((e=>"DATA"===e.type)).map((e=>e.id));return t(o),o}(e,t)}function Oe(e){const t={...e.localOptions,...e.externalOptions},o=e.memory,n=e.state,r=e.element;function s(e,t,n){const i=o[e]&&o[e].dependencies;return i&&!n.some(((e,t)=>e!==i[t]))||(o[e]={value:t(...n),dependencies:n}),o[e].value}const l=window.devicePixelRatio,d=t.borderWidth/l,u=t.data,c=e.input.value,h=s("sortBy",Se,[t.sortBy]),p=s("filters",ze,[t.filters]),w=s("textResolver",U,[]),b=s("dataFormatting",a,[t.formatting,t.dataSelector,h]),A=s("editedCellsAndFilters",y,[t.editedCells,p]),E=s("edition",x,[A]),L=s("invokedColumns",R,[t.columns,u]),B=s("invokedRows",R,[t.rows,u]),D=s("unfoldedColumns",he,[L,u]),M=s("unfoldedRows",fe,[B,u]),F=s("unfilteredColumns",k,[D,t.pinnedLeft,t.pinnedRight,t.columnWidths]),S=s("unfilteredRows",C,[M,t.pinnedTop,t.pinnedBottom,t.rowHeights]),z=s("unfilteredColumnKeys",ve,[F]),N=s("unfilteredRowKeys",ve,[S]),O=s("filterFormatting",ye,[b]),K=s("filterFormattingRules",H,[O]),P=s("filteringRules",ge,[t.filtering]),$=s("filteredColumns",V,[p,P,K,u,S,F,E]),Y=s("filteredRows",q,[p,P,K,u,S,F,E]),se=s("sortingFormatting",Re,[b]),ae=s("sortingFormattingRules",H,[se]),ue=s("sortingRules",Ce,[t.sorting]),ce=s("sortedColumns",Be,[h,ue,ae,u,Y,$,E]),pe=s("sortedRows",Le,[h,ue,ae,u,Y,$,E]),me=s("measureFormatting",we,[b]),Ae=s("measureFormattingRules",H,[me]),Ee=s("measureFormatResolver",W,[Ae,u,pe,ce,E]),ke=e.columnWidthCache,Ie=e.rowHeightCache,Te=s("measuredColumns",xe,[ce,pe,w,Ee,ke,z]),De=s("measuredRows",be,[ce,pe,w,Ee,Ie,N]),Oe=s("columns",I,[Te,l,d]),Ke=s("rows",T,[De,l,d]),He=s("columnLookup",ie,[Oe]),Pe=s("rowLookup",ie,[Ke]),We=t.focusedCell,$e=s("sections",g,[Oe,Ke]),qe=t.selectedCells,Ve=s("fixedSize",j,[$e.top.height,$e.bottom.height,$e.left.width,$e.right.width]),je=s("totalSize",G,[Oe,Ke]),Ge=function(e,t,o,n,i,r){if(!t)return null;if(t.x<0||t.y<0||t.x>r.width||t.y>r.height)return null;const s=ne(e,t,i,r),l=function(e,t){if(0===e.length)return-1;if(t<e[0].topWithBorder)return-1;if(t>e[e.length-1].bottomWithBorder)return-1;let o=0,n=e.length-1;for(;o<=n;){const i=Math.floor((o+n)/2);if(t<e[i].topWithBorder)n=i-1;else{if(!(t>e[i].bottomWithBorder))return i;o=i+1}}return-1}(o,s.y),d=function(e,t){if(0===e.length)return-1;if(t<e[0].leftWithBorder)return-1;if(t>e[e.length-1].rightWithBorder)return-1;let o=0,n=e.length-1;for(;o<=n;){const i=Math.floor((o+n)/2);if(t<e[i].leftWithBorder)n=i-1;else{if(!(t>e[i].rightWithBorder))return i;o=i+1}}return-1}(n,s.x);return-1===l||-1===d?null:{rowId:o[l].id,columnId:n[d].id}}(r,e.mousePosition,Ke,Oe,Ve,je),Ye=e.resizingColumn||s("resizableColumn",Me,[Oe,He,Pe,Ge,r,e.mousePosition,Ve,je]),Ue=e.resizingRow||s("resizableRow",Fe,[Ke,He,Pe,Ge,r,e.mousePosition,Ve,je]),_e=s("highlightedCells",re,[e.isMouseDown,!!Ye||!!Ue,We,Ge,Oe,Ke,He,Pe]),Xe=s("selection",v,[qe]),Je=s("highlight",v,[_e]),Qe=s("renderFormatting",m,[b,Ge,We,Xe,Je,E,h,Ye,Ue,t.borderWidth]),Ze=s("renderFormattingRules",H,[Qe]),et=s("renderFormatResolver",W,[Ze,u,Ke,Oe,E]),tt=s("inputFormatting",f,[b]),ot=s("inputFormattingRules",H,[tt]),nt=s("inputFormatResolver",W,[ot,u,Ke,Oe,E]),it=s("editableCells",i,[qe,nt,He,Pe]),rt=s("inputPlacement",le,[it,We,He,Pe,$e]),st=s("isTextValid",de,[c,it]),lt=function(e,t,o,n){const i={width:n.getBoundingClientRect().width,height:n.getBoundingClientRect().height},r={left:n.scrollLeft,top:n.scrollTop},s=e||oe,l=Z({left:0,top:0,...t},o),d=Z({...r,...i},o),a=X(l,J(d,ee)),u=X(l,J(d,te));return _(l,s)&&_(s,a)?Q(s)>2*Q(u)?u:s:u}(n?.scrollRect,je,Ve,r);s("activeColumns",Ne,[Oe,t.onActiveColumnsChange]),s("activeRows",Ne,[Ke,t.onActiveRowsChange]),e.state={options:t,devicePixelRatio:l,borderWidth:d,data:u,dataFormatting:b,edition:E,filteredColumns:$,filteredRows:Y,columns:Oe,rows:Ke,sections:$e,selectedCells:qe,selection:Xe,highlight:Je,hoveredCell:Ge,focusedCell:We,renderFormatting:Qe,renderFormatResolver:et,inputFormatting:tt,inputFormatResolver:nt,fixedSize:Ve,totalSize:je,textResolver:w,scrollRect:lt,highlightedCells:_e,inputPlacement:rt,columnLookup:He,rowLookup:Pe,text:c,isTextValid:st,resizableColumn:Ye,resizableRow:Ue}}function Ke(e){if(!e.error)try{Oe(e)}catch(t){e.error=t}}function He(e,t){const o=new b(t);return[...t,...e.filter((e=>!o.isIdSelected(e.rowId,e.columnId)))]}function Pe(e,t){const o=new b(t);return e.filter((e=>!o.isIdSelected(e.rowId,e.columnId)))}function We(e){const t=e.currentTarget.getBoundingClientRect();return{x:e.clientX-t.left,y:e.clientY-t.top}}function $e(e,t){return e.map((e=>({...e,columnId:"id"in e?e.id:t,rowId:"id"in e?e.id:t})))}function qe(e){if("spread-grid-context"in e)return;const t={"top-left":document.createElement("canvas"),"top-center":document.createElement("canvas"),"top-right":document.createElement("canvas"),"middle-left":document.createElement("canvas"),"middle-center":document.createElement("canvas"),"middle-right":document.createElement("canvas"),"bottom-left":document.createElement("canvas"),"bottom-center":document.createElement("canvas"),"bottom-right":document.createElement("canvas")},r=document.createElement("input");e.setAttribute("tabindex","0"),e.setAttribute("style","max-width: 100vw; max-height: 100vh; overflow: auto; display: grid; position: relative; grid-template-columns: fit-content(0) fit-content(0) fit-content(0); grid-template-rows: fit-content(0) fit-content(0) fit-content(0); outline: none; user-select: none;"),e.classList.add("spread-grid"),t["top-left"].setAttribute("style","position: sticky; left: 0; top: 0; z-index: 2; grid-row: 1; grid-column: 1;"),t["top-center"].setAttribute("style","position: sticky; top: 0; z-index: 1; grid-row: 1; grid-column: 2;"),t["top-right"].setAttribute("style","position: sticky; right: 0; top: 0; z-index: 2; grid-row: 1; grid-column: 3;"),t["middle-left"].setAttribute("style","position: sticky; left: 0; z-index: 1; grid-row: 2; grid-column: 1;"),t["middle-center"].setAttribute("style","grid-row: 2; grid-column: 2; z-index: 0;"),t["middle-right"].setAttribute("style","position: sticky; right: 0; z-index: 1; grid-row: 2; grid-column: 3;"),t["bottom-left"].setAttribute("style","position: sticky; left: 0; bottom: 0; z-index: 2; grid-row: 3; grid-column: 1;"),t["bottom-center"].setAttribute("style","position: sticky; bottom: 0; z-index: 1; grid-row: 3; grid-column: 2;"),t["bottom-right"].setAttribute("style","position: sticky; right: 0; bottom: 0; z-index: 2; grid-row: 3; grid-column: 3;"),r.setAttribute("style","position: sticky; z-index: 3; outline: none; border: none; box-shadow: none; padding: 0 5px; font-size: 12px; font-family: Calibri; background-color: white; box-sizing: border-box; opacity: 0; pointer-events: none;");const s={externalOptions:{},state:null,memory:{},element:e,canvases:t,input:r,renderRequested:!1,mousePosition:null,isMouseDown:!1,columnWidthCache:new Map,rowHeightCache:new Map,requestNewRender:()=>{s.renderRequested||(s.renderRequested=!0,requestAnimationFrame((()=>{s.renderRequested=!1,Ke(s),l(s)})))},addEventListener:(e,t,o)=>{e.addEventListener(t,(e=>{try{o(e)}catch(e){e.message=`[${t} event]: ${e.message}`,s.error=e,s.requestNewRender()}}))}};s.localOptions={data:[],columns:[{type:"DATA-BLOCK"}],rows:[{type:"HEADER"},{type:"DATA-BLOCK"}],formatting:[],filtering:[],sorting:[],dataSelector:({data:e,row:t,column:o})=>e?.[t.id]?.[o.id],pinnedTop:0,pinnedBottom:0,pinnedLeft:0,pinnedRight:0,borderWidth:1,focusedCell:null,onFocusedCellChange:e=>{s.localOptions.focusedCell=e,s.requestNewRender()},selectedCells:[],onSelectedCellsChange:e=>{s.localOptions.selectedCells=e,s.requestNewRender()},highlightedCells:[],editedCells:[],onEditedCellsChange:e=>{s.localOptions.editedCells=e,s.requestNewRender()},filters:[],onFiltersChange:e=>{s.localOptions.filters=e,s.requestNewRender()},sortBy:[],onSortByChange:e=>{s.localOptions.sortBy=e,s.requestNewRender()},onCellClick:()=>{},onCustomCellClick:()=>{},columnWidths:[],onColumnWidthsChange:e=>{s.localOptions.columnWidths=e,s.requestNewRender()},rowHeights:[],onRowHeightsChange:e=>{s.localOptions.rowHeights=e,s.requestNewRender()},onActiveColumnsChange:()=>{},onActiveRowsChange:()=>{}},e["spread-grid-context"]=s;const d=e=>{r.value=e,r.dispatchEvent(new Event("input"))},a=e=>{const t=s.state.options.selectedCells,o=s.state.inputFormatResolver,n=s.state.columnLookup,r=s.state.rowLookup,l=s.state.text,a=s.state.isTextValid,u=s.state.options.onEditedCellsChange,c=s.state.options.onFiltersChange,h=i(t,o,n,r);if(""===l)return;if(!a)return;if(e&&!h.every((e=>e.edit.autoCommit)))return;const f=h.filter((e=>"DATA"===e.type)),p=h.filter((e=>"FILTER"===e.type));var m;m=f.map((e=>({...e.cell,value:e.edit.parse({string:l})}))),u(He(s.state.options.editedCells,m)),(e=>{c(He($e(s.state.options.filters,"FILTER"),e))})(p.map((e=>({...e.cell,expression:e.edit.parse({string:l})})))),e||d("")},u=e=>{const t=s.state.options.selectedCells,o=s.state.options.onEditedCellsChange,n=s.state.options.onFiltersChange,r=i(t,s.state.inputFormatResolver,s.state.columnLookup,s.state.rowLookup);var l;e&&!r.every((e=>e.edit.autoCommit))||(l=t,o(Pe(s.state.options.editedCells,l)),(e=>{n(Pe($e(s.state.options.filters,"FILTER"),e))})(t))};s.addEventListener(e,"scroll",(e=>{s.requestNewRender()})),s.addEventListener(e,"mouseenter",(e=>{s.mousePosition=We(e),s.requestNewRender()})),s.addEventListener(e,"mousemove",(t=>{if(s.mousePosition=We(t),s.resizingColumn){const t=s.state.columnLookup.get(o(s.resizingColumn)),n=t.width,i=t.right,r=ne(e,s.mousePosition,s.state.fixedSize,s.state.totalSize),l=Math.max(10,r.x-i+n),d=s.state.options.columnWidths.filter((e=>o(e.columnId)!==t.key)).concat([{columnId:t.id,width:l}]);s.state.options.onColumnWidthsChange(d)}if(s.resizingRow){const t=s.state.rowLookup.get(o(s.resizingRow)),n=t.height,i=t.bottom,r=ne(e,s.mousePosition,s.state.fixedSize,s.state.totalSize),l=Math.max(10,r.y-i+n),d=s.state.options.rowHeights.filter((e=>o(e.rowId)!==t.key)).concat([{rowId:t.id,height:l}]);s.state.options.onRowHeightsChange(d)}s.requestNewRender()})),s.addEventListener(e,"mouseleave",(()=>{s.mousePosition=null,s.requestNewRender()})),s.addEventListener(e,"mousedown",(e=>{Ke(s),d(""),s.isMouseDown=!0,s.mouseDownPosition=s.mousePosition,s.mouseDownCell=s.state.hoveredCell,s.state.resizableColumn&&(s.resizingColumn=s.state.resizableColumn),s.state.resizableRow&&(s.resizingRow=s.state.resizableRow),s.state.resizableColumn||s.state.resizableRow||s.state.options.onFocusedCellChange(s.state.hoveredCell),e.ctrlKey||s.state.options.onSelectedCellsChange([]),s.requestNewRender()})),s.addEventListener(e,"mouseup",(e=>{Ke(s),s.isMouseDown=!1,s.resizingColumn=null,s.resizingRow=null,s.state.options.onSelectedCellsChange(He(s.state.options.selectedCells,s.state.highlightedCells)),s.requestNewRender()})),s.addEventListener(e,"pointerdown",(e=>{s.element.setPointerCapture(e.pointerId)})),s.addEventListener(e,"pointerup",(e=>{s.element.releasePointerCapture(e.pointerId)})),s.addEventListener(e,"click",(e=>{Ke(s);const t=s.state.hoveredCell,i=s.mouseDownCell;if(s.state.resizableColumn||s.state.resizableRow)return;if(null===t)return;if(o(t.columnId)!==o(i.columnId))return;if(o(t.rowId)!==o(i.rowId))return;const r=s.state.columnLookup.get(o(t.columnId)),l=s.state.rowLookup.get(o(t.rowId)),d=s.state.options.sortBy,a=s.state.inputFormatResolver.resolve(l,r);if(a.edit?.toggle){const e=function(e,t,o,n){const i=n.hasValueByKey(o.key,t.key)?n.getValueByKey(o.key,t.key):e.value,r=e.edit.toggle;return"function"==typeof r?r({value:i}):r[(r.indexOf(i)+1)%r.length]}(a,r,l,s.state.edition),o=n(r,l);"DATA"===o&&s.state.options.onEditedCellsChange(He(s.state.options.editedCells,[{...t,value:e}])),"FILTER"===o&&s.state.options.onFiltersChange(He(s.state.options.filters,[{...t,expression:e}]))}else if("DATA"===r.type&&"DATA"===l.type)s.state.options.onCellClick(s.state.hoveredCell);else if("CUSTOM"===r.type||"CUSTOM"===l.type)s.state.options.onCustomCellClick(s.state.hoveredCell);else if("HEADER"===r.type||"HEADER"===l.type){const t=function(e,t,n,i){function r(e){const i="columnId"in e?e.columnId:"HEADER",r="rowId"in e?e.rowId:"HEADER";return t.key===o(i)&&n.key===o(r)}const s=["ASC","DESC",void 0],l=e.find(r),d=s.indexOf(l?.direction),a=s[(d+1)%s.length],u=e.indexOf(l)===e.length-1;return[...!i||!u&&l?e.filter((e=>!function(e){const i="columnId"in e?e.columnId:"HEADER",r="rowId"in e?e.rowId:"HEADER";return"HEADER"===t.type&&t.key===o(i)||"HEADER"===n.type&&n.key===o(r)}(e))):e.filter((e=>!r(e))),...a?[{columnId:t.id,rowId:n.id,direction:a}]:[]]}(d,r,l,e.ctrlKey);s.state.options.onSortByChange(t),s.state.options.onSelectedCellsChange([])}})),s.addEventListener(e,"dblclick",(e=>{if(Ke(s),s.state.resizableColumn){const e=o(s.state.resizableColumn),t=s.state.options.columnWidths.filter((t=>o(t.columnId)!==e));s.state.options.onColumnWidthsChange(t),s.columnWidthCache.delete(e)}if(s.state.resizableRow){const e=o(s.state.resizableRow),t=s.state.options.rowHeights.filter((t=>o(t.rowId)!==e));s.state.options.onRowHeightsChange(t),s.rowHeightCache.delete(e)}const t=s.state.focusedCell;if(null===t)return;const n=o(t.columnId),i=o(t.rowId),l=s.state.columnLookup,a=s.state.rowLookup,u=s.state.inputFormatResolver;if(!l.has(n))return;if(!a.has(i))return;const c=l.get(n),h=a.get(i),f=u.resolve(h,c),p=f.text;f.edit&&(f.edit.toggle||(d(p),r?.select()))})),s.addEventListener(e,"focus",(()=>{r.parentElement&&r.focus({preventScroll:!0})})),s.addEventListener(e,"keydown",(e=>{Ke(s);const t=s.state.focusedCell,n=s.state.columnLookup,i=s.state.rowLookup,r=s.state.options.selectedCells,l=s.state.options.onSelectedCellsChange,c=s.state.options.onFocusedCellChange,h=s.state.options.editedCells,f=s.state.options.onEditedCellsChange,p=s.state.columns,m=s.state.rows,g=s.state.text,y=s.state.inputFormatResolver,w=(e,t)=>{c(e),t.shiftKey?l(He(r,[e])):l([e])},x=(e,i)=>{if(!t)return;const r=o(t.columnId);if(!n.has(r))return;const s=n.get(r).index,l=Math.max(0,Math.min(p.length-1,s+e));if(l===s)return;const d={rowId:t.rowId,columnId:p[l].id};w(d,i)},v=(e,n)=>{if(!t)return;const r=o(t.rowId);if(!i.has(r))return;const s=i.get(r).index,l=Math.max(0,Math.min(m.length-1,s+e));if(l===s)return;const d={rowId:m[l].id,columnId:t.columnId};w(d,n)},R=()=>{e.preventDefault(),e.stopPropagation()};switch(e.key){case"Escape":""!==g?d(""):r.length>1?l([t]):h.length>0?f([]):(c(null),l([]));break;case"Enter":a();break;case"ArrowUp":R(),v(e.ctrlKey?-m.length:-1,e);break;case"ArrowDown":R(),v(e.ctrlKey?m.length:1,e);break;case"ArrowLeft":R(),x(e.ctrlKey?-p.length:-1,e);break;case"ArrowRight":R(),x(e.ctrlKey?p.length:1,e);break;case"Delete":case"Backspace":u();break;case"c":(e=>{if(!e.ctrlKey)return;const t=function(e,t,n,i){const r=new Map(t.map((e=>[e.key,e]))),s=new Map(n.map((e=>[e.key,e]))),l=e.map((e=>({columnKey:o(e.columnId),rowKey:o(e.rowId)}))).filter((e=>r.has(e.columnKey)&&s.has(e.rowKey))),d=new Set(l.map((e=>e.columnKey))),a=new Set(l.map((e=>e.rowKey)));if(0===l.length)return"";const u=new b(e),c=Math.min(...l.map((e=>r.get(e.columnKey).index))),h=Math.max(...l.map((e=>r.get(e.columnKey).index))),f=Math.min(...l.map((e=>s.get(e.rowKey).index))),p=Math.max(...l.map((e=>s.get(e.rowKey).index))),m=[];for(let e=f;e<=p;e++){const o=n[e],r=o.key;if(a.has(r)){for(let e=c;e<=h;e++){const n=t[e],s=n.key;if(d.has(s)){if(u.isKeySelected(r,s)){const e=i.resolve(o,n).text;m.push(e)}e<h&&m.push("\t")}}e<p&&m.push("\n")}}return m.join("")}(r,p,m,y);if(navigator.clipboard)navigator.clipboard.writeText(t);else{const e=document.createElement("textarea");e.value=t,document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e)}})(e)}})),new ResizeObserver((()=>{s.requestNewRender()})).observe(e),s.addEventListener(r,"input",(e=>{Ke(s),e.target.value?(a(!0),r.style.opacity=1,r.style.pointerEvents="auto"):(e.isTrusted&&u(!0),r.style.opacity=0,r.style.pointerEvents="none")})),s.addEventListener(r,"click",(e=>{e.stopPropagation()})),s.addEventListener(r,"dblclick",(e=>{e.stopPropagation()})),s.addEventListener(r,"mousedown",(e=>{e.stopPropagation()})),s.addEventListener(r,"keydown",(e=>{switch(e.key){case"Enter":case"Escape":break;case"Delete":case"Backspace":case"ArrowUp":case"ArrowDown":case"ArrowLeft":case"ArrowRight":""!==r.value&&(e.stopPropagation(),s.requestNewRender());break;default:e.stopPropagation(),s.requestNewRender()}}))}function Ve(e,t){qe(e);const o=e["spread-grid-context"];o.externalOptions=t,null===o.state?(Ke(o),l(o)):o.requestNewRender()}return t.default})()));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SpreadGrid=t():e.SpreadGrid=t()}(self,(()=>(()=>{"use strict";var e={d:(t,o)=>{for(var n in o)e.o(o,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:o[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};function o(e){return null===e?"null":Array.isArray(e)?`[${e.map(o).join(",")}]`:"object"==typeof e?(t=e,`{${Object.keys(t).sort().map((e=>`${e}:${o(t[e])}`)).join(",")}}`):JSON.stringify(e);var t}function n(e,t){return"FILTER"===e.type^"FILTER"===t.type?"FILTER":"DATA"}function r(e,t,r,i){return e.map((e=>{const s=o(e.columnId),l=o(e.rowId);if(!r.has(s))return null;if(!i.has(l))return null;const d=r.get(s),u=i.get(l);return{edit:t.resolve(u,d).edit,cell:e,type:n(d,u)}})).filter((e=>e?.edit))}function i(e,t){return Math.round(e*t)/t}function s(e,t,o){const n=e.state,r=e.canvases[`${t}-${o}`],s=n.sections[t],l=n.sections[o],d=l.columns,u=s.rows;if(0===u.length||0===d.length)return void(r.parentElement&&r.parentElement.removeChild(r));r.parentElement||e.element.appendChild(r);const c=r.getContext("2d",{alpha:!1}),a=n.scrollRect,h=n.textResolver,f=n.renderFormatResolver,p=n.borderWidth,m=s.showTopBorder,g=s.showBottomBorder,y=l.showLeftBorder,w=l.showRightBorder,x=p/2,b=u.length-1+(m?1:0)+(g?1:0),v=d.length-1+(y?1:0)+(w?1:0),R=u.map((e=>e.height)),E=d.map((e=>e.width)),A=E.reduce(((e,t)=>e+t),0)+v*p,k=R.reduce(((e,t)=>e+t),0)+b*p,C="center"===o?a.left:0,I="middle"===t?a.top:0,T="center"===o?a.width:l.width,L="middle"===t?a.height:s.height,B=E.reduce(((e,t,o)=>{const n=e[o]+t+p;return e.push(n),e}),[y?p:0]),D=R.reduce(((e,t,o)=>{const n=e[o]+t+p;return e.push(n),e}),[m?p:0]),M=B.slice(0,-1),F=D.slice(0,-1),S=Math.max(M.findLastIndex((e=>e<=C)),0),z=M.findLastIndex((e=>e<=C+T)),O=Math.max(F.findLastIndex((e=>e<=I)),0),N=F.findLastIndex((e=>e<=I+L)),K=Math.max(S,y?0:1),P=z+(w?1:0),H=Math.max(O,m?0:1),W=N+(g?1:0),$=Array.from({length:N-O+1},((e,t)=>{const o=u[t+O];return Array.from({length:z-S+1},((e,t)=>{const n=d[t+S];return f.resolve(o,n)}))})),q=(e,t)=>$[e-O][t-S];r.width=Math.round(T*devicePixelRatio),r.height=Math.round(L*devicePixelRatio),r.style.width=`${T}px`,r.style.height=`${L}px`,r.style.marginLeft=`${C}px`,r.style.marginTop=`${I}px`,r.style.marginRight=A-T-C+"px",r.style.marginBottom=k-L-I+"px",c.fillStyle="#E9E9E9",c.fillRect(0,0,r.width,r.height);const V=(e,t)=>{c.setTransform(devicePixelRatio,0,0,devicePixelRatio,(e-C)*devicePixelRatio,(t-I)*devicePixelRatio)},Y=(e,t,o,n)=>{c.beginPath(),c.rect(e,t,o,n),c.clip()};for(let e=S;e<=z;e++){c.save(),V(B[e],0),Y(0,0,E[e],k);for(let t=O;t<=N;t++){const o=q(t,e),n=o.style,r=D[t],s=B[e],l=E[e],d=R[t],u=o.text,a=n.textBaseline||"middle",f=o.padding;if(V(s,r),c.fillStyle=n.background||"white",c.fillRect(0,0,l,d),"draw"in o&&o.draw(c),n.highlight&&(c.fillStyle=n.highlight,c.fillRect(0,0,l,d)),n.corner&&(c.fillStyle=n.corner,c.beginPath(),c.moveTo(l-7,d),c.lineTo(l,d),c.lineTo(l,d-7),c.fill()),u){c.fillStyle=n.foreground||"black",c.font=o.font;const e=h.getFontMetrics(o.font),t="center"==n.textAlign&&h.measureWidth(u,o.font)>l-f.left-f.right?"left":n.textAlign||"left";c.textAlign=t;const r=i("left"===t?f.left:"center"===t?l/2:"right"===t?l-f.right:0,devicePixelRatio),s=i("top"===a?e.middle+e.topOffset+f.top:"middle"===a?d/2+e.middle:"bottom"===a?d+e.middle-e.bottomOffset-f.bottom:0,devicePixelRatio);s-e.middle-e.topOffset>=0&&s-e.middle+e.bottomOffset<=d?c.fillText(u,r,s):(c.strokeStyle="#E9E9E9",c.lineWidth=p,c.beginPath(),c.moveTo(0,p+x),c.lineTo(l,p+x),c.moveTo(0,d-p-x),c.lineTo(l,d-p-x),c.stroke(),c.save(),Y(0,2*p,l,d-4*p),c.fillText(u,r,s),c.restore())}}c.restore()}V(0,0);const G=(e,t,o,n,r)=>{if(!r)return;if(0===r.width)return;const i=r.width/devicePixelRatio,s=t===n,l=e-(s?i/2:0),d=t-(s?0:i/2),u=o+(s?i/2:0),a=n+(s?0:i/2);c.strokeStyle=r.color||"black",c.lineWidth=i,r.dash?(c.setLineDash(r.dash.map((e=>e/devicePixelRatio))),c.lineDashOffset=s?l:d):c.setLineDash([]),c.beginPath(),c.moveTo(l,d),c.lineTo(u,a),c.stroke()},j=(e,t)=>e?t?e.index>t.index?e:t:e:t;for(let e=H;e<=W;e++){const t=e-1,o=e;for(let e=S;e<=z;e++){const n=j(t>=O?q(t,e).style.borderBottom:null,o<=N?q(o,e).style.borderTop:null);G(B[e]-x,D[o]-x,B[e+1]-x,D[o]-x,n)}}for(let e=K;e<=P;e++){const t=e-1,o=e;for(let e=O;e<=N;e++){const n=j(t>=S?q(e,t).style.borderRight:null,o<=z?q(e,o).style.borderLeft:null);G(B[o]-x,D[e]-x,B[o]-x,D[e+1]-x,n)}}}function l(e){if(!e.error)try{!function(e){s(e,"top","left"),s(e,"top","center"),s(e,"top","right"),s(e,"middle","left"),s(e,"middle","center"),s(e,"middle","right"),s(e,"bottom","left"),s(e,"bottom","center"),s(e,"bottom","right"),function(e){const t=e.element,o=e.input,n=e.state,r=n.inputPlacement;if(!r){if(o.parentElement){const e=document.activeElement===o;o.parentElement.removeChild(o),e&&t.focus({preventScroll:!0})}return}const i=e.canvases[r.section];if(o.style.left="left"in r?`${r.left}px`:"0",o.style.top="top"in r?`${r.top}px`:"0",o.style.right="right"in r?`${r.right}px`:"0",o.style.bottom="bottom"in r?`${r.bottom}px`:"0",o.style.marginLeft="marginLeft"in r?`${r.marginLeft}px`:"0",o.style.marginTop="marginTop"in r?`${r.marginTop}px`:"0",o.style.width=`${r.width}px`,o.style.height=`${r.height}px`,o.style.gridArea=i.style.gridArea,o.style.zIndex=i.style.zIndex,o.style.backgroundColor=n.isTextValid?"white":"#eb3434",!o.parentElement){const e=document.activeElement===t;t.appendChild(o),e&&o.focus({preventScroll:!0})}}(e),function(e){const t=e.element,o=e.state;e.isReordering?t.style.cursor="move":o.resizableColumn&&o.resizableRow?t.style.cursor="nwse-resize":o.resizableColumn?t.style.cursor="col-resize":o.resizableRow?t.style.cursor="row-resize":t.style.cursor="default"}(e),function(e){const t=e.element,o=e.tooltip,n=e.state.tooltip,r=e.state.tooltipPlacement;r?(o.innerHTML=n,o.style.left=`${r.left}px`,o.style.top=`${r.top}px`,o.parentElement||(t.appendChild(o),o.showPopover())):o.parentElement&&o.parentElement.removeChild(o)}(e)}(e)}catch(t){e.error=t}e.error&&function(e){if(e.errorRendered)return;e.errorRendered=!0;const t=e.element,o=e.error;t.style.backgroundColor="#9f0000",t.style.color="white",t.style.padding="20px",t.style.display="flex",t.style.flexDirection="column",t.style.userSelect="text",t.innerHTML=`\n <div style="font-size: 16px;">\n An error occurred while rendering the grid, please contact the support.\n </div>\n <div style="font-size: 20px; font-weight: bold; padding: 20px 0;">\n ${o.message}\n </div>\n <div style="font-size: 16px; white-space: pre-wrap;">${o.stack}</div>\n `}(e)}e.d(t,{default:()=>Je});const d={value:({newValue:e})=>e||"",text:({newValue:e})=>e||"Search...",edit:{validate:()=>!0,parse:({string:e})=>e,autoCommit:!0}};function u(e,t,o){return[{column:{type:"DATA"},row:{type:"HEADER"},value:({column:e})=>void 0===e.header?e.id:e.header},{column:{type:"HEADER"},row:{type:"DATA"},value:({row:e})=>void 0===e.header?e.id:e.header},{column:{type:"HEADER"},row:{type:"SPECIAL"},value:""},{column:{type:"SPECIAL"},row:{type:"HEADER"},value:""},{column:{type:"DATA"},row:{type:"FILTER"},...d},{column:{type:"FILTER"},row:{type:"DATA"},...d},{column:{type:"DATA"},row:{type:"DATA"},value:t},...e,...o.map((({columnId:e,rowId:t,direction:n},r)=>({column:{id:e},row:{id:t},text:({value:e,text:t})=>`${o.length>1?r+1:""}${"ASC"===n?"⇣":"⇡"} ${t||e}`})))]}const c=["column","row","condition"];function a(e){return Object.keys(e).length>Object.keys(e).filter((e=>c.includes(e))).length}function h(e,t){const o=[...c,...t];return e.map((e=>function(e,t){const o={};for(const n of t)n in e&&(o[n]=e[n]);return o}(e,o))).filter(a)}function f(e){return h(e,["value","text","edit"])}function p(e,t){return t?e+"99":e+"33"}function m(e,t,n,r,i,s,l,d,u,c,a,h,f){const m=n?o(n.columnId):null,g=n?o(n.rowId):null,y=null!==u,w=null!==d||y,x=c+2,b=c+4,v=(e,t,o,n)=>{if(o<0||o>=e.length)return!1;if(n<0||n>=t.length)return!1;const i=e[o].key,s=t[n].key;return r.isKeySelected(i,s)},R=(e,t)=>e?[t]:[];return[{column:{type:"DATA"},row:{type:"FILTER"},style:({newValue:e})=>({background:"#FBFBFB",foreground:e?"black":"#cccccc",border:{width:1,color:"gray"}})},{column:{type:"FILTER"},row:{type:"DATA"},style:({newValue:e})=>({background:"#FBFBFB",foreground:e?"black":"#cccccc",border:{width:1,color:"gray"}})},{column:{type:"ANY"},row:{type:"HEADER"},style:{background:"#F5F5F5",border:{width:c,color:"gray"}}},{column:{type:"HEADER"},row:{type:"ANY"},style:{background:"#F5F5F5",border:{width:c,color:"gray"}}},{column:{type:"HEADER"},row:{type:"HEADER"},style:{background:"#E0E0E0"}},...e,...R(t&&!y,{column:{type:"ANY"},row:{id:t?.rowId},style:{highlight:"#81948133"}}),...R(t&&!w,{column:{id:t?.columnId},row:{id:t?.rowId},style:{highlight:"#81948188"}}),{column:{type:"ANY"},row:{type:"ANY"},condition:({rows:e,columns:t,row:o,column:n})=>v(e,t,o.index,n.index),style:({rows:e,columns:t,row:o,column:n,edit:r})=>({...v(e,t,o.index-1,n.index)?{}:{borderTop:{width:x,color:"#596959",index:Number.MAX_SAFE_INTEGER}},...v(e,t,o.index+1,n.index)?{}:{borderBottom:{width:x,color:"#596959",index:Number.MAX_SAFE_INTEGER}},...v(e,t,o.index,n.index-1)?{}:{borderLeft:{width:x,color:"#596959",index:Number.MAX_SAFE_INTEGER}},...v(e,t,o.index,n.index+1)?{}:{borderRight:{width:x,color:"#596959",index:Number.MAX_SAFE_INTEGER}},highlight:p(r?"#798d9c":"#819481",m!==n.key||g!==o.key)})},{column:{type:"ANY"},row:{type:"ANY"},condition:({row:e,column:t})=>i.isKeySelected(e.key,t.key),style:({row:e,column:t})=>({highlight:p("#93a8b8",m!==t.key||g!==e.key)})},...R(n,{column:{id:n?.columnId},row:{id:n?.rowId},style:{highlight:"#ffffffaa"}}),...l.map((({columnId:e,rowId:t,direction:o},n)=>({column:{id:e},row:{id:t},style:{highlight:"#0377fc44"}}))),{column:{type:"ANY"},row:{type:"ANY"},condition:({edit:e})=>e,style:{corner:"#77777720"}},{column:{type:"ANY"},row:{type:"ANY"},condition:({row:e,column:t})=>s.hasValueByKey(e.key,t.key),style:{corner:"darkgreen"}},...R(d,{column:{id:d},row:{type:"HEADER"},style:{borderRight:{width:b,color:"cornflowerblue"}}}),...R(u,{column:{type:"HEADER"},row:{id:u},style:{borderBottom:{width:b,color:"cornflowerblue"}}}),...R(a&&h,{column:{id:h},row:{type:"ANY"},style:{highlight:"#3a74e055"}}),...R(a&&f,{column:{type:"ANY"},row:{id:f},style:{highlight:"#3a74e055"}})]}function g(e,t){const o=t.filter((e=>"BEGIN"===e.pinned)).length,n=t.filter((e=>"END"===e.pinned)).length,r=t.length-o-n,i=e.filter((e=>"BEGIN"===e.pinned)).length,s=e.filter((e=>"END"===e.pinned)).length,l=e.length-i-s,d=t.slice(0,o),u=t.slice(t.length-n,t.length),c=t.slice(o,t.length-n),a=e.slice(0,i),h=e.slice(e.length-s,e.length),f=e.slice(i,e.length-s),p=o>0,m=i>0,g=!0,y=!0,w=r>0||!p,x=!0,b=!p,v=!(n>0),R=!0,E=!0,A=l>0||!m,k=!0,C=!m,I=!(s>0),T=(e,t,o)=>{if(0===e.length)return 0;const n=t?e.at(0).topWithBorder:e.at(0).top;return(o?e.at(-1).bottomWithBorder:e.at(-1).bottom)-n},L=(e,t,o)=>{if(0===e.length)return 0;const n=t?e.at(0).leftWithBorder:e.at(0).left;return(o?e.at(-1).rightWithBorder:e.at(-1).right)-n};return{top:{rows:d,showTopBorder:g,showBottomBorder:y,height:T(d,g,y)},bottom:{rows:u,showTopBorder:w,showBottomBorder:x,height:T(u,w,x)},middle:{rows:c,showTopBorder:b,showBottomBorder:v,height:T(c,b,v)},left:{columns:a,showLeftBorder:R,showRightBorder:E,width:L(a,R,E)},right:{columns:h,showLeftBorder:A,showRightBorder:k,width:L(h,A,k)},center:{columns:f,showLeftBorder:C,showRightBorder:I,width:L(f,C,I)}}}function y(e,t){return[...e,...t.map((e=>({columnId:e.columnId,rowId:e.rowId,value:e.expression})))]}class w{constructor(e){this.lookup=new Map,e.forEach((e=>{const t=o(e.rowId),n=o(e.columnId);this.lookup.has(t)||this.lookup.set(t,new Map),this.lookup.get(t).set(n,e.value)}))}hasValueByKey(e,t){return this.lookup.has(e)&&this.lookup.get(e).has(t)}getValueByKey(e,t){if(this.hasValueByKey(e,t))return this.lookup.get(e).get(t)}hasValueById(e,t){return this.hasValueByKey(o(e),o(t))}getValueById(e,t){return this.getValueByKey(o(e),o(t))}}function x(e){return new w(e)}class b{constructor(e){this.lookup=new Map,e.forEach((e=>{const t=o(e.rowId),n=o(e.columnId);this.lookup.has(t)||this.lookup.set(t,new Set),this.lookup.get(t).add(n)}))}isKeySelected(e,t){return this.lookup.has(e)&&this.lookup.get(e).has(t)}isIdSelected(e,t){return this.isKeySelected(o(e),o(t))}}function v(e){return new b(e)}function R(e,t){return"function"==typeof e?e(t):e}function E(e,t,o,n){return e<o?"BEGIN":e>=t-n?"END":void 0}function A(e,t,n){return e.map(((r,i)=>{const s="id"in r?r.id:r.type;return{...r,id:s,type:r.type||"DATA",key:o(s),pinned:E(i,e.length,t,n),header:"header"in r?r.header:s,labels:r.labels||[]}}))}function k(e,t,n,r){const i=new Map(r.map((({columnId:e,width:t})=>[o(e),t])));return A(e,t,n).map((e=>({...e,width:i.has(e.key)?i.get(e.key):"width"in e?e.width:"fit"})))}function C(e,t,n,r){const i=new Map(r.map((({rowId:e,height:t})=>[o(e),t])));return A(e,t,n).map((e=>({...e,height:i.has(e.key)?i.get(e.key):"height"in e?e.height:"fit"})))}function I(e,t,o){let n=o;return e.map(((e,r)=>{const s=i("width"in e?e.width:100,t),l={...e,index:r,width:s,leftWithBorder:n-o,left:n,right:n+s,rightWithBorder:n+s+o};return n+=l.width+o,l}))}function T(e,t,o){let n=o;return e.map(((e,r)=>{const s=i("height"in e?e.height:20,t),l={...e,index:r,height:s,topWithBorder:n-o,top:n,bottom:n+s,bottomWithBorder:n+s+o};return n+=l.height+o,l}))}const L="12px Calibri",B={top:2,right:5,bottom:2,left:5},D={HEADER:["HEADER"],FILTER:["FILTER"],DATA:["DATA"],CUSTOM:["CUSTOM"],ANY:["HEADER","DATA","FILTER","CUSTOM"],SPECIAL:["HEADER","FILTER","CUSTOM"],undefined:[]};class M{byKey=new Map;byIndex=new Map;byLabel=new Map;byType=new Map}class F{lookup=new M;hasRules=!1;addRule(e,t,n){if(this.hasRules=!0,Array.isArray(e))for(const o of e)this.addRule(o,t,n);else if(Array.isArray(t))for(const o of t)this.addRule(e,o,n);else{e=e?"id"in e?{key:o(e.id)}:e:{type:"DATA"},t=t?"id"in t?{key:o(t.id)}:t:{type:"DATA"},"key"in e&&i(this.lookup.byKey,e.key),"index"in e&&i(this.lookup.byIndex,e.index),"label"in e&&i(this.lookup.byLabel,e.label);for(const t of D[e.type])i(this.lookup.byType,t)}function r(e,t){e.has(t)||e.set(t,[]),e.get(t).push(n)}function i(e,o){e.has(o)||e.set(o,new M),"key"in t&&r(e.get(o).byKey,t.key),"index"in t&&r(e.get(o).byIndex,t.index),"label"in t&&r(e.get(o).byLabel,t.label);for(const n of D[t.type])r(e.get(o).byType,n)}}getRules(e,t){const o=[];if(!this.hasRules)return o;function n(e){for(const t of e)o.push(t)}function r(e){e.byKey.has(t.key)&&n(e.byKey.get(t.key)),e.byIndex.has(t.index)&&n(e.byIndex.get(t.index)),e.byType.has(t.type)&&n(e.byType.get(t.type));for(const o of t.labels)e.byLabel.has(o)&&n(e.byLabel.get(o))}this.lookup.byKey.has(e.key)&&r(this.lookup.byKey.get(e.key)),this.lookup.byIndex.has(e.index)&&r(this.lookup.byIndex.get(e.index)),this.lookup.byType.has(e.type)&&r(this.lookup.byType.get(e.type));for(const t of e.labels)this.lookup.byLabel.has(t)&&r(this.lookup.byLabel.get(t));return o}}const S=["borderTop","borderRight","borderBottom","borderLeft"],z={validate:()=>!0,parse:({string:e})=>e};function O(e,t){const o={...e};if("border"in o){for(const e of S)o[e]=o.border;delete o.border}for(const e of S)e in o&&(o[e]={...o[e],index:t});return o}function N(e,t){if(!1!==e.edit)return!0===e.edit?"edit"in t?t.edit:z:"edit"in t?{...t.edit,...e.edit}:{...z,...e.edit}}class K{constructor(e){this.rulesLookup=new F;for(const[t,o]of e.entries()){const e={index:t};"condition"in o&&(e.condition=o.condition),"style"in o&&(e.style="function"==typeof o.style?o.style:()=>o.style),"value"in o&&(e.value="function"==typeof o.value?o.value:()=>o.value),"text"in o&&(e.text="function"==typeof o.text?o.text:()=>o.text),"font"in o&&(e.font="function"==typeof o.font?o.font:()=>o.font),"padding"in o&&(e.padding="function"==typeof o.padding?o.padding:()=>o.padding),"edit"in o&&(e.edit=o.edit),"tooltip"in o&&(e.tooltip="function"==typeof o.tooltip?o.tooltip:()=>o.tooltip),"draw"in o&&(e.draw=o.draw),this.rulesLookup.addRule(o.column,o.row,e)}}resolve(e,t,o,n,r,i){const s=this.rulesLookup.getRules(r,n).sort(((e,t)=>e.index-t.index)).filter(((e,t,o)=>e.index!==o[t-1]?.index));let l,d,u={data:e,rows:t,columns:o,row:n,column:r},c={},a=B,h=L;i.hasValueByKey(n.key,r.key)&&(u={...u,newValue:i.getValueByKey(n.key,r.key)});for(const e of s)if((!("condition"in e)||e.condition(u))&&("value"in e&&(u={...u,value:e.value(u)}),"style"in e&&(c={...c,...O(e.style(u),e.index)}),"text"in e&&(u={...u,text:e.text(u)}),"font"in e&&(h=e.font(u)),"padding"in e&&(a={...a,...e.padding(u)}),"edit"in e&&(u={...u,edit:N(e,u)}),"tooltip"in e&&(d=e.tooltip(u)),"draw"in e)){const t=u;l=o=>e.draw({...t,ctx:o})}const f=function(e){return"text"in e?`${e.text}`:"newValue"in e?`${e.newValue}`:void 0!==e.value?`${e.value}`:""}(u),p={style:c,visible:!0,text:f,padding:a,font:h};return"value"in u&&(p.value=u.value),"edit"in u&&void 0!==u.edit&&(p.edit=u.edit),void 0!==d&&(p.tooltip=d),void 0!==l&&(p.draw=l),p}}function P(e){return new K(e)}class H{constructor(e,t,o,n,r){this.formattingRules=e,this.data=t,this.rows=o,this.columns=n,this.edition=r}resolve(e,t){return this.formattingRules.resolve(this.data,this.rows,this.columns,e,t,this.edition)}}function W(e,t,o,n,r){return new H(e,t,o,n,r)}function $(e,t,n){const r=new Map;for(const i of e){const e=o(i[t]),s=o(i[n]);r.has(e)||r.set(e,new Map),r.get(e).set(s,i.expression)}return r}function q(e,t,o,n,r,i,s){if(0===e.length)return r;const l=$(e,"columnId","rowId"),d=i.filter((e=>"FILTER"!==e.type&&l.has(e.key)));return 0===d.length?r:r.filter((e=>{for(const u of d){const d=o.resolve(n,r,i,e,u,s),c=l.get(u.key);if(!t.resolve(n,r,i,e,u,d.value,d.text,c))return!1}return!0}))}function V(e,t,o,n,r,i,s){if(0===e.length)return i;const l=$(e,"rowId","columnId"),d=r.filter((e=>"FILTER"!==e.type&&l.has(e.key)));return 0===d.length?i:i.filter((e=>{for(const u of d){const d=o.resolve(n,r,i,u,e,s),c=l.get(u.key);if(!t.resolve(n,r,i,u,e,d.value,d.text,c))return!1}return!0}))}function Y(e,t,o,n){return{top:e,bottom:t,left:o,right:n}}function G(e,t){return{width:e.length?e.at(-1).rightWithBorder:0,height:t.length?t.at(-1).bottomWithBorder:0}}class j{constructor(){this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),this.fontMetrics=new Map}measureWidth(e,t){if(!e)return 0;const o=this.context;return o.font=t||L,o.measureText(e).width}measureHeight(e,t){let o=1;for(const t of e)"\n"===t&&o++;return o*this.getFontMetrics(t).height}getFontMetrics(e){const t=e;if(this.fontMetrics.has(t))return this.fontMetrics.get(t);const o=this.context;o.font=e||L;const n=o.measureText("X"),r=(n.actualBoundingBoxDescent-n.actualBoundingBoxAscent)/2,i={topOffset:r+n.fontBoundingBoxAscent,middle:-r,bottomOffset:n.fontBoundingBoxDescent-r,height:n.fontBoundingBoxAscent+n.fontBoundingBoxDescent};return this.fontMetrics.set(t,i),i}}function U(){return new j}function _(e,t){return t.top>=e.top&&t.left>=e.left&&t.top+t.height<=e.top+e.height&&t.left+t.width<=e.left+e.width}function X(e,t){const o={top:Math.max(e.top,t.top),left:Math.max(e.left,t.left),width:Math.min(e.left+e.width,t.left+t.width)-Math.max(e.left,t.left),height:Math.min(e.top+e.height,t.top+t.height)-Math.max(e.top,t.top)};return o.width>=0&&o.height>=0?o:{top:e.top,left:e.left,width:0,height:0}}function J(e,t){return{top:e.top-t,left:e.left-t,width:e.width+2*t,height:e.height+2*t}}function Q(e){return e.width*e.height}function Z(e,t){return{top:e.top,left:e.left,width:Math.max(0,e.width-t.left-t.right),height:Math.max(0,e.height-t.top-t.bottom)}}const ee=200,te=400,oe={left:0,top:0,width:0,height:0};function ne(e,t,o,n){const r=t.x,i=t.y,s=e.scrollLeft,l=e.scrollTop,d=e.clientWidth,u=e.clientHeight;return{x:r<=o.left?r:r>=d?r+s:r>=d-o.right?n.width-d+r:r+s,y:i<=o.top?i:i>=u?i+l:i>=u-o.bottom?n.height-u+i:i+l}}function re(e){return e.reduce(((e,t)=>e.set(t.key,t)),new Map)}function ie(e,t,n,r,i,s,l,d){if(!e)return[];if(!t)return[];if(!r)return[];if(!n)return[];const u=o(n.columnId),c=o(n.rowId),a=o(r.columnId),h=o(r.rowId);if(!l.has(u))return[];if(!d.has(c))return[];if(!l.has(a))return[];if(!d.has(h))return[];const f=Math.min(l.get(u).index,l.get(a).index),p=Math.max(l.get(u).index,l.get(a).index),m=Math.min(d.get(c).index,d.get(h).index),g=Math.max(d.get(c).index,d.get(h).index);return i.slice(f,p+1).flatMap((e=>s.slice(m,g+1).map((t=>({rowId:t.id,columnId:e.id})))))}function se(e,t){const o=function(e){return"BEGIN"===e.pinned?"top":"END"===e.pinned?"bottom":"middle"}(t),n=function(e){return"BEGIN"===e.pinned?"left":"END"===e.pinned?"right":"center"}(e);return`${o}-${n}`}function le(e,t,n,r){if(!e)return null;const i=o(e.columnId),s=o(e.rowId);if(!t.has(i))return null;if(!n.has(s))return null;const l=t.get(i),d=n.get(s),u={width:l.width,height:d.height,section:se(l,d)};switch(d.pinned){case"BEGIN":u.top=d.top;break;case"END":u.bottom=r.top.height+r.middle.height+r.bottom.height-d.top-d.height;break;default:u.marginTop=d.top-r.top.height}switch(l.pinned){case"BEGIN":u.left=l.left;break;case"END":u.right=r.left.width+r.center.width+r.right.width-l.left-l.width;break;default:u.marginLeft=l.left-r.left.width}return u}function de(e,t,o,n,r){return 0===e.length?null:le(t,o,n,r)}function ue(e,t){return t.every((t=>t.edit.validate({string:e})))}function ce(e){return Array.isArray(e)?e.map(((e,t)=>t)):Object.keys(e)}function ae(e){return ce(e)}function he(e){const t=new Set;if(Array.isArray(e))for(const o of e)for(const e of ce(o))t.add(e);else for(const o in e)for(const n of ce(e[o]))t.add(n);return[...t]}function fe(e,t){if(!e.some((e=>"DATA-BLOCK"===e.type)))return e;const o=[];for(const n of e)if("DATA-BLOCK"===n.type){const e="selector"in n?n.selector(t):he(t);for(const t of e)o.push({...n,id:t,type:"DATA"})}else o.push(n);return o}function pe(e,t){if(!e.some((e=>"DATA-BLOCK"===e.type)))return e;const o=[];for(const n of e)if("DATA-BLOCK"===n.type){const e="selector"in n?n.selector(t):ae(t);for(const t of e)o.push({...n,id:t,type:"DATA"})}else o.push(n);return o}const me=({text:e,expression:t})=>e.includes(t);class ge{constructor(e){this.rulesLookup=new F;for(const t of e){const e={by:o("by"in t?t.by:"FILTER"),condition:t.condition||me};this.rulesLookup.addRule(t.column,t.row,e)}}resolve(e,t,o,n,r,i,s,l){const d=this.rulesLookup.getRules(r,n);if(0===d.length)return"DATA"!==n.type||"DATA"!==r.type||!l.has('"FILTER"')||me({text:s,expression:l.get('"FILTER"')});let u={data:e,rows:t,columns:o,row:n,column:r,value:i,text:s};for(const e of d){if(!l.has(e.by))continue;const t={...u,expression:l.get(e.by)};if(!e.condition(t))return!1}return!0}}function ye(e){return new ge(e)}function we(e){return h(e,["value","text"])}function xe(e){return h(e,["value","text","font","padding"])}function be(e,t,o,n,r,i){if(e.every((e=>"number"==typeof e.width)))return e;const s=e=>{const i=e.width;if("number"==typeof i)return i;if(r.has(e.key)){const t=r.get(e.key);if("fit-once"===i&&!t.dataOnly)return t.width;if("fit-data-once"===i&&t.dataOnly)return t.width}let s=0;for(const r of t){if("DATA"!==r.type&&"fit-data-once"===i)continue;if("DATA"!==r.type&&"fit-data"===i)continue;const t=n.resolve(r,e),l=t.text,d=t.font,u=t.padding.left+t.padding.right,c=o.measureWidth(l,d)+u;s=Math.max(s,c)}return r.set(e.key,{width:s,dataOnly:"fit-data-once"===i}),s};for(const e of r.keys())i.has(e)||r.delete(e);return e.map((e=>({...e,width:s(e)})))}function ve(e,t,o,n,r,i){if(t.every((e=>"number"==typeof e.height)))return t;const s=t=>{const i=t.height;if("number"==typeof i)return i;if(r.has(t.key)){const e=r.get(t.key);if("fit-once"===i&&!e.dataOnly)return e.height;if("fit-data-once"===i&&e.dataOnly)return e.height}let s=0;for(const r of e){if("DATA"!==r.type&&"fit-data-once"===i)continue;if("DATA"!==r.type&&"fit-data"===i)continue;const e=n.resolve(t,r),l=e.text,d=e.font,u=e.padding.top+e.padding.bottom,c=o.measureHeight(l,d)+u;s=Math.max(s,c)}return r.set(t.key,{height:s,dataOnly:"fit-data-once"===i}),s};for(const e of r.keys())i.has(e)||r.delete(e);return t.map((e=>({...e,height:s(e)})))}function Re(e){return new Set(e.map((e=>e.key)))}function Ee(e){return h(e,["value","text"])}function Ae(e,t){return null!=e.value&&(null==t.value||e.value<t.value)}function ke(e,t){return null!=e.value&&(null==t.value||e.value>t.value)}class Ce{constructor(e){this.rulesLookup=new F;for(const t of e){const e=t.comparator?(e,o)=>t.comparator(e,o):(e,t)=>Ae(e,t),n=t.comparator?(e,o)=>!t.comparator(e,o):(e,t)=>ke(e,t),r={by:o("by"in t?t.by:"HEADER"),comparatorAsc:e,comparatorDesc:n};this.rulesLookup.addRule(t.column,t.row,r)}}resolve(e,t,o){const n=this.rulesLookup.getRules(e,t);if(0===n.length)return"DATA"!==t.type||"DATA"!==e.type?null:o.has('"HEADER"')?"ASC"===o.get('"HEADER"')?Ae:ke:null;if(n.length>1)throw new Error("Multiple sorting rules for the same cell");const r=n[0];return o.has(r.by)?"ASC"===o.get(r.by)?r.comparatorAsc:r.comparatorDesc:null}}function Ie(e){return new Ce(e)}function Te(e,t,n){const r=new Map;for(const i of e){const e=o(i[t]),s=o(i[n]);r.has(e)||r.set(e,new Map),r.get(e).set(s,i.direction)}return r}function Le(e,t){e.sort(((e,t)=>{const o=e.comparator(e.cell,t.cell);return"number"==typeof o?o:o?-1:1})),t.push(...e.map((e=>e.entity))),e.length=0}function Be(e,t,n,r,i,s,l){if(0===e.length)return i;const d=Te(e,"columnId","rowId"),u=new Map(s.map((e=>[e.key,e]))),c=e.map((e=>o(e.columnId))).filter((e=>u.has(e))).map((e=>u.get(e))).reverse();if(0===c.length)return i;for(const e of c){const o=[],u=[];for(const c of i){const a=t.resolve(e,c,d.get(e.key));if(!a){Le(u,o),o.push(c);continue}const h={entity:c,comparator:a,cell:n.resolve(r,i,s,c,e,l)};0!==u.length&&u[0].comparator!==a?(Le(u,o),u.push(h)):u.push(h)}Le(u,o),i=o}return i}function De(e,t,n,r,i,s,l){if(0===e.length)return s;const d=Te(e,"rowId","columnId"),u=new Map(i.map((e=>[e.key,e]))),c=e.map((e=>o(e.rowId))).filter((e=>u.has(e))).map((e=>u.get(e))).reverse();if(0===c.length)return s;for(const e of c){const o=[],u=[];for(const c of s){const a=t.resolve(c,e,d.get(e.key));if(!a){Le(u,o),o.push(c);continue}const h={entity:c,comparator:a,cell:n.resolve(r,i,s,e,c,l)};0!==u.length&&u[0].comparator!==a?(Le(u,o),u.push(h)):u.push(h)}Le(u,o),s=o}return s}const Me=5;function Fe(e,t,n,r,i,s,l,d,u){if(!r)return null;if(l)return null;const c=t.get(o(r.columnId));if("HEADER"!==n.get(o(r.rowId)).type)return null;const a=ne(i,s,d,u);if(!a)return null;const h=a.x;return h>=c.right-Me&&h<=c.right+Me?c.id:0===c.index||h<c.left-Me||h>c.left+Me?null:e[c.index-1].id}function Se(e,t,n,r,i,s,l,d,u){if(!r)return null;if(l)return null;const c=t.get(o(r.columnId)),a=n.get(o(r.rowId));if("HEADER"!==c.type)return null;const h=ne(i,s,d,u);if(!h)return null;const f=h.y;return f>=a.bottom-Me&&f<=a.bottom+Me?a.id:0===a.index||f<a.top-Me||f>a.top+Me?null:e[a.index-1].id}function ze(e){return e.map((e=>({columnId:"columnId"in e?e.columnId:"HEADER",rowId:"rowId"in e?e.rowId:"HEADER",direction:e.direction})))}function Oe(e){return e.map((e=>({columnId:"columnId"in e?e.columnId:"FILTER",rowId:"rowId"in e?e.rowId:"FILTER",expression:e.expression})))}function Ne(e,t){return function(e,t){const o=e.filter((e=>"DATA"===e.type)).map((e=>e.id));return t(o),o}(e,t)}function Ke(e){return h(e,["value","text","tooltip"])}function Pe(e,t,n,r){if(!e)return null;const i=o(e.columnId),s=o(e.rowId);if(!n.has(i))return null;if(!r.has(s))return null;const l=r.get(s),d=n.get(i);return t.resolve(l,d).tooltip}function He(e,t,o,n,r){if(!e)return null;const i=le(t,o,n,r);return i?{top:i.top,left:i.left}:null}function We(e){return e.map((e=>o(e)))}function $e(e,t){if(!t)return e;const o=new Map;for(const t of e)o.set(t.key,t);const n=[];for(const e of t)o.has(e)&&(n.push(o.get(e)),o.delete(e));for(const t of e)o.has(t.key)&&n.push(o.get(t.key));return[...n.filter((e=>"BEGIN"===e.pinned)),...n.filter((e=>!e.pinned)),...n.filter((e=>"END"===e.pinned))]}function qe(e){const t={...e.localOptions,...e.externalOptions},o=e.memory,n=e.state,i=e.element;function s(e,t,n){const r=o[e]&&o[e].dependencies;return r&&!n.some(((e,t)=>e!==r[t]))||(o[e]={value:t(...n),dependencies:n}),o[e].value}const l=window.devicePixelRatio,d=t.borderWidth/l,c=t.data,a=e.input.value,h=s("sortBy",ze,[t.sortBy]),p=s("filters",Oe,[t.filters]),w=s("textResolver",U,[]),b=s("dataFormatting",u,[t.formatting,t.dataSelector,h]),E=s("editedCellsAndFilters",y,[t.editedCells,p]),A=s("edition",x,[E]),L=s("invokedColumns",R,[t.columns,c]),B=s("invokedRows",R,[t.rows,c]),D=s("unfoldedColumns",fe,[L,c]),M=s("unfoldedRows",pe,[B,c]),F=s("unfilteredColumns",k,[D,t.pinnedLeft,t.pinnedRight,t.columnWidths]),S=s("unfilteredRows",C,[M,t.pinnedTop,t.pinnedBottom,t.rowHeights]),z=s("unfilteredColumnKeys",Re,[F]),O=s("unfilteredRowKeys",Re,[S]),N=s("columnsOrder",We,[t.columnsOrder]),K=s("rowsOrder",We,[t.rowsOrder]),H=s("orderedColumns",$e,[F,N]),$=s("orderedRows",$e,[S,K]),j=s("filterFormatting",we,[b]),se=s("filterFormattingRules",P,[j]),le=s("filteringRules",ye,[t.filtering]),ce=s("filteredColumns",V,[p,le,se,c,$,H,A]),ae=s("filteredRows",q,[p,le,se,c,$,H,A]),he=s("sortingFormatting",Ee,[b]),me=s("sortingFormattingRules",P,[he]),ge=s("sortingRules",Ie,[t.sorting]),Ae=s("sortedColumns",De,[h,ge,me,c,ae,ce,A]),ke=s("sortedRows",Be,[h,ge,me,c,ae,ce,A]),Ce=s("measureFormatting",xe,[b]),Te=s("measureFormattingRules",P,[Ce]),Le=s("measureFormatResolver",W,[Te,c,ke,Ae,A]),Me=e.columnWidthCache,qe=e.rowHeightCache,Ve=s("measuredColumns",be,[Ae,ke,w,Le,Me,z]),Ye=s("measuredRows",ve,[Ae,ke,w,Le,qe,O]),Ge=s("columns",I,[Ve,l,d]),je=s("rows",T,[Ye,l,d]),Ue=s("columnLookup",re,[Ge]),_e=s("rowLookup",re,[je]),Xe=t.focusedCell,Je=s("sections",g,[Ge,je]),Qe=t.selectedCells,Ze=s("fixedSize",Y,[Je.top.height,Je.bottom.height,Je.left.width,Je.right.width]),et=s("totalSize",G,[Ge,je]),tt=function(e,t,o,n,r,i){if(!t)return null;if(t.x<0||t.y<0||t.x>i.width||t.y>i.height)return null;const s=ne(e,t,r,i),l=function(e,t){if(0===e.length)return-1;if(t<e[0].topWithBorder)return-1;if(t>e[e.length-1].bottomWithBorder)return-1;let o=0,n=e.length-1;for(;o<=n;){const r=Math.floor((o+n)/2);if(t<e[r].topWithBorder)n=r-1;else{if(!(t>e[r].bottomWithBorder))return r;o=r+1}}return-1}(o,s.y),d=function(e,t){if(0===e.length)return-1;if(t<e[0].leftWithBorder)return-1;if(t>e[e.length-1].rightWithBorder)return-1;let o=0,n=e.length-1;for(;o<=n;){const r=Math.floor((o+n)/2);if(t<e[r].leftWithBorder)n=r-1;else{if(!(t>e[r].rightWithBorder))return r;o=r+1}}return-1}(n,s.x);return-1===l||-1===d?null:{rowId:o[l].id,columnId:n[d].id}}(i,e.mousePosition,je,Ge,Ze,et),ot=e.isReordering,nt=e.resizingColumn||s("resizableColumn",Fe,[Ge,Ue,_e,tt,i,e.mousePosition,ot,Ze,et]),rt=e.resizingRow||s("resizableRow",Se,[je,Ue,_e,tt,i,e.mousePosition,ot,Ze,et]),it=s("highlightedCells",ie,[e.isMouseDown,!nt&&!rt&&!e.didReorder,Xe,tt,Ge,je,Ue,_e]),st=s("selection",v,[Qe]),lt=s("highlight",v,[it]),dt=s("renderFormatting",m,[b,tt,Xe,st,lt,A,h,nt,rt,t.borderWidth,ot,e.reorderedColumn,e.reorderedRow]),ut=s("renderFormattingRules",P,[dt]),ct=s("renderFormatResolver",W,[ut,c,je,Ge,A]),at=s("inputFormatting",f,[b]),ht=s("inputFormattingRules",P,[at]),ft=s("inputFormatResolver",W,[ht,c,je,Ge,A]),pt=s("editableCells",r,[Qe,ft,Ue,_e]),mt=s("inputPlacement",de,[pt,Xe,Ue,_e,Je]),gt=s("isTextValid",ue,[a,pt]),yt=s("contextFormatting",Ke,[b]),wt=s("contextFormattingRules",P,[yt]),xt=s("contextFormatResolver",W,[wt,c,je,Ge,A]),bt=s("tooltip",Pe,[tt,xt,Ue,_e]),vt=s("tooltipPlacement",He,[bt,tt,Ue,_e,Je]),Rt=function(e,t,o,n){const r={width:n.getBoundingClientRect().width,height:n.getBoundingClientRect().height},i={left:n.scrollLeft,top:n.scrollTop},s=e||oe,l=Z({left:0,top:0,...t},o),d=Z({...i,...r},o),u=X(l,J(d,ee)),c=X(l,J(d,te));return _(l,s)&&_(s,u)?Q(s)>2*Q(c)?c:s:c}(n?.scrollRect,et,Ze,i);s("activeColumns",Ne,[Ge,t.onActiveColumnsChange]),s("activeRows",Ne,[je,t.onActiveRowsChange]),e.state={options:t,devicePixelRatio:l,borderWidth:d,data:c,edition:A,filteredColumns:ce,filteredRows:ae,columns:Ge,rows:je,sections:Je,selectedCells:Qe,selection:st,highlight:lt,hoveredCell:tt,focusedCell:Xe,renderFormatting:dt,renderFormatResolver:ct,inputFormatting:at,inputFormatResolver:ft,fixedSize:Ze,totalSize:et,textResolver:w,scrollRect:Rt,highlightedCells:it,inputPlacement:mt,columnLookup:Ue,rowLookup:_e,text:a,isTextValid:gt,resizableColumn:nt,resizableRow:rt,tooltip:bt,tooltipPlacement:vt}}function Ve(e){if(!e.error)try{qe(e)}catch(t){e.error=t}}function Ye(e,t){const o=new b(t);return[...t,...e.filter((e=>!o.isIdSelected(e.rowId,e.columnId)))]}function Ge(e,t){const o=new b(t);return e.filter((e=>!o.isIdSelected(e.rowId,e.columnId)))}function je(e){const t=e.currentTarget.getBoundingClientRect();return{x:e.clientX-t.left,y:e.clientY-t.top}}function Ue(e,t){return e.map((e=>({...e,columnId:"id"in e?e.id:t,rowId:"id"in e?e.id:t})))}function _e(e,t,n){const r=o(t),i=o(n);if(r===i)return null;const s=e.findIndex((e=>e.key===r)),l=e.findIndex((e=>e.key===i));return-1===s||-1===l||s===l?null:[s,l]}function Xe(e){if("spread-grid-context"in e)return;const t={"top-left":document.createElement("canvas"),"top-center":document.createElement("canvas"),"top-right":document.createElement("canvas"),"middle-left":document.createElement("canvas"),"middle-center":document.createElement("canvas"),"middle-right":document.createElement("canvas"),"bottom-left":document.createElement("canvas"),"bottom-center":document.createElement("canvas"),"bottom-right":document.createElement("canvas")},i=document.createElement("input"),s=document.createElement("div");e.setAttribute("tabindex","0"),e.setAttribute("style","max-width: 100vw; max-height: 100vh; overflow: auto; display: grid; position: relative; grid-template-columns: fit-content(0) fit-content(0) fit-content(0); grid-template-rows: fit-content(0) fit-content(0) fit-content(0); outline: none; user-select: none;"),e.classList.add("spread-grid"),t["top-left"].setAttribute("style","position: sticky; left: 0; top: 0; z-index: 2; grid-row: 1; grid-column: 1;"),t["top-center"].setAttribute("style","position: sticky; top: 0; z-index: 1; grid-row: 1; grid-column: 2;"),t["top-right"].setAttribute("style","position: sticky; right: 0; top: 0; z-index: 2; grid-row: 1; grid-column: 3;"),t["middle-left"].setAttribute("style","position: sticky; left: 0; z-index: 1; grid-row: 2; grid-column: 1;"),t["middle-center"].setAttribute("style","grid-row: 2; grid-column: 2; z-index: 0;"),t["middle-right"].setAttribute("style","position: sticky; right: 0; z-index: 1; grid-row: 2; grid-column: 3;"),t["bottom-left"].setAttribute("style","position: sticky; left: 0; bottom: 0; z-index: 2; grid-row: 3; grid-column: 1;"),t["bottom-center"].setAttribute("style","position: sticky; bottom: 0; z-index: 1; grid-row: 3; grid-column: 2;"),t["bottom-right"].setAttribute("style","position: sticky; right: 0; bottom: 0; z-index: 2; grid-row: 3; grid-column: 3;"),i.setAttribute("style","position: sticky; z-index: 3; outline: none; border: none; box-shadow: none; padding: 0 5px; font-size: 12px; font-family: Calibri; background-color: white; box-sizing: border-box; opacity: 0; pointer-events: none;"),s.setAttribute("style","pointer-events: none; background-color: white; color: black; border: 1px solid black; padding: 5px;"),s.setAttribute("popover","");const d={externalOptions:{},state:null,memory:{},element:e,canvases:t,input:i,tooltip:s,renderRequested:!1,mousePosition:null,isMouseDown:!1,columnWidthCache:new Map,rowHeightCache:new Map,requestNewRender:()=>{d.renderRequested||(d.renderRequested=!0,requestAnimationFrame((()=>{d.renderRequested=!1,Ve(d),l(d)})))},addEventListener:(e,t,o)=>{e.addEventListener(t,(e=>{try{o(e)}catch(e){e.message=`[${t} event]: ${e.message}`,d.error=e,d.requestNewRender()}}))}};d.localOptions={data:[],columns:[{type:"DATA-BLOCK"}],rows:[{type:"HEADER"},{type:"DATA-BLOCK"}],formatting:[],filtering:[],sorting:[],dataSelector:({data:e,row:t,column:o})=>e?.[t.id]?.[o.id],pinnedTop:0,pinnedBottom:0,pinnedLeft:0,pinnedRight:0,borderWidth:1,focusedCell:null,onFocusedCellChange:e=>{d.localOptions.focusedCell=e,d.requestNewRender()},selectedCells:[],onSelectedCellsChange:e=>{d.localOptions.selectedCells=e,d.requestNewRender()},highlightedCells:[],editedCells:[],onEditedCellsChange:e=>{d.localOptions.editedCells=e,d.requestNewRender()},filters:[],onFiltersChange:e=>{d.localOptions.filters=e,d.requestNewRender()},sortBy:[],onSortByChange:e=>{d.localOptions.sortBy=e,d.requestNewRender()},onCellClick:()=>{},onCustomCellClick:()=>{},columnWidths:[],onColumnWidthsChange:e=>{d.localOptions.columnWidths=e,d.requestNewRender()},rowHeights:[],onRowHeightsChange:e=>{d.localOptions.rowHeights=e,d.requestNewRender()},columnsOrder:[],onColumnsOrderChange:e=>{d.localOptions.columnsOrder=e,d.requestNewRender()},rowsOrder:[],onRowsOrderChange:e=>{d.localOptions.rowsOrder=e,d.requestNewRender()},onActiveColumnsChange:()=>{},onActiveRowsChange:()=>{}},e["spread-grid-context"]=d;const u=e=>{i.value=e,i.dispatchEvent(new Event("input"))},c=e=>{const t=d.state.options.selectedCells,o=d.state.inputFormatResolver,n=d.state.columnLookup,i=d.state.rowLookup,s=d.state.text,l=d.state.isTextValid,c=d.state.options.onEditedCellsChange,a=d.state.options.onFiltersChange,h=r(t,o,n,i);if(""===s)return;if(!l)return;if(e&&!h.every((e=>e.edit.autoCommit)))return;const f=h.filter((e=>"DATA"===e.type)),p=h.filter((e=>"FILTER"===e.type));var m;m=f.map((e=>({...e.cell,value:e.edit.parse({string:s})}))),c(Ye(d.state.options.editedCells,m)),(e=>{a(Ye(Ue(d.state.options.filters,"FILTER"),e))})(p.map((e=>({...e.cell,expression:e.edit.parse({string:s})})))),e||u("")},a=e=>{const t=d.state.options.selectedCells,o=d.state.options.onEditedCellsChange,n=d.state.options.onFiltersChange,i=r(t,d.state.inputFormatResolver,d.state.columnLookup,d.state.rowLookup);var s;e&&!i.every((e=>e.edit.autoCommit))||(s=t,o(Ge(d.state.options.editedCells,s)),(e=>{n(Ge(Ue(d.state.options.filters,"FILTER"),e))})(t))};d.addEventListener(e,"scroll",(e=>{d.requestNewRender()})),d.addEventListener(e,"mouseenter",(e=>{d.mousePosition=je(e),d.requestNewRender()})),d.addEventListener(e,"mousemove",(t=>{if(d.mousePosition=je(t),d.resizingColumn){const t=d.state.columnLookup.get(o(d.resizingColumn)),n=t.width,r=t.right,i=ne(e,d.mousePosition,d.state.fixedSize,d.state.totalSize),s=Math.max(10,i.x-r+n),l=d.state.options.columnWidths.filter((e=>o(e.columnId)!==t.key)).concat([{columnId:t.id,width:s}]);d.state.options.onColumnWidthsChange(l)}if(d.resizingRow){const t=d.state.rowLookup.get(o(d.resizingRow)),n=t.height,r=t.bottom,i=ne(e,d.mousePosition,d.state.fixedSize,d.state.totalSize),s=Math.max(10,i.y-r+n),l=d.state.options.rowHeights.filter((e=>o(e.rowId)!==t.key)).concat([{rowId:t.id,height:s}]);d.state.options.onRowHeightsChange(l)}if(d.reorderedColumn){const t=d.state.columns,o=d.state.hoveredCell,n=ne(e,d.mousePosition,d.state.fixedSize,d.state.totalSize),r=function(e,t,o,n){if(!o)return null;const r=_e(e,t,o.columnId);if(!r)return null;const[i,s]=r,l=s<=i?n.x<e[s].leftWithBorder+e[i].width?s:s+1:n.x>e[s].rightWithBorder-e[i].width?s:s-1;if(l===i)return null;const d=e.map((e=>e.id));return d.splice(i,1),d.splice(l,0,t),d}(t,d.reorderedColumn,o,n);r&&(d.didReorder=!0,d.isReordering=!0,d.state.options.onColumnsOrderChange(r))}if(d.reorderedRow){const t=d.state.rows,o=d.state.hoveredCell,n=ne(e,d.mousePosition,d.state.fixedSize,d.state.totalSize),r=function(e,t,o,n){if(!o)return null;const r=_e(e,t,o.rowId);if(!r)return null;const[i,s]=r,l=s<=i?n.y<e[s].topWithBorder+e[i].height?s:s+1:n.y>e[s].bottomWithBorder-e[i].height?s:s-1;if(l===i)return null;const d=e.map((e=>e.id));return d.splice(i,1),d.splice(l,0,t),d}(t,d.reorderedRow,o,n);r&&(d.didReorder=!0,d.isReordering=!0,d.state.options.onRowsOrderChange(r))}d.requestNewRender()})),d.addEventListener(e,"mouseleave",(()=>{d.mousePosition=null,d.requestNewRender()})),d.addEventListener(e,"mousedown",(e=>{Ve(d),u("");const t=d.state.hoveredCell;if(d.isMouseDown=!0,d.didReorder=!1,d.mouseDownPosition=d.mousePosition,d.mouseDownCell=t,d.state.resizableColumn&&(d.resizingColumn=d.state.resizableColumn),d.state.resizableRow&&(d.resizingRow=d.state.resizableRow),!d.resizingColumn&&t){const e=d.state.rowLookup.get(o(t.rowId));d.reorderedColumn="HEADER"===e.type?t.columnId:null}if(!d.resizingRow&&t){const e=d.state.columnLookup.get(o(t.columnId));d.reorderedRow="HEADER"===e.type?t.rowId:null}d.resizingColumn||d.resizingRow||d.state.options.onFocusedCellChange(t),e.ctrlKey||d.state.options.onSelectedCellsChange([]),d.requestNewRender()})),d.addEventListener(e,"mouseup",(e=>{Ve(d),d.isMouseDown=!1,d.isReordering=!1,d.resizingColumn=null,d.resizingRow=null,d.reorderedColumn=null,d.reorderedRow=null,d.state.options.onSelectedCellsChange(Ye(d.state.options.selectedCells,d.state.highlightedCells)),d.requestNewRender()})),d.addEventListener(e,"pointerdown",(e=>{d.element.setPointerCapture(e.pointerId)})),d.addEventListener(e,"pointerup",(e=>{d.element.releasePointerCapture(e.pointerId)})),d.addEventListener(e,"click",(e=>{Ve(d);const t=d.state.hoveredCell,r=d.mouseDownCell;if(d.state.resizableColumn||d.state.resizableRow)return;if(d.didReorder)return;if(null===t)return;if(o(t.columnId)!==o(r.columnId))return;if(o(t.rowId)!==o(r.rowId))return;const i=d.state.columnLookup.get(o(t.columnId)),s=d.state.rowLookup.get(o(t.rowId)),l=d.state.options.sortBy,u=d.state.inputFormatResolver.resolve(s,i),c={ctrlKey:e.ctrlKey,shiftKey:e.shiftKey,button:e.button,buttons:e.buttons};if(u.edit?.toggle){const e=function(e,t,o,n){const r=n.hasValueByKey(o.key,t.key)?n.getValueByKey(o.key,t.key):e.value,i=e.edit.toggle;return"function"==typeof i?i({value:r}):i[(i.indexOf(r)+1)%i.length]}(u,i,s,d.state.edition),o=n(i,s);"DATA"===o&&d.state.options.onEditedCellsChange(Ye(d.state.options.editedCells,[{...t,value:e}])),"FILTER"===o&&d.state.options.onFiltersChange(Ye(d.state.options.filters,[{...t,expression:e}]))}else if("DATA"===i.type&&"DATA"===s.type)d.state.options.onCellClick({...d.state.hoveredCell,...c});else if("CUSTOM"===i.type||"CUSTOM"===s.type)d.state.options.onCustomCellClick({...d.state.hoveredCell,...c});else if("HEADER"===i.type||"HEADER"===s.type){const t=function(e,t,n,r){function i(e){const r="columnId"in e?e.columnId:"HEADER",i="rowId"in e?e.rowId:"HEADER";return t.key===o(r)&&n.key===o(i)}const s=["ASC","DESC",void 0],l=e.find(i),d=s.indexOf(l?.direction),u=s[(d+1)%s.length],c=e.indexOf(l)===e.length-1;return[...!r||!c&&l?e.filter((e=>!function(e){const r="columnId"in e?e.columnId:"HEADER",i="rowId"in e?e.rowId:"HEADER";return"HEADER"===t.type&&t.key===o(r)||"HEADER"===n.type&&n.key===o(i)}(e))):e.filter((e=>!i(e))),...u?[{columnId:t.id,rowId:n.id,direction:u}]:[]]}(l,i,s,e.ctrlKey);d.state.options.onSortByChange(t),d.state.options.onSelectedCellsChange([])}})),d.addEventListener(e,"dblclick",(e=>{if(Ve(d),d.state.resizableColumn){const e=o(d.state.resizableColumn),t=d.state.options.columnWidths.filter((t=>o(t.columnId)!==e));d.state.options.onColumnWidthsChange(t),d.columnWidthCache.delete(e)}if(d.state.resizableRow){const e=o(d.state.resizableRow),t=d.state.options.rowHeights.filter((t=>o(t.rowId)!==e));d.state.options.onRowHeightsChange(t),d.rowHeightCache.delete(e)}const t=d.state.focusedCell;if(null===t)return;const n=o(t.columnId),r=o(t.rowId),s=d.state.columnLookup,l=d.state.rowLookup,c=d.state.inputFormatResolver;if(!s.has(n))return;if(!l.has(r))return;const a=s.get(n),h=l.get(r),f=c.resolve(h,a),p=f.text;f.edit&&(f.edit.toggle||(u(p),i?.select()))})),d.addEventListener(e,"focus",(()=>{i.parentElement&&i.focus({preventScroll:!0})})),d.addEventListener(e,"keydown",(e=>{Ve(d);const t=d.state.focusedCell,n=d.state.columnLookup,r=d.state.rowLookup,i=d.state.options.selectedCells,s=d.state.options.onSelectedCellsChange,l=d.state.options.onFocusedCellChange,h=d.state.options.editedCells,f=d.state.options.onEditedCellsChange,p=d.state.columns,m=d.state.rows,g=d.state.text,y=d.state.inputFormatResolver,w=(e,t)=>{l(e),t.shiftKey?s(Ye(i,[e])):s([e])},x=(e,r)=>{if(!t)return;const i=o(t.columnId);if(!n.has(i))return;const s=n.get(i).index,l=Math.max(0,Math.min(p.length-1,s+e));if(l===s)return;const d={rowId:t.rowId,columnId:p[l].id};w(d,r)},v=(e,n)=>{if(!t)return;const i=o(t.rowId);if(!r.has(i))return;const s=r.get(i).index,l=Math.max(0,Math.min(m.length-1,s+e));if(l===s)return;const d={rowId:m[l].id,columnId:t.columnId};w(d,n)},R=()=>{e.preventDefault(),e.stopPropagation()};switch(e.key){case"Escape":""!==g?u(""):i.length>1?s([t]):h.length>0?f([]):(l(null),s([]));break;case"Enter":c();break;case"ArrowUp":R(),v(e.ctrlKey?-m.length:-1,e);break;case"ArrowDown":R(),v(e.ctrlKey?m.length:1,e);break;case"ArrowLeft":R(),x(e.ctrlKey?-p.length:-1,e);break;case"ArrowRight":R(),x(e.ctrlKey?p.length:1,e);break;case"Delete":case"Backspace":a();break;case"c":(e=>{if(!e.ctrlKey)return;const t=function(e,t,n,r){const i=new Map(t.map((e=>[e.key,e]))),s=new Map(n.map((e=>[e.key,e]))),l=e.map((e=>({columnKey:o(e.columnId),rowKey:o(e.rowId)}))).filter((e=>i.has(e.columnKey)&&s.has(e.rowKey))),d=new Set(l.map((e=>e.columnKey))),u=new Set(l.map((e=>e.rowKey)));if(0===l.length)return"";const c=new b(e),a=Math.min(...l.map((e=>i.get(e.columnKey).index))),h=Math.max(...l.map((e=>i.get(e.columnKey).index))),f=Math.min(...l.map((e=>s.get(e.rowKey).index))),p=Math.max(...l.map((e=>s.get(e.rowKey).index))),m=[];for(let e=f;e<=p;e++){const o=n[e],i=o.key;if(u.has(i)){for(let e=a;e<=h;e++){const n=t[e],s=n.key;if(d.has(s)){if(c.isKeySelected(i,s)){const e=r.resolve(o,n).text;m.push(e)}e<h&&m.push("\t")}}e<p&&m.push("\n")}}return m.join("")}(i,p,m,y);if(navigator.clipboard)navigator.clipboard.writeText(t);else{const e=document.createElement("textarea");e.value=t,document.body.appendChild(e),e.select(),document.execCommand("copy"),document.body.removeChild(e)}})(e)}})),new ResizeObserver((()=>{d.requestNewRender()})).observe(e),d.addEventListener(i,"input",(e=>{Ve(d),e.target.value?(c(!0),i.style.opacity=1,i.style.pointerEvents="auto"):(e.isTrusted&&a(!0),i.style.opacity=0,i.style.pointerEvents="none")})),d.addEventListener(i,"click",(e=>{e.stopPropagation()})),d.addEventListener(i,"dblclick",(e=>{e.stopPropagation()})),d.addEventListener(i,"mousedown",(e=>{e.stopPropagation()})),d.addEventListener(i,"keydown",(e=>{switch(e.key){case"Enter":case"Escape":break;case"Delete":case"Backspace":case"ArrowUp":case"ArrowDown":case"ArrowLeft":case"ArrowRight":""!==i.value&&(e.stopPropagation(),d.requestNewRender());break;default:e.stopPropagation(),d.requestNewRender()}}))}function Je(e,t){Xe(e);const o=e["spread-grid-context"];o.externalOptions=t,null===o.state?(Ve(o),l(o)):o.requestNewRender()}return t.default})()));
|
package/package.json
CHANGED
package/src/core/render.js
CHANGED
|
@@ -346,7 +346,9 @@ function renderCursor(context) {
|
|
|
346
346
|
const element = context.element;
|
|
347
347
|
const state = context.state;
|
|
348
348
|
|
|
349
|
-
if (
|
|
349
|
+
if (context.isReordering)
|
|
350
|
+
element.style.cursor = 'move';
|
|
351
|
+
else if (state.resizableColumn && state.resizableRow)
|
|
350
352
|
element.style.cursor = 'nwse-resize';
|
|
351
353
|
else if (state.resizableColumn)
|
|
352
354
|
element.style.cursor = 'col-resize';
|
|
@@ -356,6 +358,28 @@ function renderCursor(context) {
|
|
|
356
358
|
element.style.cursor = 'default';
|
|
357
359
|
}
|
|
358
360
|
|
|
361
|
+
function renderTooltip(context) {
|
|
362
|
+
const element = context.element;
|
|
363
|
+
const tooltip = context.tooltip;
|
|
364
|
+
const content = context.state.tooltip;
|
|
365
|
+
const placement = context.state.tooltipPlacement;
|
|
366
|
+
|
|
367
|
+
if (!placement) {
|
|
368
|
+
if (tooltip.parentElement)
|
|
369
|
+
tooltip.parentElement.removeChild(tooltip);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
tooltip.innerHTML = content;
|
|
374
|
+
tooltip.style.left = `${placement.left}px`;
|
|
375
|
+
tooltip.style.top = `${placement.top}px`;
|
|
376
|
+
|
|
377
|
+
if (!tooltip.parentElement) {
|
|
378
|
+
element.appendChild(tooltip);
|
|
379
|
+
tooltip.showPopover();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
359
383
|
function renderInternal(context) {
|
|
360
384
|
renderSection(context, 'top', 'left');
|
|
361
385
|
renderSection(context, 'top', 'center');
|
|
@@ -369,6 +393,7 @@ function renderInternal(context) {
|
|
|
369
393
|
|
|
370
394
|
renderInput(context);
|
|
371
395
|
renderCursor(context);
|
|
396
|
+
renderTooltip(context);
|
|
372
397
|
}
|
|
373
398
|
|
|
374
399
|
function renderError(context) {
|
package/src/core/state.js
CHANGED
|
@@ -34,6 +34,11 @@ import { getResizableColumn, getResizableRow } from "../state-utils/getResizable
|
|
|
34
34
|
import getResolvedSortBy from "../state-utils/getResolvedSortBy.js";
|
|
35
35
|
import getResolvedFilters from "../state-utils/getResolvedFilters.js";
|
|
36
36
|
import { getActiveColumns } from "../state-utils/getActive.js";
|
|
37
|
+
import getContextFormatting from "../state-utils/getContextFormatting.js";
|
|
38
|
+
import getTooltip from "../state-utils/getTooltip.js";
|
|
39
|
+
import getTooltipPlacement from "../state-utils/getTooltipPlacement.js";
|
|
40
|
+
import getOrder from "../state-utils/getOrder.js";
|
|
41
|
+
import getOrdered from "../state-utils/getOrdered.js";
|
|
37
42
|
|
|
38
43
|
// TODO: write some test to check if the cache is working properly
|
|
39
44
|
function updateStateInternal(context) {
|
|
@@ -66,6 +71,8 @@ function updateStateInternal(context) {
|
|
|
66
71
|
const invokedRows = cache('invokedRows', getInvoked, [options.rows, data]);
|
|
67
72
|
// TODO: throw on duplicate ids
|
|
68
73
|
// TODO: throw on duplicate row/column filter ids
|
|
74
|
+
|
|
75
|
+
// Resolving
|
|
69
76
|
const unfoldedColumns = cache('unfoldedColumns', getUnfoldedColumns, [invokedColumns, data]);
|
|
70
77
|
const unfoldedRows = cache('unfoldedRows', getUnfoldedRows, [invokedRows, data]);
|
|
71
78
|
const unfilteredColumns = cache('unfilteredColumns', getResolvedColumns, [unfoldedColumns, options.pinnedLeft, options.pinnedRight, options.columnWidths]);
|
|
@@ -73,12 +80,18 @@ function updateStateInternal(context) {
|
|
|
73
80
|
const unfilteredColumnKeys = cache('unfilteredColumnKeys', getKeys, [unfilteredColumns]);
|
|
74
81
|
const unfilteredRowKeys = cache('unfilteredRowKeys', getKeys, [unfilteredRows]);
|
|
75
82
|
|
|
83
|
+
// Ordering
|
|
84
|
+
const columnsOrder = cache('columnsOrder', getOrder, [options.columnsOrder]);
|
|
85
|
+
const rowsOrder = cache('rowsOrder', getOrder, [options.rowsOrder]);
|
|
86
|
+
const orderedColumns = cache('orderedColumns', getOrdered, [unfilteredColumns, columnsOrder]);
|
|
87
|
+
const orderedRows = cache('orderedRows', getOrdered, [unfilteredRows, rowsOrder]);
|
|
88
|
+
|
|
76
89
|
// Filtering
|
|
77
90
|
const filterFormatting = cache('filterFormatting', getFilterFormatting, [dataFormatting]);
|
|
78
91
|
const filterFormattingRules = cache('filterFormattingRules', getFormattingRules, [filterFormatting]);
|
|
79
92
|
const filteringRules = cache('filteringRules', getFilteringRules, [options.filtering]);
|
|
80
|
-
const filteredColumns = cache('filteredColumns', getFilteredColumns, [filters, filteringRules, filterFormattingRules, data,
|
|
81
|
-
const filteredRows = cache('filteredRows', getFilteredRows, [filters, filteringRules, filterFormattingRules, data,
|
|
93
|
+
const filteredColumns = cache('filteredColumns', getFilteredColumns, [filters, filteringRules, filterFormattingRules, data, orderedRows, orderedColumns, edition]);
|
|
94
|
+
const filteredRows = cache('filteredRows', getFilteredRows, [filters, filteringRules, filterFormattingRules, data, orderedRows, orderedColumns, edition]);
|
|
82
95
|
|
|
83
96
|
// Sorting
|
|
84
97
|
const sortingFormatting = cache('sortingFormatting', getSortingFormatting, [dataFormatting]);
|
|
@@ -112,15 +125,16 @@ function updateStateInternal(context) {
|
|
|
112
125
|
const totalSize = cache('totalSize', getTotalSize, [columns, rows]);
|
|
113
126
|
// TODO: do some proper caching, so that if value is not changed, the old value is returned (currently not working because of scrolling)
|
|
114
127
|
const hoveredCell = getHoveredCell(element, context.mousePosition, rows, columns, fixedSize, totalSize);
|
|
115
|
-
const
|
|
116
|
-
const
|
|
128
|
+
const isReordering = context.isReordering;
|
|
129
|
+
const resizableColumn = context.resizingColumn || cache('resizableColumn', getResizableColumn, [columns, columnLookup, rowLookup, hoveredCell, element, context.mousePosition, isReordering, fixedSize, totalSize]);
|
|
130
|
+
const resizableRow = context.resizingRow || cache('resizableRow', getResizableRow, [rows, columnLookup, rowLookup, hoveredCell, element, context.mousePosition, isReordering, fixedSize, totalSize]);
|
|
117
131
|
const isMouseDown = context.isMouseDown;
|
|
118
|
-
const
|
|
119
|
-
const highlightedCells = cache('highlightedCells', getHighlightedCells, [isMouseDown,
|
|
132
|
+
const canHighlight = !resizableColumn && !resizableRow && !context.didReorder;
|
|
133
|
+
const highlightedCells = cache('highlightedCells', getHighlightedCells, [isMouseDown, canHighlight, focusedCell, hoveredCell, columns, rows, columnLookup, rowLookup]);
|
|
120
134
|
const selection = cache('selection', getSelection, [selectedCells]);
|
|
121
135
|
const highlight = cache('highlight', getSelection, [highlightedCells]);
|
|
122
136
|
// TODO: addDataFormattingRules and addRenderFormattingRules should remove unnecessary rules
|
|
123
|
-
const renderFormatting = cache('renderFormatting', getRenderFormatting, [dataFormatting, hoveredCell, focusedCell, selection, highlight, edition, sortBy, resizableColumn, resizableRow, options.borderWidth]);
|
|
137
|
+
const renderFormatting = cache('renderFormatting', getRenderFormatting, [dataFormatting, hoveredCell, focusedCell, selection, highlight, edition, sortBy, resizableColumn, resizableRow, options.borderWidth, isReordering, context.reorderedColumn, context.reorderedRow]);
|
|
124
138
|
const renderFormattingRules = cache('renderFormattingRules', getFormattingRules, [renderFormatting]);
|
|
125
139
|
const renderFormatResolver = cache('renderFormatResolver', getFormatResolver, [renderFormattingRules, data, rows, columns, edition]);
|
|
126
140
|
const inputFormatting = cache('inputFormatting', getInputFormatting, [dataFormatting]);
|
|
@@ -129,6 +143,11 @@ function updateStateInternal(context) {
|
|
|
129
143
|
const editableCells = cache('editableCells', getEditableCells, [selectedCells, inputFormatResolver, columnLookup, rowLookup]);
|
|
130
144
|
const inputPlacement = cache('inputPlacement', getInputPlacement, [editableCells, focusedCell, columnLookup, rowLookup, sections]);
|
|
131
145
|
const isTextValid = cache('isTextValid', getIsTextValid, [text, editableCells]);
|
|
146
|
+
const contextFormatting = cache('contextFormatting', getContextFormatting, [dataFormatting]);
|
|
147
|
+
const contextFormattingRules = cache('contextFormattingRules', getFormattingRules, [contextFormatting]);
|
|
148
|
+
const contextFormatResolver = cache('contextFormatResolver', getFormatResolver, [contextFormattingRules, data, rows, columns, edition]);
|
|
149
|
+
const tooltip = cache('tooltip', getTooltip, [hoveredCell, contextFormatResolver, columnLookup, rowLookup]);
|
|
150
|
+
const tooltipPlacement = cache('tooltipPlacement', getTooltipPlacement, [tooltip, hoveredCell, columnLookup, rowLookup, sections]);
|
|
132
151
|
|
|
133
152
|
// cache result, but not call
|
|
134
153
|
const scrollRect = getScrollRect(previousState?.scrollRect, totalSize, fixedSize, element);
|
|
@@ -142,7 +161,6 @@ function updateStateInternal(context) {
|
|
|
142
161
|
devicePixelRatio,
|
|
143
162
|
borderWidth,
|
|
144
163
|
data,
|
|
145
|
-
dataFormatting,
|
|
146
164
|
edition,
|
|
147
165
|
filteredColumns,
|
|
148
166
|
filteredRows,
|
|
@@ -170,6 +188,8 @@ function updateStateInternal(context) {
|
|
|
170
188
|
isTextValid,
|
|
171
189
|
resizableColumn,
|
|
172
190
|
resizableRow,
|
|
191
|
+
tooltip,
|
|
192
|
+
tooltipPlacement,
|
|
173
193
|
};
|
|
174
194
|
}
|
|
175
195
|
|
package/src/index.js
CHANGED
|
@@ -11,6 +11,7 @@ import getToggledValue from "./state-utils/getToggledValue.js";
|
|
|
11
11
|
import getCellEditType from "./state-utils/getCellEditType.js";
|
|
12
12
|
import getInternalPosition from "./state-utils/getInternalPosition.js";
|
|
13
13
|
import { getWithAssumedId } from "./state-utils/getWithAssumedId.js";
|
|
14
|
+
import { getReorderedColumns, getReorderedRows } from "./state-utils/getReordered.js";
|
|
14
15
|
|
|
15
16
|
function initialize(element) {
|
|
16
17
|
if ('spread-grid-context' in element) return;
|
|
@@ -29,6 +30,7 @@ function initialize(element) {
|
|
|
29
30
|
'bottom-right': document.createElement('canvas')
|
|
30
31
|
};
|
|
31
32
|
const input = document.createElement('input');
|
|
33
|
+
const tooltip = document.createElement('div');
|
|
32
34
|
|
|
33
35
|
element.setAttribute('tabindex', '0');
|
|
34
36
|
element.setAttribute('style', 'max-width: 100vw; max-height: 100vh; overflow: auto; display: grid; position: relative; grid-template-columns: fit-content(0) fit-content(0) fit-content(0); grid-template-rows: fit-content(0) fit-content(0) fit-content(0); outline: none; user-select: none;');
|
|
@@ -43,6 +45,8 @@ function initialize(element) {
|
|
|
43
45
|
canvases['bottom-center'].setAttribute('style', 'position: sticky; bottom: 0; z-index: 1; grid-row: 3; grid-column: 2;');
|
|
44
46
|
canvases['bottom-right'].setAttribute('style', 'position: sticky; right: 0; bottom: 0; z-index: 2; grid-row: 3; grid-column: 3;');
|
|
45
47
|
input.setAttribute('style', 'position: sticky; z-index: 3; outline: none; border: none; box-shadow: none; padding: 0 5px; font-size: 12px; font-family: Calibri; background-color: white; box-sizing: border-box; opacity: 0; pointer-events: none;');
|
|
48
|
+
tooltip.setAttribute('style', 'pointer-events: none; background-color: white; color: black; border: 1px solid black; padding: 5px;');
|
|
49
|
+
tooltip.setAttribute('popover', '');
|
|
46
50
|
|
|
47
51
|
const context = {
|
|
48
52
|
externalOptions: {},
|
|
@@ -51,6 +55,7 @@ function initialize(element) {
|
|
|
51
55
|
element: element,
|
|
52
56
|
canvases: canvases,
|
|
53
57
|
input: input,
|
|
58
|
+
tooltip: tooltip,
|
|
54
59
|
renderRequested: false,
|
|
55
60
|
mousePosition: null,
|
|
56
61
|
isMouseDown: false,
|
|
@@ -133,6 +138,16 @@ function initialize(element) {
|
|
|
133
138
|
context.localOptions.rowHeights = rowHeights;
|
|
134
139
|
context.requestNewRender();
|
|
135
140
|
},
|
|
141
|
+
columnsOrder: [],
|
|
142
|
+
onColumnsOrderChange: (columnsOrder) => {
|
|
143
|
+
context.localOptions.columnsOrder = columnsOrder;
|
|
144
|
+
context.requestNewRender();
|
|
145
|
+
},
|
|
146
|
+
rowsOrder: [],
|
|
147
|
+
onRowsOrderChange: (rowsOrder) => {
|
|
148
|
+
context.localOptions.rowsOrder = rowsOrder;
|
|
149
|
+
context.requestNewRender();
|
|
150
|
+
},
|
|
136
151
|
onActiveColumnsChange: () => { },
|
|
137
152
|
onActiveRowsChange: () => { },
|
|
138
153
|
};
|
|
@@ -234,6 +249,28 @@ function initialize(element) {
|
|
|
234
249
|
.concat([{ rowId: row.id, height: newRowHeight }]);
|
|
235
250
|
context.state.options.onRowHeightsChange(newRowHeights);
|
|
236
251
|
}
|
|
252
|
+
if (context.reorderedColumn) {
|
|
253
|
+
const columns = context.state.columns;
|
|
254
|
+
const hoveredCell = context.state.hoveredCell;
|
|
255
|
+
const internalPosition = getInternalPosition(element, context.mousePosition, context.state.fixedSize, context.state.totalSize);
|
|
256
|
+
const reorderedColumns = getReorderedColumns(columns, context.reorderedColumn, hoveredCell, internalPosition);
|
|
257
|
+
if (reorderedColumns) {
|
|
258
|
+
context.didReorder = true;
|
|
259
|
+
context.isReordering = true;
|
|
260
|
+
context.state.options.onColumnsOrderChange(reorderedColumns);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (context.reorderedRow) {
|
|
264
|
+
const rows = context.state.rows;
|
|
265
|
+
const hoveredCell = context.state.hoveredCell;
|
|
266
|
+
const internalPosition = getInternalPosition(element, context.mousePosition, context.state.fixedSize, context.state.totalSize);
|
|
267
|
+
const reorderedRows = getReorderedRows(rows, context.reorderedRow, hoveredCell, internalPosition);
|
|
268
|
+
if (reorderedRows) {
|
|
269
|
+
context.didReorder = true;
|
|
270
|
+
context.isReordering = true;
|
|
271
|
+
context.state.options.onRowsOrderChange(reorderedRows);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
237
274
|
|
|
238
275
|
// TODO: only request new render if hovered cell changed
|
|
239
276
|
context.requestNewRender();
|
|
@@ -250,9 +287,12 @@ function initialize(element) {
|
|
|
250
287
|
updateState(context);
|
|
251
288
|
setText('');
|
|
252
289
|
|
|
290
|
+
const hoveredCell = context.state.hoveredCell;
|
|
291
|
+
|
|
253
292
|
context.isMouseDown = true;
|
|
293
|
+
context.didReorder = false;
|
|
254
294
|
context.mouseDownPosition = context.mousePosition;
|
|
255
|
-
context.mouseDownCell =
|
|
295
|
+
context.mouseDownCell = hoveredCell;
|
|
256
296
|
|
|
257
297
|
if (context.state.resizableColumn) {
|
|
258
298
|
context.resizingColumn = context.state.resizableColumn;
|
|
@@ -260,8 +300,17 @@ function initialize(element) {
|
|
|
260
300
|
if (context.state.resizableRow) {
|
|
261
301
|
context.resizingRow = context.state.resizableRow;
|
|
262
302
|
}
|
|
263
|
-
if (!context.
|
|
264
|
-
context.state.
|
|
303
|
+
if (!context.resizingColumn && hoveredCell) {
|
|
304
|
+
const row = context.state.rowLookup.get(stringifyId(hoveredCell.rowId));
|
|
305
|
+
context.reorderedColumn = row.type === 'HEADER' ? hoveredCell.columnId : null;
|
|
306
|
+
}
|
|
307
|
+
if (!context.resizingRow && hoveredCell) {
|
|
308
|
+
const column = context.state.columnLookup.get(stringifyId(hoveredCell.columnId));
|
|
309
|
+
context.reorderedRow = column.type === 'HEADER' ? hoveredCell.rowId : null;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (!context.resizingColumn && !context.resizingRow) {
|
|
313
|
+
context.state.options.onFocusedCellChange(hoveredCell);
|
|
265
314
|
}
|
|
266
315
|
|
|
267
316
|
if (!event.ctrlKey)
|
|
@@ -274,8 +323,11 @@ function initialize(element) {
|
|
|
274
323
|
updateState(context);
|
|
275
324
|
|
|
276
325
|
context.isMouseDown = false;
|
|
326
|
+
context.isReordering = false;
|
|
277
327
|
context.resizingColumn = null;
|
|
278
328
|
context.resizingRow = null;
|
|
329
|
+
context.reorderedColumn = null;
|
|
330
|
+
context.reorderedRow = null;
|
|
279
331
|
|
|
280
332
|
context.state.options.onSelectedCellsChange(getCombinedCells(context.state.options.selectedCells, context.state.highlightedCells));
|
|
281
333
|
context.requestNewRender();
|
|
@@ -297,6 +349,8 @@ function initialize(element) {
|
|
|
297
349
|
|
|
298
350
|
if (context.state.resizableColumn || context.state.resizableRow)
|
|
299
351
|
return;
|
|
352
|
+
if (context.didReorder)
|
|
353
|
+
return;
|
|
300
354
|
if (cell === null)
|
|
301
355
|
return;
|
|
302
356
|
if (stringifyId(cell.columnId) !== stringifyId(mouseDownCell.columnId))
|
|
@@ -309,6 +363,12 @@ function initialize(element) {
|
|
|
309
363
|
const sortBy = context.state.options.sortBy;
|
|
310
364
|
const formatResolver = context.state.inputFormatResolver;
|
|
311
365
|
const cellData = formatResolver.resolve(row, column);
|
|
366
|
+
const eventProperties = {
|
|
367
|
+
ctrlKey: event.ctrlKey,
|
|
368
|
+
shiftKey: event.shiftKey,
|
|
369
|
+
button: event.button,
|
|
370
|
+
buttons: event.buttons
|
|
371
|
+
};
|
|
312
372
|
|
|
313
373
|
if (cellData.edit?.toggle) {
|
|
314
374
|
const edition = context.state.edition;
|
|
@@ -319,9 +379,9 @@ function initialize(element) {
|
|
|
319
379
|
if (cellType === 'FILTER')
|
|
320
380
|
context.state.options.onFiltersChange(getCombinedCells(context.state.options.filters, [{ ...cell, expression: newValue }]));
|
|
321
381
|
} else if (column.type === 'DATA' && row.type === 'DATA') {
|
|
322
|
-
context.state.options.onCellClick(context.state.hoveredCell);
|
|
382
|
+
context.state.options.onCellClick({ ...context.state.hoveredCell, ...eventProperties });
|
|
323
383
|
} else if (column.type === 'CUSTOM' || row.type === 'CUSTOM') {
|
|
324
|
-
context.state.options.onCustomCellClick(context.state.hoveredCell);
|
|
384
|
+
context.state.options.onCustomCellClick({ ...context.state.hoveredCell, ...eventProperties });
|
|
325
385
|
} else if (column.type === 'HEADER' || row.type === 'HEADER') {
|
|
326
386
|
const newSortBy = getNewSortBy(sortBy, column, row, event.ctrlKey);
|
|
327
387
|
context.state.options.onSortByChange(newSortBy);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import stringifyId from "../core-utils/stringifyId.js";
|
|
2
|
+
import getCellSection from "./getCellSection.js";
|
|
3
|
+
|
|
4
|
+
export default function getInputPlacement(cell, columnLookup, rowLookup, sections) {
|
|
5
|
+
if (!cell)
|
|
6
|
+
return null;
|
|
7
|
+
|
|
8
|
+
const columnKey = stringifyId(cell.columnId);
|
|
9
|
+
const rowKey = stringifyId(cell.rowId);
|
|
10
|
+
|
|
11
|
+
if (!columnLookup.has(columnKey))
|
|
12
|
+
return null;
|
|
13
|
+
if (!rowLookup.has(rowKey))
|
|
14
|
+
return null;
|
|
15
|
+
|
|
16
|
+
const column = columnLookup.get(columnKey);
|
|
17
|
+
const row = rowLookup.get(rowKey);
|
|
18
|
+
|
|
19
|
+
const position = {
|
|
20
|
+
width: column.width,
|
|
21
|
+
height: row.height,
|
|
22
|
+
section: getCellSection(column, row)
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
switch (row.pinned) {
|
|
26
|
+
case "BEGIN":
|
|
27
|
+
position.top = row.top;
|
|
28
|
+
break;
|
|
29
|
+
case "END":
|
|
30
|
+
position.bottom = sections.top.height + sections.middle.height + sections.bottom.height - row.top - row.height;
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
position.marginTop = row.top - sections.top.height;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
switch (column.pinned) {
|
|
37
|
+
case "BEGIN":
|
|
38
|
+
position.left = column.left;
|
|
39
|
+
break;
|
|
40
|
+
case "END":
|
|
41
|
+
position.right = sections.left.width + sections.center.width + sections.right.width - column.left - column.width;
|
|
42
|
+
break;
|
|
43
|
+
default:
|
|
44
|
+
position.marginLeft = column.left - sections.left.width;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return position;
|
|
48
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import FormattingRules from "../types/FormattingRules.js";
|
|
2
2
|
|
|
3
|
-
export default function getFormattingRules(
|
|
4
|
-
return new FormattingRules(
|
|
3
|
+
export default function getFormattingRules(formatting) {
|
|
4
|
+
return new FormattingRules(formatting);
|
|
5
5
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import stringifyId from "../core-utils/stringifyId.js";
|
|
2
2
|
|
|
3
|
-
export default function getHighlightedCells(isMouseDown,
|
|
3
|
+
export default function getHighlightedCells(isMouseDown, canHighlight, focusedCell, hoveredCell, columns, rows, columnLookup, rowLookup) {
|
|
4
4
|
if (!isMouseDown)
|
|
5
5
|
return [];
|
|
6
|
-
if (
|
|
6
|
+
if (!canHighlight)
|
|
7
7
|
return [];
|
|
8
8
|
if (!hoveredCell)
|
|
9
9
|
return [];
|
|
@@ -1,51 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import getCellSection from "./getCellSection.js";
|
|
1
|
+
import getCellPlacement from "./getCellPlacement.js";
|
|
3
2
|
|
|
4
3
|
export default function getInputPlacement(editableCells, focusedCell, columnLookup, rowLookup, sections) {
|
|
5
|
-
if (!focusedCell)
|
|
6
|
-
return null;
|
|
7
|
-
|
|
8
|
-
const focusedColumnKey = stringifyId(focusedCell.columnId);
|
|
9
|
-
const focusedRowKey = stringifyId(focusedCell.rowId);
|
|
10
|
-
|
|
11
|
-
if (!columnLookup.has(focusedColumnKey))
|
|
12
|
-
return null;
|
|
13
|
-
if (!rowLookup.has(focusedRowKey))
|
|
14
|
-
return null;
|
|
15
|
-
|
|
16
|
-
const column = columnLookup.get(focusedColumnKey);
|
|
17
|
-
const row = rowLookup.get(focusedRowKey);
|
|
18
|
-
|
|
19
4
|
if (editableCells.length === 0)
|
|
20
5
|
return null;
|
|
21
6
|
|
|
22
|
-
|
|
23
|
-
width: column.width,
|
|
24
|
-
height: row.height,
|
|
25
|
-
section: getCellSection(column, row)
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
switch (row.pinned) {
|
|
29
|
-
case "BEGIN":
|
|
30
|
-
position.top = row.top;
|
|
31
|
-
break;
|
|
32
|
-
case "END":
|
|
33
|
-
position.bottom = sections.top.height + sections.middle.height + sections.bottom.height - row.top - row.height;
|
|
34
|
-
break;
|
|
35
|
-
default:
|
|
36
|
-
position.marginTop = row.top - sections.top.height;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
switch (column.pinned) {
|
|
40
|
-
case "BEGIN":
|
|
41
|
-
position.left = column.left;
|
|
42
|
-
break;
|
|
43
|
-
case "END":
|
|
44
|
-
position.right = sections.left.width + sections.center.width + sections.right.width - column.left - column.width;
|
|
45
|
-
break;
|
|
46
|
-
default:
|
|
47
|
-
position.marginLeft = column.left - sections.left.width;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
return position;
|
|
7
|
+
return getCellPlacement(focusedCell, columnLookup, rowLookup, sections);
|
|
51
8
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export default function getOrdered(entries, order) {
|
|
2
|
+
if (!order) {
|
|
3
|
+
return entries;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
const map = new Map();
|
|
7
|
+
|
|
8
|
+
for (const entry of entries) {
|
|
9
|
+
map.set(entry.key, entry);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const mixedResult = [];
|
|
13
|
+
|
|
14
|
+
for (const key of order) {
|
|
15
|
+
if (map.has(key)) {
|
|
16
|
+
mixedResult.push(map.get(key));
|
|
17
|
+
map.delete(key);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
if (map.has(entry.key)) {
|
|
23
|
+
mixedResult.push(map.get(entry.key));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return [
|
|
28
|
+
...mixedResult.filter(entry => entry.pinned === "BEGIN"),
|
|
29
|
+
...mixedResult.filter(entry => !entry.pinned),
|
|
30
|
+
...mixedResult.filter(entry => entry.pinned === "END")
|
|
31
|
+
]
|
|
32
|
+
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
const commonFields = ['column', 'row', 'condition'];
|
|
2
2
|
|
|
3
3
|
function reduce(rule, fields) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
const reducedRule = {};
|
|
5
|
+
for (const field of fields) {
|
|
6
|
+
if (field in rule)
|
|
7
|
+
reducedRule[field] = rule[field];
|
|
8
|
+
}
|
|
9
|
+
return reducedRule;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
function hasImpact(rule) {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const allKeys = Object.keys(rule).length;
|
|
14
|
+
const commonKeys = Object.keys(rule).filter(key => commonFields.includes(key)).length;
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
return allKeys > commonKeys;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export default function getReducedFormatting(formatting, fields) {
|
|
20
|
-
|
|
20
|
+
const acceptedFields = [...commonFields, ...fields];
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
return formatting.map(rule => reduce(rule, acceptedFields)).filter(hasImpact);
|
|
23
23
|
}
|
|
@@ -7,7 +7,7 @@ function getHighlightColor(baseColor, isStrong) {
|
|
|
7
7
|
return baseColor + '33';
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export default function getRenderFormatting(formatting, hoveredCell, focusedCell, selection, highlight, edition, sortBy, resizableColumn, resizableRow, borderWidth) {
|
|
10
|
+
export default function getRenderFormatting(formatting, hoveredCell, focusedCell, selection, highlight, edition, sortBy, resizableColumn, resizableRow, borderWidth, isReordering, reorderedColumn, reorderedRow) {
|
|
11
11
|
const focusedColumnKey = focusedCell ? stringifyId(focusedCell.columnId) : null;
|
|
12
12
|
const focusedRowKey = focusedCell ? stringifyId(focusedCell.rowId) : null;
|
|
13
13
|
const isResizingColumn = resizableColumn !== null;
|
|
@@ -130,5 +130,15 @@ export default function getRenderFormatting(formatting, hoveredCell, focusedCell
|
|
|
130
130
|
row: { id: resizableRow },
|
|
131
131
|
style: { borderBottom: { width: resizableBorderWidth, color: 'cornflowerblue' } }
|
|
132
132
|
}),
|
|
133
|
+
...optional(isReordering && reorderedColumn, {
|
|
134
|
+
column: { id: reorderedColumn },
|
|
135
|
+
row: { type: 'ANY' },
|
|
136
|
+
style: { highlight: '#3a74e055' },
|
|
137
|
+
}),
|
|
138
|
+
...optional(isReordering && reorderedRow, {
|
|
139
|
+
column: { type: 'ANY' },
|
|
140
|
+
row: { id: reorderedRow },
|
|
141
|
+
style: { highlight: '#3a74e055' },
|
|
142
|
+
}),
|
|
133
143
|
];
|
|
134
144
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import stringifyId from "../core-utils/stringifyId.js";
|
|
2
|
+
|
|
3
|
+
function findMove(entries, focusedId, hoveredId) {
|
|
4
|
+
const focusedKey = stringifyId(focusedId);
|
|
5
|
+
const hoveredKey = stringifyId(hoveredId);
|
|
6
|
+
|
|
7
|
+
if (focusedKey === hoveredKey)
|
|
8
|
+
return null;
|
|
9
|
+
|
|
10
|
+
const focusedIndex = entries.findIndex(entry => entry.key === focusedKey);
|
|
11
|
+
const hoveredIndex = entries.findIndex(entry => entry.key === hoveredKey);
|
|
12
|
+
|
|
13
|
+
if (focusedIndex === -1)
|
|
14
|
+
return null;
|
|
15
|
+
if (hoveredIndex === -1)
|
|
16
|
+
return null;
|
|
17
|
+
if (focusedIndex === hoveredIndex)
|
|
18
|
+
return null;
|
|
19
|
+
|
|
20
|
+
return [focusedIndex, hoveredIndex];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getReorderedColumns(columns, columnId, hoveredCell, mousePosition) {
|
|
24
|
+
if (!hoveredCell)
|
|
25
|
+
return null;
|
|
26
|
+
|
|
27
|
+
const move = findMove(columns, columnId, hoveredCell.columnId);
|
|
28
|
+
|
|
29
|
+
if (!move)
|
|
30
|
+
return null;
|
|
31
|
+
|
|
32
|
+
const [from, to] = move;
|
|
33
|
+
const adjustedTo = to <= from
|
|
34
|
+
? (mousePosition.x < columns[to].leftWithBorder + columns[from].width ? to : to + 1)
|
|
35
|
+
: (mousePosition.x > columns[to].rightWithBorder - columns[from].width ? to : to - 1);
|
|
36
|
+
|
|
37
|
+
if (adjustedTo === from)
|
|
38
|
+
return null;
|
|
39
|
+
|
|
40
|
+
const reordered = columns.map(entry => entry.id);
|
|
41
|
+
reordered.splice(from, 1);
|
|
42
|
+
reordered.splice(adjustedTo, 0, columnId);
|
|
43
|
+
|
|
44
|
+
return reordered;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function getReorderedRows(rows, rowId, hoveredCell, mousePosition) {
|
|
48
|
+
if (!hoveredCell)
|
|
49
|
+
return null;
|
|
50
|
+
|
|
51
|
+
const move = findMove(rows, rowId, hoveredCell.rowId);
|
|
52
|
+
|
|
53
|
+
if (!move)
|
|
54
|
+
return null;
|
|
55
|
+
|
|
56
|
+
const [from, to] = move;
|
|
57
|
+
const adjustedTo = to <= from
|
|
58
|
+
? (mousePosition.y < rows[to].topWithBorder + rows[from].height ? to : to + 1)
|
|
59
|
+
: (mousePosition.y > rows[to].bottomWithBorder - rows[from].height ? to : to - 1);
|
|
60
|
+
|
|
61
|
+
if (adjustedTo === from)
|
|
62
|
+
return null;
|
|
63
|
+
|
|
64
|
+
const reordered = rows.map(entry => entry.id);
|
|
65
|
+
reordered.splice(from, 1);
|
|
66
|
+
reordered.splice(adjustedTo, 0, rowId);
|
|
67
|
+
|
|
68
|
+
return reordered;
|
|
69
|
+
}
|
|
@@ -5,9 +5,11 @@ const grabOffset = 5;
|
|
|
5
5
|
|
|
6
6
|
// TODO: not working when scrolled
|
|
7
7
|
|
|
8
|
-
export function getResizableColumn(columns, columnLookup, rowLookup, hoveredCell, element, mousePosition, fixedSize, totalSize) {
|
|
8
|
+
export function getResizableColumn(columns, columnLookup, rowLookup, hoveredCell, element, mousePosition, isReordering, fixedSize, totalSize) {
|
|
9
9
|
if (!hoveredCell)
|
|
10
10
|
return null;
|
|
11
|
+
if (isReordering)
|
|
12
|
+
return null;
|
|
11
13
|
|
|
12
14
|
const column = columnLookup.get(stringifyId(hoveredCell.columnId));
|
|
13
15
|
const row = rowLookup.get(stringifyId(hoveredCell.rowId));
|
|
@@ -31,9 +33,11 @@ export function getResizableColumn(columns, columnLookup, rowLookup, hoveredCell
|
|
|
31
33
|
return columns[column.index - 1].id;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
export function getResizableRow(rows, columnLookup, rowLookup, hoveredCell, element, mousePosition, fixedSize, totalSize) {
|
|
36
|
+
export function getResizableRow(rows, columnLookup, rowLookup, hoveredCell, element, mousePosition, isReordering, fixedSize, totalSize) {
|
|
35
37
|
if (!hoveredCell)
|
|
36
38
|
return null;
|
|
39
|
+
if (isReordering)
|
|
40
|
+
return null;
|
|
37
41
|
|
|
38
42
|
const column = columnLookup.get(stringifyId(hoveredCell.columnId));
|
|
39
43
|
const row = rowLookup.get(stringifyId(hoveredCell.rowId));
|
|
@@ -8,7 +8,6 @@ function getResolved(elements, pinnedBegin, pinnedEnd) {
|
|
|
8
8
|
...element,
|
|
9
9
|
id: id,
|
|
10
10
|
type: element.type || "DATA",
|
|
11
|
-
index: index,
|
|
12
11
|
key: stringifyId(id),
|
|
13
12
|
pinned: getPinned(index, elements.length, pinnedBegin, pinnedEnd),
|
|
14
13
|
header: 'header' in element ? element.header : id,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import stringifyId from "../core-utils/stringifyId.js";
|
|
2
|
+
|
|
3
|
+
export default function getTooltip(hoveredCell, formatResolver, columnLookup, rowLookup) {
|
|
4
|
+
if (!hoveredCell)
|
|
5
|
+
return null;
|
|
6
|
+
|
|
7
|
+
const columnKey = stringifyId(hoveredCell.columnId);
|
|
8
|
+
const rowKey = stringifyId(hoveredCell.rowId);
|
|
9
|
+
|
|
10
|
+
if (!columnLookup.has(columnKey))
|
|
11
|
+
return null;
|
|
12
|
+
if (!rowLookup.has(rowKey))
|
|
13
|
+
return null;
|
|
14
|
+
|
|
15
|
+
const row = rowLookup.get(rowKey);
|
|
16
|
+
const column = columnLookup.get(columnKey);
|
|
17
|
+
|
|
18
|
+
return formatResolver.resolve(row, column).tooltip;
|
|
19
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import getCellPlacement from "./getCellPlacement.js";
|
|
2
|
+
|
|
3
|
+
export default function getTooltipPlacement(tooltip, focusedCell, columnLookup, rowLookup, sections) {
|
|
4
|
+
if (!tooltip)
|
|
5
|
+
return null;
|
|
6
|
+
|
|
7
|
+
const cellPlacement = getCellPlacement(focusedCell, columnLookup, rowLookup, sections);
|
|
8
|
+
|
|
9
|
+
if (!cellPlacement)
|
|
10
|
+
return null;
|
|
11
|
+
|
|
12
|
+
return {
|
|
13
|
+
top: cellPlacement.top,
|
|
14
|
+
left: cellPlacement.left
|
|
15
|
+
};
|
|
16
|
+
}
|
|
@@ -53,6 +53,7 @@ export default class FormattingRules {
|
|
|
53
53
|
for (const [index, rule] of rules.entries()) {
|
|
54
54
|
const entry = { index };
|
|
55
55
|
|
|
56
|
+
// TODO: Mark which rules are actually present and only check those in resolve
|
|
56
57
|
if ('condition' in rule)
|
|
57
58
|
entry.condition = rule.condition;
|
|
58
59
|
if ('style' in rule)
|
|
@@ -67,6 +68,8 @@ export default class FormattingRules {
|
|
|
67
68
|
entry.padding = typeof rule.padding === 'function' ? rule.padding : () => rule.padding;
|
|
68
69
|
if ('edit' in rule)
|
|
69
70
|
entry.edit = rule.edit;
|
|
71
|
+
if ('tooltip' in rule)
|
|
72
|
+
entry.tooltip = typeof rule.tooltip === 'function' ? rule.tooltip : () => rule.tooltip;
|
|
70
73
|
if ('draw' in rule)
|
|
71
74
|
entry.draw = rule.draw;
|
|
72
75
|
|
|
@@ -86,6 +89,7 @@ export default class FormattingRules {
|
|
|
86
89
|
let visible = true;
|
|
87
90
|
let padding = defaultPadding;
|
|
88
91
|
let font = defaultFont;
|
|
92
|
+
let tooltip = undefined;
|
|
89
93
|
|
|
90
94
|
if (edition.hasValueByKey(row.key, column.key))
|
|
91
95
|
context = { ...context, newValue: edition.getValueByKey(row.key, column.key) };
|
|
@@ -107,6 +111,8 @@ export default class FormattingRules {
|
|
|
107
111
|
padding = { ...padding, ...rule.padding(context) };
|
|
108
112
|
if ('edit' in rule)
|
|
109
113
|
context = { ...context, edit: getEdit(rule, context) };
|
|
114
|
+
if ('tooltip' in rule)
|
|
115
|
+
tooltip = rule.tooltip(context);
|
|
110
116
|
if ('draw' in rule) {
|
|
111
117
|
const currentContext = context;
|
|
112
118
|
draw = (ctx) => rule.draw({ ...currentContext, ctx });
|
|
@@ -128,6 +134,8 @@ export default class FormattingRules {
|
|
|
128
134
|
result.value = context.value;
|
|
129
135
|
if ('edit' in context && context.edit !== undefined)
|
|
130
136
|
result.edit = context.edit;
|
|
137
|
+
if (tooltip !== undefined)
|
|
138
|
+
result.tooltip = tooltip;
|
|
131
139
|
if (draw !== undefined)
|
|
132
140
|
result.draw = draw;
|
|
133
141
|
|