table-minimap 1.1.1 → 1.1.3

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/README.md CHANGED
@@ -101,15 +101,17 @@ For a smaller, hideable floating minimap, enable `compact` together with `positi
101
101
  const minimap = new TableMinimap('#my-table', {
102
102
  position: 'fixed',
103
103
  fixedWidth: 260,
104
+ fixedPosition: 'bottom-right',
104
105
  compact: true,
105
106
  height: 44,
106
107
  });
107
108
  ```
108
109
 
109
110
  - Collapses into a small translucent dot in the bottom-right corner
110
- - Expands on hover or keyboard focus
111
+ - Expands on click or keyboard focus
111
112
  - Remains clickable when collapsed
112
113
  - Uses a short ease-in-out transition for width/height/opacity
114
+ - Double-click fixed minimaps to move them to the next corner
113
115
 
114
116
  ### Canvas Mode (VS Code-like)
115
117
 
@@ -192,6 +194,7 @@ interface TableMinimapOptions {
192
194
 
193
195
  /**
194
196
  * Corner position when using position: 'fixed'
197
+ * Double-click fixed minimaps to cycle to the next corner.
195
198
  * @default "bottom-right"
196
199
  */
197
200
  fixedPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
package/dist/index.d.ts CHANGED
@@ -82,6 +82,8 @@ export declare class TableMinimap {
82
82
  private isCompactExpanding;
83
83
  /** Timeout used to collapse compact mode after pointer leave */
84
84
  private compactCollapseTimer;
85
+ /** Timeout used to delay fixed minimap click navigation until double-click is ruled out */
86
+ private minimapClickTimer;
85
87
  /** The scrollable container (parent of table) */
86
88
  private scrollContainer;
87
89
  /** Main minimap container element */
@@ -108,6 +110,8 @@ export declare class TableMinimap {
108
110
  private wasPanning;
109
111
  /** Pan start position */
110
112
  private panStartX;
113
+ /** Last pointer X waiting to be applied during canvas panning */
114
+ private pendingPanClientX;
111
115
  /** Currently hovered column index (-1 = none) */
112
116
  private hoveredColumn;
113
117
  /** Drag start X position */
@@ -122,6 +126,8 @@ export declare class TableMinimap {
122
126
  private boundHandlers;
123
127
  /** Animation frame ID for throttling */
124
128
  private rafId;
129
+ /** Animation frame ID for throttling canvas panning */
130
+ private canvasPanRafId;
125
131
  /** Whether the instance has been destroyed */
126
132
  private isDestroyed;
127
133
  /**
@@ -174,6 +180,14 @@ export declare class TableMinimap {
174
180
  * Inserts the minimap into the DOM
175
181
  */
176
182
  private insertMinimap;
183
+ /**
184
+ * Applies the configured fixed corner position to the minimap element.
185
+ */
186
+ private applyFixedPosition;
187
+ /**
188
+ * Moves fixed minimaps to the next configured corner.
189
+ */
190
+ private cycleFixedPosition;
177
191
  /**
178
192
  * Updates the scroll state from the container
179
193
  */
@@ -217,6 +231,22 @@ export declare class TableMinimap {
217
231
  * @param e - Mouse event
218
232
  */
219
233
  private onMinimapClick;
234
+ /**
235
+ * Handles double-click on fixed minimaps to move them to the next corner.
236
+ *
237
+ * @param e - Mouse event
238
+ */
239
+ private onMinimapDoubleClick;
240
+ /**
241
+ * Clears a pending delayed minimap click.
242
+ */
243
+ private clearMinimapClickTimer;
244
+ /**
245
+ * Handles single-click minimap navigation.
246
+ *
247
+ * @param clientX - Click position in viewport coordinates
248
+ */
249
+ private handleMinimapClick;
220
250
  /**
221
251
  * Handles pointer down on viewport for drag start
222
252
  *
@@ -229,6 +259,18 @@ export declare class TableMinimap {
229
259
  * @param e - Pointer event
230
260
  */
231
261
  private onPointerMove;
262
+ /**
263
+ * Schedules canvas panning work for the next animation frame.
264
+ */
265
+ private scheduleCanvasPan;
266
+ /**
267
+ * Applies pending canvas pan movement using a dampened scroll ratio.
268
+ */
269
+ private applyCanvasPan;
270
+ /**
271
+ * Cancels any pending canvas pan frame.
272
+ */
273
+ private clearCanvasPanFrame;
232
274
  /**
233
275
  * Handles pointer up to end drag
234
276
  *
@@ -388,6 +430,7 @@ export declare interface TableMinimapOptions {
388
430
  fixedWidth?: number;
389
431
  /**
390
432
  * Corner position when using position: 'fixed'
433
+ * Double-click fixed minimaps to cycle to the next corner.
391
434
  * @default "bottom-right"
392
435
  */
393
436
  fixedPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
@@ -1,2 +1,2 @@
1
- "use strict";var z=Object.defineProperty;var H=(v,t,e)=>t in v?z(v,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):v[t]=e;var n=(v,t,e)=>H(v,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A={mode:"columns",height:40,position:"bottom",fixedWidth:300,fixedPosition:"bottom-right",compact:!1,draggable:!0,showViewport:!0,zoomable:!1,minZoom:1,maxZoom:10,zoomSpeed:.1},T=24,O=5,I=180;class Z{constructor(t,e={}){n(this,"table");n(this,"options");n(this,"isCompactMode");n(this,"isCompactCollapsed",!1);n(this,"isCompactExpanding",!1);n(this,"compactCollapseTimer",null);n(this,"scrollContainer",null);n(this,"minimapEl",null);n(this,"columnsEl",null);n(this,"canvasEl",null);n(this,"canvasCtx",null);n(this,"viewportEl",null);n(this,"columns",[]);n(this,"scrollState",{scrollLeft:0,scrollWidth:0,clientWidth:0,viewportRatio:1,positionRatio:0});n(this,"zoomState",{level:1,panX:0,isMinZoom:!0,isMaxZoom:!1});n(this,"isDragging",!1);n(this,"isPanning",!1);n(this,"wasPanning",!1);n(this,"panStartX",0);n(this,"hoveredColumn",-1);n(this,"dragStartX",0);n(this,"dragStartScrollLeft",0);n(this,"resizeObserver",null);n(this,"mutationObserver",null);n(this,"boundHandlers");n(this,"rafId",null);n(this,"isDestroyed",!1);n(this,"isPotentialPan",!1);this.table=this.resolveTable(t),this.options={...A,...e},this.isCompactMode=this.options.compact&&this.options.position==="fixed",this.boundHandlers={onScroll:this.onScroll.bind(this),onPointerDown:this.onPointerDown.bind(this),onPointerMove:this.onPointerMove.bind(this),onPointerUp:this.onPointerUp.bind(this),onMinimapClick:this.onMinimapClick.bind(this),onWheel:this.onWheel.bind(this),onCanvasPointerDown:this.onCanvasPointerDown.bind(this),onCanvasMouseMove:this.onCanvasMouseMove.bind(this),onCanvasMouseLeave:this.onCanvasMouseLeave.bind(this),onCompactFocusIn:this.onCompactFocusIn.bind(this),onCompactFocusOut:this.onCompactFocusOut.bind(this),onCompactKeyDown:this.onCompactKeyDown.bind(this),onDocumentClick:this.onDocumentClick.bind(this)},this.init()}resolveTable(t){let e;if(typeof t=="string"){if(e=document.querySelector(t),!e)throw new Error(`TableMinimap: No element found for selector "${t}"`)}else if(t instanceof HTMLTableElement)e=t;else throw new Error("TableMinimap: Selector must be a CSS selector string or an HTMLTableElement");if(e.tagName!=="TABLE")throw new Error(`TableMinimap: Element must be a <table>, got <${e.tagName.toLowerCase()}>`);return e}init(){this.scrollContainer=this.findScrollContainer(),this.detectColumns(),this.createMinimapElement(),this.updateScrollState(),this.render(),this.attachEventListeners(),this.setupObservers()}findScrollContainer(){let t=this.table.parentElement;for(;t;){const e=getComputedStyle(t),i=e.overflowX,o=e.overflow;if(i==="auto"||i==="scroll"||o==="auto"||o==="scroll"||t.scrollWidth>t.clientWidth)return t;t=t.parentElement}return this.table.parentElement||document.body}detectColumns(){this.columns=[];const t=this.table.querySelectorAll("thead th, thead td");let e;if(t.length>0)e=t;else{const o=this.table.querySelector("tr");o?e=o.querySelectorAll("th, td"):e=[]}const i=this.table.offsetWidth||1;Array.from(e).forEach(o=>{const a=o.colSpan||1,s=o.offsetWidth;for(let r=0;r<a;r++){const l=s/a;this.columns.push({index:this.columns.length,width:l,widthPercent:l/i*100})}}),this.columns.length===0&&this.columns.push({index:0,width:i,widthPercent:100})}createMinimapElement(){this.minimapEl=document.createElement("div"),this.minimapEl.className=`tm-minimap tm-minimap--${this.options.position}`,this.minimapEl.style.setProperty("--tm-minimap-height",`${this.options.height}px`),this.options.position==="fixed"&&(this.minimapEl.style.setProperty("--tm-minimap-width",`${this.options.fixedWidth}px`),this.minimapEl.classList.add(`tm-minimap--${this.options.fixedPosition}`)),this.isCompactMode?(this.minimapEl.classList.add("tm-minimap--compact","tm-minimap--compact-collapsed"),this.minimapEl.style.setProperty("--tm-compact-dot-size",`${O}px`),this.isCompactCollapsed=!0,this.applyCompactDimensions(!0),this.minimapEl.setAttribute("aria-expanded","false")):this.minimapEl.setAttribute("aria-expanded","true"),this.minimapEl.setAttribute("role","slider"),this.minimapEl.setAttribute("aria-label","Table minimap navigation"),this.minimapEl.setAttribute("aria-valuemin","0"),this.minimapEl.setAttribute("aria-valuemax","100"),this.minimapEl.setAttribute("tabindex","0"),this.options.mode==="canvas"?this.createCanvasContent():this.createColumnsContent(),this.options.showViewport&&this.createViewportIndicator(),this.insertMinimap()}createColumnsContent(){this.minimapEl&&(this.columnsEl=document.createElement("div"),this.columnsEl.className="tm-columns",this.columns.forEach(()=>{const t=document.createElement("div");t.className="tm-column",this.columnsEl.appendChild(t)}),this.minimapEl.appendChild(this.columnsEl))}createCanvasContent(){this.minimapEl&&(this.canvasEl=document.createElement("canvas"),this.canvasEl.className="tm-canvas",this.canvasCtx=this.canvasEl.getContext("2d"),this.minimapEl.appendChild(this.canvasEl))}createViewportIndicator(){this.minimapEl&&(this.viewportEl=document.createElement("div"),this.viewportEl.className="tm-viewport",this.options.draggable||this.viewportEl.classList.add("tm-viewport--disabled"),this.minimapEl.appendChild(this.viewportEl))}insertMinimap(){if(!this.minimapEl||!this.scrollContainer)return;const t=this.scrollContainer.parentElement;if(this.options.position==="fixed"){if(t){getComputedStyle(t).position==="static"&&(t.style.position="relative");const i=this.scrollContainer.nextSibling;i?t.insertBefore(this.minimapEl,i):t.appendChild(this.minimapEl),this.minimapEl.style.position="absolute";const o=this.isCompactMode?8:12,a=this.options.fixedPosition;this.minimapEl.style.top="",this.minimapEl.style.bottom="",this.minimapEl.style.left="",this.minimapEl.style.right="",this.minimapEl.style.marginTop="0",a==="top-left"?(this.minimapEl.style.top=`${o}px`,this.minimapEl.style.left=`${o}px`):a==="top-right"?(this.minimapEl.style.top=`${o}px`,this.minimapEl.style.right=`${o}px`):a==="bottom-left"?(this.minimapEl.style.bottom=`${o}px`,this.minimapEl.style.left=`${o}px`):(this.minimapEl.style.bottom=`${o}px`,this.minimapEl.style.right=`${o}px`)}}else if(this.options.position==="top")t?t.insertBefore(this.minimapEl,this.scrollContainer):this.scrollContainer.insertBefore(this.minimapEl,this.scrollContainer.firstChild);else if(t){const e=this.scrollContainer.nextSibling;e?t.insertBefore(this.minimapEl,e):t.appendChild(this.minimapEl)}else this.scrollContainer.appendChild(this.minimapEl)}updateScrollState(){if(!this.scrollContainer)return;const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer;this.scrollState={scrollLeft:t,scrollWidth:e,clientWidth:i,viewportRatio:i/Math.max(e,1),positionRatio:t/Math.max(e-i,1)},this.scrollState.viewportRatio=Math.min(1,Math.max(0,this.scrollState.viewportRatio)),this.scrollState.positionRatio=Math.min(1,Math.max(0,this.scrollState.positionRatio)),this.minimapEl&&this.minimapEl.setAttribute("aria-valuenow",String(Math.round(this.scrollState.positionRatio*100)))}render(){this.isDestroyed||this.isCompactMode&&this.isCompactCollapsed||(this.updateViewport(),this.options.mode==="canvas"&&this.renderCanvas())}getCanvasMetrics(){var p;const t=((p=this.minimapEl)==null?void 0:p.offsetWidth)??0,e=this.zoomState.level,i=this.columns.length,o=1/e,a=i*o,s=a>0?t/a:0;let r=0;if(e>1&&this.scrollContainer){const{scrollLeft:m,scrollWidth:E,clientWidth:g}=this.scrollContainer,u=Math.max(E-g,1);r=m/u*(1-o)}const l=r*i,c=Math.floor(l),h=Math.min(Math.ceil(l+a)+1,i),f=-(l-c)*s;return{width:t,zoom:e,numCols:i,visibleRatio:o,visibleCols:a,cellWidth:s,panX:r,startColFloat:l,startCol:c,endCol:h,xOffset:f}}getColumnAtX(t){const{width:e,numCols:i,panX:o,visibleRatio:a}=this.getCanvasMetrics();if(i===0||e===0)return-1;const s=t/e,r=o+s*a,l=Math.floor(r*i);return Math.max(0,Math.min(i-1,l))}updateViewport(){if(!this.viewportEl||!this.minimapEl)return;if(this.options.mode==="canvas"){this.viewportEl.style.display="none";return}const t=this.minimapEl.offsetWidth,e=Math.max(t*this.scrollState.viewportRatio,20),o=(t-e)*this.scrollState.positionRatio;this.viewportEl.style.cssText=`width:${e}px;left:${o}px;display:block`}renderCanvas(){if(!this.canvasEl||!this.canvasCtx||!this.minimapEl)return;const t=this.getCanvasMetrics(),e=this.options.height,i=window.devicePixelRatio||1;this.canvasEl.width=t.width*i,this.canvasEl.height=e*i,this.canvasEl.style.width=`${t.width}px`,this.canvasEl.style.height=`${e}px`,this.canvasCtx.scale(i,i),this.renderTableDirect(t,e)}renderTableDirect(t,e){var S,y,P,k;if(!this.canvasCtx)return;const i=this.canvasCtx,{width:o,numCols:a,cellWidth:s,startCol:r,endCol:l,xOffset:c}=t,h=Array.from(this.table.querySelectorAll("tr")),f=h.length;if(f===0||a===0)return;const p=Math.min(e*.15,30),m=(e-p)/f,E=Math.min(m*.6,s*.15,14),g=Math.min(p*.6,s*.15,14),u={bg:"#ffffff",headerBg:"#f1f5f9",border:"#e2e8f0",text:"#334155",headerText:"#1e293b",altRow:"#f8fafc",hoverFill:"rgba(59, 130, 246, 0.08)",hoverStroke:"rgba(59, 130, 246, 0.3)"};i.fillStyle=u.bg,i.fillRect(0,0,o,e),i.fillStyle=u.headerBg,i.fillRect(0,0,o,p);const x=this.table.querySelector("thead tr")||h[0],L=x?Array.from(x.querySelectorAll("th, td")):[];i.font=`bold ${g}px system-ui, sans-serif`,i.textBaseline="middle";for(let d=r;d<l;d++){const b=c+(d-r)*s;if(b+s<0||b>o)continue;i.strokeStyle=u.border,i.lineWidth=1,i.strokeRect(b,0,s,p);const C=((y=(S=L[d])==null?void 0:S.textContent)==null?void 0:y.trim())||`Col ${d+1}`;i.fillStyle=u.headerText,i.save(),i.beginPath(),i.rect(b+2,0,s-4,p),i.clip(),i.fillText(C,b+4,p/2),i.restore()}i.font=`${E}px system-ui, sans-serif`;for(let d=0;d<h.length;d++){const b=h[d];if(b.closest("thead"))continue;const C=p+d*m;if(C+m<0||C>e)continue;d%2===1&&(i.fillStyle=u.altRow,i.fillRect(0,C,o,m));const X=Array.from(b.querySelectorAll("th, td"));for(let M=r;M<l;M++){const w=c+(M-r)*s;if(w+s<0||w>o)continue;i.strokeStyle=u.border,i.lineWidth=.5,i.strokeRect(w,C,s,m);const D=(k=(P=X[M])==null?void 0:P.textContent)==null?void 0:k.trim();D&&(i.fillStyle=u.text,i.save(),i.beginPath(),i.rect(w+2,C,s-4,m),i.clip(),i.fillText(D,w+4,C+m/2),i.restore())}}if(this.hoveredColumn>=r&&this.hoveredColumn<l){const d=c+(this.hoveredColumn-r)*s;i.fillStyle=u.hoverFill,i.fillRect(d,0,s,e),i.strokeStyle=u.hoverStroke,i.lineWidth=1,i.strokeRect(d,0,s,e)}}attachEventListeners(){!this.scrollContainer||!this.minimapEl||(this.scrollContainer.addEventListener("scroll",this.boundHandlers.onScroll,{passive:!0}),this.minimapEl.addEventListener("click",this.boundHandlers.onMinimapClick),this.isCompactMode&&(this.minimapEl.addEventListener("focusin",this.boundHandlers.onCompactFocusIn),this.minimapEl.addEventListener("focusout",this.boundHandlers.onCompactFocusOut),this.minimapEl.addEventListener("keydown",this.boundHandlers.onCompactKeyDown),document.addEventListener("click",this.boundHandlers.onDocumentClick)),this.options.draggable&&this.viewportEl&&this.viewportEl.addEventListener("pointerdown",this.boundHandlers.onPointerDown),this.options.zoomable&&this.options.mode==="canvas"&&this.canvasEl&&(this.canvasEl.addEventListener("wheel",this.boundHandlers.onWheel,{passive:!1}),this.canvasEl.addEventListener("pointerdown",this.boundHandlers.onCanvasPointerDown),this.canvasEl.style.cursor=this.zoomState.level>1?"grab":"pointer",this.viewportEl&&this.viewportEl.addEventListener("wheel",this.boundHandlers.onWheel,{passive:!1})),this.options.mode==="canvas"&&this.canvasEl&&(this.canvasEl.addEventListener("mousemove",this.boundHandlers.onCanvasMouseMove),this.canvasEl.addEventListener("mouseleave",this.boundHandlers.onCanvasMouseLeave)),document.addEventListener("pointermove",this.boundHandlers.onPointerMove),document.addEventListener("pointerup",this.boundHandlers.onPointerUp))}onScroll(){this.isDragging||this.rafId===null&&(this.rafId=requestAnimationFrame(()=>{this.updateScrollState(),this.updateViewport(),this.options.mode==="canvas"&&this.render(),this.rafId=null}))}onMinimapClick(t){if(!this.minimapEl||!this.scrollContainer)return;if(this.isCompactMode&&this.isCompactCollapsed){t.preventDefault(),this.expandCompact();return}if(this.isCompactExpanding||this.isDragging||this.isPanning||this.wasPanning)return;const{scrollWidth:e,clientWidth:i}=this.scrollContainer,o=e-i,a=this.minimapEl.getBoundingClientRect(),s=t.clientX-a.left;if(this.options.mode==="canvas"){const c=this.getColumnAtX(s);if(c>=0){const h=this.columns.length,f=e/h,m=(c+.5)*f-i/2;this.scrollContainer.scrollTo({left:Math.max(0,Math.min(o,m)),behavior:"smooth"})}return}const l=s/a.width*o;this.scrollContainer.scrollTo({left:Math.max(0,Math.min(o,l)),behavior:"smooth"})}onPointerDown(t){!this.viewportEl||!this.scrollContainer||(t.preventDefault(),t.stopPropagation(),this.isDragging=!0,this.dragStartX=t.clientX,this.dragStartScrollLeft=this.scrollContainer.scrollLeft,this.viewportEl.classList.add("tm-viewport--dragging"),this.viewportEl.setPointerCapture(t.pointerId))}onPointerMove(t){if(this.isPotentialPan&&!this.isPanning&&this.canvasEl&&this.zoomState.level>1&&Math.abs(t.clientX-this.panStartX)>3&&(this.isPanning=!0,this.canvasEl.style.cursor="grabbing"),this.isPanning&&this.canvasEl&&this.minimapEl&&this.scrollContainer){t.preventDefault();const c=t.clientX-this.panStartX,h=this.minimapEl.offsetWidth,{scrollWidth:f,clientWidth:p}=this.scrollContainer,m=f-p,E=c/h*m*this.zoomState.level,g=this.dragStartScrollLeft+E;this.scrollContainer.scrollLeft=Math.max(0,Math.min(m,g)),this.updateScrollState(),this.updateViewport(),this.render();return}if(!this.isDragging||!this.minimapEl||!this.scrollContainer)return;t.preventDefault();const{scrollWidth:e,clientWidth:i}=this.scrollContainer,o=this.minimapEl.offsetWidth,a=e-i,r=(t.clientX-this.dragStartX)/o*a,l=this.dragStartScrollLeft+r;this.scrollContainer.scrollLeft=Math.max(0,Math.min(a,l)),this.updateScrollState(),this.updateViewport()}onPointerUp(t){if(this.isPotentialPan&&!this.isPanning&&this.canvasEl&&this.minimapEl){this.isPotentialPan=!1,this.canvasEl.hasPointerCapture(t.pointerId)&&this.canvasEl.releasePointerCapture(t.pointerId);const e=new MouseEvent("click",{clientX:t.clientX,clientY:t.clientY,bubbles:!0});this.minimapEl.dispatchEvent(e);return}this.isPotentialPan=!1,this.isPanning&&this.canvasEl&&(this.isPanning=!1,this.wasPanning=!0,this.canvasEl.hasPointerCapture(t.pointerId)&&this.canvasEl.releasePointerCapture(t.pointerId),this.canvasEl.style.cursor=this.zoomState.level>1?"grab":"pointer",setTimeout(()=>{this.wasPanning=!1},100)),this.isDragging&&(this.isDragging=!1,this.viewportEl&&(this.viewportEl.classList.remove("tm-viewport--dragging"),this.viewportEl.releasePointerCapture(t.pointerId)))}onWheel(t){if(!this.options.zoomable||this.options.mode!=="canvas"||!this.canvasEl||!this.scrollContainer||!this.minimapEl)return;t.preventDefault();const e=this.zoomState.level,i=-t.deltaY*this.options.zoomSpeed,o=Math.max(this.options.minZoom,Math.min(this.options.maxZoom,e+i));if(o===e)return;const a=this.canvasEl.getBoundingClientRect(),s=t.clientX-a.left,r=this.minimapEl.offsetWidth,l=s/r,c=1/e,{scrollLeft:h,scrollWidth:f,clientWidth:p}=this.scrollContainer,m=Math.max(f-p,1),E=h/m,u=(e>1?E*(1-c):0)+l*c;this.zoomState={level:o,panX:0,isMinZoom:o<=this.options.minZoom,isMaxZoom:o>=this.options.maxZoom};const x=1/o;if(o>1){const S=(u-l*x)/(1-x),y=Math.max(0,Math.min(m,S*m));this.scrollContainer.scrollLeft=y}this.updateScrollState(),this.render()}onCanvasPointerDown(t){!this.canvasEl||!this.scrollContainer||(this.isPotentialPan=!0,this.panStartX=t.clientX,this.dragStartScrollLeft=this.scrollContainer.scrollLeft,this.zoomState.level>1&&(t.preventDefault(),this.canvasEl.setPointerCapture(t.pointerId)))}onCanvasMouseMove(t){if(!this.canvasEl||this.isPanning)return;const e=this.canvasEl.getBoundingClientRect(),i=this.getColumnAtX(t.clientX-e.left);i!==this.hoveredColumn&&(this.hoveredColumn=i,this.canvasEl.style.cursor=i>=0?"pointer":this.zoomState.level>1?"grab":"default",this.render())}onCanvasMouseLeave(){this.hoveredColumn!==-1&&(this.hoveredColumn=-1,this.canvasEl&&(this.canvasEl.style.cursor=this.zoomState.level>1?"grab":"default"),this.render())}expandCompact(){!this.isCompactMode||!this.minimapEl||this.isCompactExpanding||(this.clearCompactCollapseTimer(),this.isCompactExpanding=!0,this.applyCompactDimensions(!1),setTimeout(()=>{this.isCompactExpanding=!1,!this.isDestroyed&&!this.isCompactCollapsed&&(this.updateScrollState(),this.render())},200))}collapseCompact(){!this.isCompactMode||!this.minimapEl||this.applyCompactDimensions(!0)}applyCompactDimensions(t){if(!(!this.minimapEl||!this.isCompactMode)){if(this.isCompactCollapsed=t,t){this.minimapEl.classList.add("tm-minimap--compact-collapsed"),this.minimapEl.classList.remove("tm-minimap--compact-expanded"),this.minimapEl.style.setProperty("--tm-minimap-width",`${T}px`),this.minimapEl.style.setProperty("--tm-minimap-height",`${T}px`),this.minimapEl.setAttribute("aria-expanded","false");return}this.minimapEl.classList.remove("tm-minimap--compact-collapsed"),this.minimapEl.classList.add("tm-minimap--compact-expanded"),this.minimapEl.style.setProperty("--tm-minimap-width",`${this.options.fixedWidth}px`),this.minimapEl.style.setProperty("--tm-minimap-height",`${this.options.height}px`),this.minimapEl.setAttribute("aria-expanded","true")}}clearCompactCollapseTimer(){this.compactCollapseTimer!==null&&(clearTimeout(this.compactCollapseTimer),this.compactCollapseTimer=null)}scheduleCompactCollapse(t=I){this.isCompactMode&&(this.clearCompactCollapseTimer(),this.compactCollapseTimer=window.setTimeout(()=>{this.collapseCompact(),this.compactCollapseTimer=null},t))}onDocumentClick(t){!this.isCompactMode||!this.minimapEl||this.isCompactCollapsed||this.minimapEl.contains(t.target)||this.collapseCompact()}onCompactFocusIn(){this.isCompactMode&&this.expandCompact()}onCompactFocusOut(){this.isCompactMode&&this.scheduleCompactCollapse(0)}onCompactKeyDown(t){if(this.isCompactMode){if(t.key==="Escape"){t.preventDefault(),this.collapseCompact();return}(t.key==="Enter"||t.key===" ")&&(t.preventDefault(),this.isCompactCollapsed?this.expandCompact():this.collapseCompact())}}setupObservers(){this.resizeObserver=new ResizeObserver(()=>{this.onResize()}),this.scrollContainer&&this.resizeObserver.observe(this.scrollContainer),this.resizeObserver.observe(this.table),this.mutationObserver=new MutationObserver(t=>{t.some(i=>i.type==="childList"||i.attributeName==="colspan")&&this.onTableMutation()}),this.mutationObserver.observe(this.table,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["colspan"]})}onResize(){this.isDestroyed||(this.rafId!==null&&cancelAnimationFrame(this.rafId),this.rafId=requestAnimationFrame(()=>{this.detectColumns(),this.updateScrollState(),this.render(),this.options.mode==="columns"&&this.columnsEl&&this.minimapEl&&(this.columnsEl.innerHTML="",this.columns.forEach(()=>{const t=document.createElement("div");t.className="tm-column",this.columnsEl.appendChild(t)})),this.rafId=null}))}onTableMutation(){this.isDestroyed||(this.detectColumns(),this.updateScrollState(),this.render(),this.options.mode==="columns"&&this.columnsEl&&(this.columnsEl.innerHTML="",this.columns.forEach(()=>{const t=document.createElement("div");t.className="tm-column",this.columnsEl.appendChild(t)})))}getScrollState(){return{...this.scrollState}}getColumns(){return[...this.columns]}scrollToColumn(t,e=!0){if(!this.scrollContainer||t<0||t>=this.columns.length)return;const o=this.columns.slice(0,t).reduce((a,s)=>a+s.width,0);this.scrollContainer.scrollTo({left:o,behavior:e?"smooth":"auto"})}refresh(){this.isDestroyed||(this.scrollContainer=this.findScrollContainer(),this.detectColumns(),this.updateScrollState(),this.render(),this.options.mode==="columns"&&this.columnsEl&&(this.columnsEl.innerHTML="",this.columns.forEach(()=>{const t=document.createElement("div");t.className="tm-column",this.columnsEl.appendChild(t)})))}getZoomState(){return{...this.zoomState}}setZoom(t,e){if(this.isDestroyed||this.options.mode!=="canvas"||!this.scrollContainer)return;const i=Math.max(this.options.minZoom,Math.min(this.options.maxZoom,t)),o=1/i,a=1-o;let s=e!==void 0?e:0;if(s=Math.max(0,Math.min(a,s)),this.zoomState={level:i,panX:0,isMinZoom:i<=this.options.minZoom,isMaxZoom:i>=this.options.maxZoom},i>1&&s>0){const{scrollWidth:r,clientWidth:l}=this.scrollContainer,c=Math.max(r-l,1),h=s/(1-o);this.scrollContainer.scrollLeft=Math.max(0,Math.min(c,h*c))}else i<=1&&(this.scrollContainer.scrollLeft=0);this.updateScrollState(),this.render()}resetZoom(){this.setZoom(1,0)}zoomToColumns(t,e){if(this.isDestroyed||this.options.mode!=="canvas")return;const i=this.columns.length;if(i===0)return;const o=Math.max(0,Math.min(i-1,t)),s=Math.max(o+1,Math.min(i,e))-o,r=i/s,l=o/i;this.setZoom(r,l)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.clearCompactCollapseTimer(),this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.scrollContainer&&this.scrollContainer.removeEventListener("scroll",this.boundHandlers.onScroll),this.minimapEl&&(this.minimapEl.removeEventListener("click",this.boundHandlers.onMinimapClick),this.minimapEl.removeEventListener("focusin",this.boundHandlers.onCompactFocusIn),this.minimapEl.removeEventListener("focusout",this.boundHandlers.onCompactFocusOut),this.minimapEl.removeEventListener("keydown",this.boundHandlers.onCompactKeyDown)),document.removeEventListener("click",this.boundHandlers.onDocumentClick),this.viewportEl&&(this.viewportEl.removeEventListener("pointerdown",this.boundHandlers.onPointerDown),this.viewportEl.removeEventListener("wheel",this.boundHandlers.onWheel)),this.canvasEl&&(this.canvasEl.removeEventListener("wheel",this.boundHandlers.onWheel),this.canvasEl.removeEventListener("pointerdown",this.boundHandlers.onCanvasPointerDown),this.canvasEl.removeEventListener("mousemove",this.boundHandlers.onCanvasMouseMove),this.canvasEl.removeEventListener("mouseleave",this.boundHandlers.onCanvasMouseLeave)),document.removeEventListener("pointermove",this.boundHandlers.onPointerMove),document.removeEventListener("pointerup",this.boundHandlers.onPointerUp),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.minimapEl&&this.minimapEl.parentNode&&this.minimapEl.parentNode.removeChild(this.minimapEl),this.minimapEl=null,this.columnsEl=null,this.canvasEl=null,this.canvasCtx=null,this.viewportEl=null,this.scrollContainer=null,this.columns=[])}}const $=':root{--tm-background: #e3f2fd;--tm-border: #90caf9;--tm-viewport-color: rgba(25, 118, 210, .3);--tm-viewport-border: #1976d2;--tm-height: 40px;--tm-column-color: #64b5f6;--tm-column-gap: 1px;--tm-border-radius: 4px;--tm-canvas-empty: #bbdefb;--tm-canvas-filled: #1565c0;--tm-compact-dot-size: 5px;--tm-compact-transition-duration: .18s}@media (prefers-color-scheme: dark){:root{--tm-background: #1a237e;--tm-border: #3949ab;--tm-viewport-color: rgba(100, 180, 255, .3);--tm-viewport-border: #64b5f6;--tm-column-color: #3f51b5;--tm-canvas-empty: #283593;--tm-canvas-filled: #90caf9}}.tm-minimap{position:relative;width:var(--tm-minimap-width, 100%);height:var(--tm-minimap-height, var(--tm-height));background:var(--tm-background);border:1px solid var(--tm-border);border-radius:var(--tm-border-radius);box-sizing:border-box;overflow:hidden;user-select:none;-webkit-user-select:none;cursor:pointer;transition:width var(--tm-compact-transition-duration) ease-in-out,height var(--tm-compact-transition-duration) ease-in-out,opacity var(--tm-compact-transition-duration) ease-in-out,transform var(--tm-compact-transition-duration) ease-in-out,background-color var(--tm-compact-transition-duration) ease-in-out,border-color var(--tm-compact-transition-duration) ease-in-out,box-shadow var(--tm-compact-transition-duration) ease-in-out;will-change:width,height,opacity,transform}.tm-minimap--top{margin-bottom:8px}.tm-minimap--bottom{margin-top:8px}.tm-minimap--fixed{z-index:100;background:color-mix(in srgb,var(--tm-background) 72%,transparent);border-color:color-mix(in srgb,var(--tm-border) 72%,transparent);box-shadow:0 4px 12px #00000026;border-radius:8px;opacity:.78;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.tm-minimap--fixed:hover,.tm-minimap--fixed:focus-within{opacity:.96}.tm-minimap--compact-collapsed{border-radius:999px}.tm-minimap--compact-expanded{border-radius:8px}.tm-minimap--compact>*{transition:opacity var(--tm-compact-transition-duration) ease-in-out}.tm-minimap--compact-collapsed{background:color-mix(in srgb,var(--tm-background) 60%,transparent);border-color:color-mix(in srgb,var(--tm-border) 45%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--tm-border) 20%,transparent);opacity:.72;transform:translate(2px,2px)}.tm-minimap--compact-collapsed>*{opacity:0;pointer-events:none}.tm-minimap--compact-collapsed:after{content:"";position:absolute;right:calc((var(--tm-minimap-width, 24px) - var(--tm-compact-dot-size)) / 2);bottom:calc((var(--tm-minimap-height, 24px) - var(--tm-compact-dot-size)) / 2);width:var(--tm-compact-dot-size);height:var(--tm-compact-dot-size);border-radius:999px;background:color-mix(in srgb,var(--tm-viewport-border) 72%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--tm-viewport-border) 24%,transparent);opacity:.78;pointer-events:none;transition:opacity var(--tm-compact-transition-duration) ease-in-out,transform var(--tm-compact-transition-duration) ease-in-out,background-color var(--tm-compact-transition-duration) ease-in-out}.tm-minimap--compact-expanded{transform:translate(0)}.tm-minimap--compact-expanded:after{opacity:0;transform:scale(.7)}.tm-columns{display:flex;align-items:stretch;height:100%;gap:var(--tm-column-gap);padding:4px;box-sizing:border-box}.tm-column{flex:1 1 0;min-width:0;height:100%;background:var(--tm-column-color);border-radius:2px;transition:background-color .15s ease;cursor:pointer}.tm-column:hover{background:color-mix(in srgb,var(--tm-column-color) 80%,black)}.tm-canvas{width:100%;height:100%;display:block;cursor:pointer}.tm-viewport{position:absolute;top:0;height:100%;background:var(--tm-viewport-color);border-left:2px solid var(--tm-viewport-border);border-right:2px solid var(--tm-viewport-border);box-sizing:border-box;cursor:grab;transition:background-color .15s ease;z-index:10}.tm-viewport:hover{background:color-mix(in srgb,var(--tm-viewport-color) 100%,black 10%)}.tm-viewport--dragging{cursor:grabbing;background:color-mix(in srgb,var(--tm-viewport-color) 100%,black 20%);transition:none}.tm-viewport--disabled{cursor:default;pointer-events:none}.tm-minimap:focus-visible{outline:2px solid var(--tm-viewport-border);outline-offset:2px}.tm-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}';let W=!1;function R(){if(W||typeof document>"u")return;const v=document.createElement("style");v.id="table-minimap-styles",v.textContent=$,document.head.appendChild(v),W=!0}R();exports.TableMinimap=Z;exports.injectStyles=R;
1
+ "use strict";var z=Object.defineProperty;var A=(v,t,e)=>t in v?z(v,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):v[t]=e;var o=(v,t,e)=>A(v,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const H={mode:"columns",height:40,position:"bottom",fixedWidth:300,fixedPosition:"bottom-right",compact:!1,draggable:!0,showViewport:!0,zoomable:!1,minZoom:1,maxZoom:10,zoomSpeed:.1},X=24,O=5,F=180,$=180,P=["bottom-right","bottom-left","top-left","top-right"],Z=3,N=.85;class B{constructor(t,e={}){o(this,"table");o(this,"options");o(this,"isCompactMode");o(this,"isCompactCollapsed",!1);o(this,"isCompactExpanding",!1);o(this,"compactCollapseTimer",null);o(this,"minimapClickTimer",null);o(this,"scrollContainer",null);o(this,"minimapEl",null);o(this,"columnsEl",null);o(this,"canvasEl",null);o(this,"canvasCtx",null);o(this,"viewportEl",null);o(this,"columns",[]);o(this,"scrollState",{scrollLeft:0,scrollWidth:0,clientWidth:0,viewportRatio:1,positionRatio:0});o(this,"zoomState",{level:1,panX:0,isMinZoom:!0,isMaxZoom:!1});o(this,"isDragging",!1);o(this,"isPanning",!1);o(this,"wasPanning",!1);o(this,"panStartX",0);o(this,"pendingPanClientX",null);o(this,"hoveredColumn",-1);o(this,"dragStartX",0);o(this,"dragStartScrollLeft",0);o(this,"resizeObserver",null);o(this,"mutationObserver",null);o(this,"boundHandlers");o(this,"rafId",null);o(this,"canvasPanRafId",null);o(this,"isDestroyed",!1);o(this,"isPotentialPan",!1);this.table=this.resolveTable(t),this.options={...H,...e},this.isCompactMode=this.options.compact&&this.options.position==="fixed",this.boundHandlers={onScroll:this.onScroll.bind(this),onPointerDown:this.onPointerDown.bind(this),onPointerMove:this.onPointerMove.bind(this),onPointerUp:this.onPointerUp.bind(this),onMinimapClick:this.onMinimapClick.bind(this),onMinimapDoubleClick:this.onMinimapDoubleClick.bind(this),onWheel:this.onWheel.bind(this),onCanvasPointerDown:this.onCanvasPointerDown.bind(this),onCanvasMouseMove:this.onCanvasMouseMove.bind(this),onCanvasMouseLeave:this.onCanvasMouseLeave.bind(this),onCompactFocusIn:this.onCompactFocusIn.bind(this),onCompactFocusOut:this.onCompactFocusOut.bind(this),onCompactKeyDown:this.onCompactKeyDown.bind(this),onDocumentClick:this.onDocumentClick.bind(this)},this.init()}resolveTable(t){let e;if(typeof t=="string"){if(e=document.querySelector(t),!e)throw new Error(`TableMinimap: No element found for selector "${t}"`)}else if(t instanceof HTMLTableElement)e=t;else throw new Error("TableMinimap: Selector must be a CSS selector string or an HTMLTableElement");if(e.tagName!=="TABLE")throw new Error(`TableMinimap: Element must be a <table>, got <${e.tagName.toLowerCase()}>`);return e}init(){this.scrollContainer=this.findScrollContainer(),this.detectColumns(),this.createMinimapElement(),this.updateScrollState(),this.render(),this.attachEventListeners(),this.setupObservers()}findScrollContainer(){let t=this.table.parentElement;for(;t;){const e=getComputedStyle(t),i=e.overflowX,n=e.overflow;if(i==="auto"||i==="scroll"||n==="auto"||n==="scroll"||t.scrollWidth>t.clientWidth)return t;t=t.parentElement}return this.table.parentElement||document.body}detectColumns(){this.columns=[];const t=this.table.querySelectorAll("thead th, thead td");let e;if(t.length>0)e=t;else{const n=this.table.querySelector("tr");n?e=n.querySelectorAll("th, td"):e=[]}const i=this.table.offsetWidth||1;Array.from(e).forEach(n=>{const a=n.colSpan||1,s=n.offsetWidth;for(let l=0;l<a;l++){const r=s/a;this.columns.push({index:this.columns.length,width:r,widthPercent:r/i*100})}}),this.columns.length===0&&this.columns.push({index:0,width:i,widthPercent:100})}createMinimapElement(){this.minimapEl=document.createElement("div"),this.minimapEl.className=`tm-minimap tm-minimap--${this.options.position}`,this.minimapEl.style.setProperty("--tm-minimap-height",`${this.options.height}px`),this.options.position==="fixed"&&(this.minimapEl.style.setProperty("--tm-minimap-width",`${this.options.fixedWidth}px`),this.minimapEl.title="Double-click to move minimap to the next corner"),this.isCompactMode?(this.minimapEl.classList.add("tm-minimap--compact","tm-minimap--compact-collapsed"),this.minimapEl.style.setProperty("--tm-compact-dot-size",`${O}px`),this.isCompactCollapsed=!0,this.applyCompactDimensions(!0),this.minimapEl.setAttribute("aria-expanded","false")):this.minimapEl.setAttribute("aria-expanded","true"),this.minimapEl.setAttribute("role","slider"),this.minimapEl.setAttribute("aria-label","Table minimap navigation"),this.minimapEl.setAttribute("aria-valuemin","0"),this.minimapEl.setAttribute("aria-valuemax","100"),this.minimapEl.setAttribute("tabindex","0"),this.options.mode==="canvas"?this.createCanvasContent():this.createColumnsContent(),this.options.showViewport&&this.createViewportIndicator(),this.insertMinimap()}createColumnsContent(){this.minimapEl&&(this.columnsEl=document.createElement("div"),this.columnsEl.className="tm-columns",this.columns.forEach(()=>{const t=document.createElement("div");t.className="tm-column",this.columnsEl.appendChild(t)}),this.minimapEl.appendChild(this.columnsEl))}createCanvasContent(){this.minimapEl&&(this.canvasEl=document.createElement("canvas"),this.canvasEl.className="tm-canvas",this.canvasCtx=this.canvasEl.getContext("2d"),this.minimapEl.appendChild(this.canvasEl))}createViewportIndicator(){this.minimapEl&&(this.viewportEl=document.createElement("div"),this.viewportEl.className="tm-viewport",this.options.draggable||this.viewportEl.classList.add("tm-viewport--disabled"),this.minimapEl.appendChild(this.viewportEl))}insertMinimap(){if(!this.minimapEl||!this.scrollContainer)return;const t=this.scrollContainer.parentElement;if(this.options.position==="fixed"){if(t){getComputedStyle(t).position==="static"&&(t.style.position="relative");const i=this.scrollContainer.nextSibling;i?t.insertBefore(this.minimapEl,i):t.appendChild(this.minimapEl),this.minimapEl.style.position="absolute",this.applyFixedPosition()}}else if(this.options.position==="top")t?t.insertBefore(this.minimapEl,this.scrollContainer):this.scrollContainer.insertBefore(this.minimapEl,this.scrollContainer.firstChild);else if(t){const e=this.scrollContainer.nextSibling;e?t.insertBefore(this.minimapEl,e):t.appendChild(this.minimapEl)}else this.scrollContainer.appendChild(this.minimapEl)}applyFixedPosition(){if(!this.minimapEl||this.options.position!=="fixed")return;const t=this.isCompactMode?8:12,e=this.options.fixedPosition;P.forEach(i=>{this.minimapEl.classList.remove(`tm-minimap--${i}`)}),this.minimapEl.classList.add(`tm-minimap--${e}`),this.minimapEl.style.top="",this.minimapEl.style.bottom="",this.minimapEl.style.left="",this.minimapEl.style.right="",this.minimapEl.style.marginTop="0",e==="top-left"?(this.minimapEl.style.top=`${t}px`,this.minimapEl.style.left=`${t}px`):e==="top-right"?(this.minimapEl.style.top=`${t}px`,this.minimapEl.style.right=`${t}px`):e==="bottom-left"?(this.minimapEl.style.bottom=`${t}px`,this.minimapEl.style.left=`${t}px`):(this.minimapEl.style.bottom=`${t}px`,this.minimapEl.style.right=`${t}px`)}cycleFixedPosition(){if(this.options.position!=="fixed")return;const t=P.indexOf(this.options.fixedPosition),e=t>=0?(t+1)%P.length:0;this.options.fixedPosition=P[e],this.applyFixedPosition()}updateScrollState(){if(!this.scrollContainer)return;const{scrollLeft:t,scrollWidth:e,clientWidth:i}=this.scrollContainer;this.scrollState={scrollLeft:t,scrollWidth:e,clientWidth:i,viewportRatio:i/Math.max(e,1),positionRatio:t/Math.max(e-i,1)},this.scrollState.viewportRatio=Math.min(1,Math.max(0,this.scrollState.viewportRatio)),this.scrollState.positionRatio=Math.min(1,Math.max(0,this.scrollState.positionRatio)),this.minimapEl&&this.minimapEl.setAttribute("aria-valuenow",String(Math.round(this.scrollState.positionRatio*100)))}render(){this.isDestroyed||this.isCompactMode&&this.isCompactCollapsed||(this.updateViewport(),this.options.mode==="canvas"&&this.renderCanvas())}getCanvasMetrics(){var p;const t=((p=this.minimapEl)==null?void 0:p.offsetWidth)??0,e=this.zoomState.level,i=this.columns.length,n=1/e,a=i*n,s=a>0?t/a:0;let l=0;if(e>1&&this.scrollContainer){const{scrollLeft:c,scrollWidth:g,clientWidth:w}=this.scrollContainer,d=Math.max(g-w,1);l=c/d*(1-n)}const r=l*i,m=Math.floor(r),u=Math.min(Math.ceil(r+a)+1,i),f=-(r-m)*s;return{width:t,zoom:e,numCols:i,visibleRatio:n,visibleCols:a,cellWidth:s,panX:l,startColFloat:r,startCol:m,endCol:u,xOffset:f}}getColumnAtX(t){const{width:e,numCols:i,panX:n,visibleRatio:a}=this.getCanvasMetrics();if(i===0||e===0)return-1;const s=t/e,l=n+s*a,r=Math.floor(l*i);return Math.max(0,Math.min(i-1,r))}updateViewport(){if(!this.viewportEl||!this.minimapEl)return;if(this.options.mode==="canvas"){this.viewportEl.style.display="none";return}const t=this.minimapEl.offsetWidth,e=Math.max(t*this.scrollState.viewportRatio,20),n=(t-e)*this.scrollState.positionRatio;this.viewportEl.style.cssText=`width:${e}px;left:${n}px;display:block`}renderCanvas(){if(!this.canvasEl||!this.canvasCtx||!this.minimapEl)return;const t=this.getCanvasMetrics(),e=this.options.height,i=window.devicePixelRatio||1;this.canvasEl.width=t.width*i,this.canvasEl.height=e*i,this.canvasEl.style.width=`${t.width}px`,this.canvasEl.style.height=`${e}px`,this.canvasCtx.scale(i,i),this.renderTableDirect(t,e)}renderTableDirect(t,e){var S,M,k,T;if(!this.canvasCtx)return;const i=this.canvasCtx,{width:n,numCols:a,cellWidth:s,startCol:l,endCol:r,xOffset:m}=t,u=Array.from(this.table.querySelectorAll("tr")),f=u.length;if(f===0||a===0)return;const p=Math.min(e*.15,30),c=(e-p)/f,g=Math.min(c*.6,s*.15,14),w=Math.min(p*.6,s*.15,14),d={bg:"#ffffff",headerBg:"#f1f5f9",border:"#e2e8f0",text:"#334155",headerText:"#1e293b",altRow:"#f8fafc",hoverFill:"rgba(59, 130, 246, 0.08)",hoverStroke:"rgba(59, 130, 246, 0.3)"};i.fillStyle=d.bg,i.fillRect(0,0,n,e),i.fillStyle=d.headerBg,i.fillRect(0,0,n,p);const E=this.table.querySelector("thead tr")||u[0],L=E?Array.from(E.querySelectorAll("th, td")):[];i.font=`bold ${w}px system-ui, sans-serif`,i.textBaseline="middle";for(let h=l;h<r;h++){const C=m+(h-l)*s;if(C+s<0||C>n)continue;i.strokeStyle=d.border,i.lineWidth=1,i.strokeRect(C,0,s,p);const b=((M=(S=L[h])==null?void 0:S.textContent)==null?void 0:M.trim())||`Col ${h+1}`;i.fillStyle=d.headerText,i.save(),i.beginPath(),i.rect(C+2,0,s-4,p),i.clip(),i.fillText(b,C+4,p/2),i.restore()}i.font=`${g}px system-ui, sans-serif`;for(let h=0;h<u.length;h++){const C=u[h];if(C.closest("thead"))continue;const b=p+h*c;if(b+c<0||b>e)continue;h%2===1&&(i.fillStyle=d.altRow,i.fillRect(0,b,n,c));const I=Array.from(C.querySelectorAll("th, td"));for(let y=l;y<r;y++){const x=m+(y-l)*s;if(x+s<0||x>n)continue;i.strokeStyle=d.border,i.lineWidth=.5,i.strokeRect(x,b,s,c);const D=(T=(k=I[y])==null?void 0:k.textContent)==null?void 0:T.trim();D&&(i.fillStyle=d.text,i.save(),i.beginPath(),i.rect(x+2,b,s-4,c),i.clip(),i.fillText(D,x+4,b+c/2),i.restore())}}if(this.hoveredColumn>=l&&this.hoveredColumn<r){const h=m+(this.hoveredColumn-l)*s;i.fillStyle=d.hoverFill,i.fillRect(h,0,s,e),i.strokeStyle=d.hoverStroke,i.lineWidth=1,i.strokeRect(h,0,s,e)}}attachEventListeners(){!this.scrollContainer||!this.minimapEl||(this.scrollContainer.addEventListener("scroll",this.boundHandlers.onScroll,{passive:!0}),this.minimapEl.addEventListener("click",this.boundHandlers.onMinimapClick),this.minimapEl.addEventListener("dblclick",this.boundHandlers.onMinimapDoubleClick),this.isCompactMode&&(this.minimapEl.addEventListener("focusin",this.boundHandlers.onCompactFocusIn),this.minimapEl.addEventListener("focusout",this.boundHandlers.onCompactFocusOut),this.minimapEl.addEventListener("keydown",this.boundHandlers.onCompactKeyDown),document.addEventListener("click",this.boundHandlers.onDocumentClick)),this.options.draggable&&this.viewportEl&&this.viewportEl.addEventListener("pointerdown",this.boundHandlers.onPointerDown),this.options.zoomable&&this.options.mode==="canvas"&&this.canvasEl&&(this.canvasEl.addEventListener("wheel",this.boundHandlers.onWheel,{passive:!1}),this.canvasEl.addEventListener("pointerdown",this.boundHandlers.onCanvasPointerDown),this.canvasEl.style.cursor=this.zoomState.level>1?"grab":"pointer",this.viewportEl&&this.viewportEl.addEventListener("wheel",this.boundHandlers.onWheel,{passive:!1})),this.options.mode==="canvas"&&this.canvasEl&&(this.canvasEl.addEventListener("mousemove",this.boundHandlers.onCanvasMouseMove),this.canvasEl.addEventListener("mouseleave",this.boundHandlers.onCanvasMouseLeave)),document.addEventListener("pointermove",this.boundHandlers.onPointerMove),document.addEventListener("pointerup",this.boundHandlers.onPointerUp))}onScroll(){this.isDragging||this.rafId===null&&(this.rafId=requestAnimationFrame(()=>{this.updateScrollState(),this.updateViewport(),this.options.mode==="canvas"&&this.render(),this.rafId=null}))}onMinimapClick(t){if(!(!this.minimapEl||!this.scrollContainer)){if(this.isCompactMode&&(this.isCompactCollapsed||this.isCompactExpanding)){t.preventDefault(),this.clearMinimapClickTimer(),this.isCompactCollapsed&&this.expandCompact();return}if(this.options.position==="fixed"){if(t.detail>1)return;const e=t.clientX;this.clearMinimapClickTimer(),this.minimapClickTimer=window.setTimeout(()=>{this.minimapClickTimer=null,this.handleMinimapClick(e)},$);return}this.handleMinimapClick(t.clientX)}}onMinimapDoubleClick(t){this.options.position==="fixed"&&(t.preventDefault(),t.stopPropagation(),this.clearMinimapClickTimer(),this.cycleFixedPosition())}clearMinimapClickTimer(){this.minimapClickTimer!==null&&(clearTimeout(this.minimapClickTimer),this.minimapClickTimer=null)}handleMinimapClick(t){if(!this.minimapEl||!this.scrollContainer)return;if(this.isCompactMode&&this.isCompactCollapsed){this.expandCompact();return}if(this.isCompactExpanding||this.isDragging||this.isPanning||this.wasPanning)return;const{scrollWidth:e,clientWidth:i}=this.scrollContainer,n=e-i,a=this.minimapEl.getBoundingClientRect(),s=t-a.left;if(this.options.mode==="canvas"){const m=this.getColumnAtX(s);if(m>=0){const u=this.columns.length,f=e/u,c=(m+.5)*f-i/2;this.scrollContainer.scrollTo({left:Math.max(0,Math.min(n,c)),behavior:"smooth"})}return}const r=s/a.width*n;this.scrollContainer.scrollTo({left:Math.max(0,Math.min(n,r)),behavior:"smooth"})}onPointerDown(t){!this.viewportEl||!this.scrollContainer||(t.preventDefault(),t.stopPropagation(),this.isDragging=!0,this.dragStartX=t.clientX,this.dragStartScrollLeft=this.scrollContainer.scrollLeft,this.viewportEl.classList.add("tm-viewport--dragging"),this.viewportEl.setPointerCapture(t.pointerId))}onPointerMove(t){if(this.isPotentialPan&&!this.isPanning&&this.canvasEl&&this.zoomState.level>1&&Math.abs(t.clientX-this.panStartX)>Z&&(this.isPanning=!0,this.canvasEl.style.cursor="grabbing"),this.isPanning&&this.canvasEl&&this.minimapEl&&this.scrollContainer){t.preventDefault(),this.pendingPanClientX=t.clientX,this.scheduleCanvasPan();return}if(!this.isDragging||!this.minimapEl||!this.scrollContainer)return;t.preventDefault();const{scrollWidth:e,clientWidth:i}=this.scrollContainer,n=this.minimapEl.offsetWidth,a=e-i,l=(t.clientX-this.dragStartX)/n*a,r=this.dragStartScrollLeft+l;this.scrollContainer.scrollLeft=Math.max(0,Math.min(a,r)),this.updateScrollState(),this.updateViewport()}scheduleCanvasPan(){this.canvasPanRafId===null&&(this.canvasPanRafId=requestAnimationFrame(()=>{this.canvasPanRafId=null,this.applyCanvasPan()}))}applyCanvasPan(){if(!this.isPanning||this.pendingPanClientX===null||!this.minimapEl||!this.scrollContainer)return;const t=this.panStartX-this.pendingPanClientX,e=Math.max(this.minimapEl.offsetWidth,1),{scrollWidth:i,clientWidth:n}=this.scrollContainer,a=Math.max(i-n,0),s=1/Math.max(this.zoomState.level,1),l=t/e*a*s*N;this.scrollContainer.scrollLeft=Math.max(0,Math.min(a,this.dragStartScrollLeft+l)),this.updateScrollState(),this.updateViewport(),this.render()}clearCanvasPanFrame(){this.canvasPanRafId!==null&&(cancelAnimationFrame(this.canvasPanRafId),this.canvasPanRafId=null)}onPointerUp(t){if(this.isPotentialPan&&!this.isPanning&&this.canvasEl&&this.minimapEl){this.isPotentialPan=!1,this.pendingPanClientX=null,this.canvasEl.hasPointerCapture(t.pointerId)&&this.canvasEl.releasePointerCapture(t.pointerId);const e=new MouseEvent("click",{clientX:t.clientX,clientY:t.clientY,bubbles:!0});this.minimapEl.dispatchEvent(e);return}this.isPotentialPan=!1,this.isPanning&&this.canvasEl&&(this.applyCanvasPan(),this.clearCanvasPanFrame(),this.pendingPanClientX=null,this.isPanning=!1,this.wasPanning=!0,this.canvasEl.hasPointerCapture(t.pointerId)&&this.canvasEl.releasePointerCapture(t.pointerId),this.canvasEl.style.cursor=this.zoomState.level>1?"grab":"pointer",setTimeout(()=>{this.wasPanning=!1},100)),this.isDragging&&(this.isDragging=!1,this.viewportEl&&(this.viewportEl.classList.remove("tm-viewport--dragging"),this.viewportEl.releasePointerCapture(t.pointerId)))}onWheel(t){if(!this.options.zoomable||this.options.mode!=="canvas"||!this.canvasEl||!this.scrollContainer||!this.minimapEl)return;t.preventDefault();const e=this.zoomState.level,i=-t.deltaY*this.options.zoomSpeed,n=Math.max(this.options.minZoom,Math.min(this.options.maxZoom,e+i));if(n===e)return;const a=this.canvasEl.getBoundingClientRect(),s=t.clientX-a.left,l=this.minimapEl.offsetWidth,r=s/l,m=1/e,{scrollLeft:u,scrollWidth:f,clientWidth:p}=this.scrollContainer,c=Math.max(f-p,1),g=u/c,d=(e>1?g*(1-m):0)+r*m;this.zoomState={level:n,panX:0,isMinZoom:n<=this.options.minZoom,isMaxZoom:n>=this.options.maxZoom};const E=1/n;if(n>1){const S=(d-r*E)/(1-E),M=Math.max(0,Math.min(c,S*c));this.scrollContainer.scrollLeft=M}this.updateScrollState(),this.render()}onCanvasPointerDown(t){!this.canvasEl||!this.scrollContainer||(this.isPotentialPan=!0,this.panStartX=t.clientX,this.dragStartScrollLeft=this.scrollContainer.scrollLeft,this.zoomState.level>1&&(t.preventDefault(),this.canvasEl.setPointerCapture(t.pointerId)))}onCanvasMouseMove(t){if(!this.canvasEl||this.isPanning)return;const e=this.canvasEl.getBoundingClientRect(),i=this.getColumnAtX(t.clientX-e.left);i!==this.hoveredColumn&&(this.hoveredColumn=i,this.canvasEl.style.cursor=i>=0?"pointer":this.zoomState.level>1?"grab":"default",this.render())}onCanvasMouseLeave(){this.hoveredColumn!==-1&&(this.hoveredColumn=-1,this.canvasEl&&(this.canvasEl.style.cursor=this.zoomState.level>1?"grab":"default"),this.render())}expandCompact(){!this.isCompactMode||!this.minimapEl||this.isCompactExpanding||(this.clearCompactCollapseTimer(),this.isCompactExpanding=!0,this.applyCompactDimensions(!1),setTimeout(()=>{this.isCompactExpanding=!1,!this.isDestroyed&&!this.isCompactCollapsed&&(this.updateScrollState(),this.render())},200))}collapseCompact(){!this.isCompactMode||!this.minimapEl||this.applyCompactDimensions(!0)}applyCompactDimensions(t){if(!(!this.minimapEl||!this.isCompactMode)){if(this.isCompactCollapsed=t,t){this.minimapEl.classList.add("tm-minimap--compact-collapsed"),this.minimapEl.classList.remove("tm-minimap--compact-expanded"),this.minimapEl.style.setProperty("--tm-minimap-width",`${X}px`),this.minimapEl.style.setProperty("--tm-minimap-height",`${X}px`),this.minimapEl.setAttribute("aria-expanded","false");return}this.minimapEl.classList.remove("tm-minimap--compact-collapsed"),this.minimapEl.classList.add("tm-minimap--compact-expanded"),this.minimapEl.style.setProperty("--tm-minimap-width",`${this.options.fixedWidth}px`),this.minimapEl.style.setProperty("--tm-minimap-height",`${this.options.height}px`),this.minimapEl.setAttribute("aria-expanded","true")}}clearCompactCollapseTimer(){this.compactCollapseTimer!==null&&(clearTimeout(this.compactCollapseTimer),this.compactCollapseTimer=null)}scheduleCompactCollapse(t=F){this.isCompactMode&&(this.clearCompactCollapseTimer(),this.compactCollapseTimer=window.setTimeout(()=>{this.collapseCompact(),this.compactCollapseTimer=null},t))}onDocumentClick(t){!this.isCompactMode||!this.minimapEl||this.isCompactCollapsed||this.minimapEl.contains(t.target)||this.collapseCompact()}onCompactFocusIn(){this.isCompactMode&&this.expandCompact()}onCompactFocusOut(){this.isCompactMode&&this.scheduleCompactCollapse(0)}onCompactKeyDown(t){if(this.isCompactMode){if(t.key==="Escape"){t.preventDefault(),this.collapseCompact();return}(t.key==="Enter"||t.key===" ")&&(t.preventDefault(),this.isCompactCollapsed?this.expandCompact():this.collapseCompact())}}setupObservers(){this.resizeObserver=new ResizeObserver(()=>{this.onResize()}),this.scrollContainer&&this.resizeObserver.observe(this.scrollContainer),this.resizeObserver.observe(this.table),this.mutationObserver=new MutationObserver(t=>{t.some(i=>i.type==="childList"||i.attributeName==="colspan")&&this.onTableMutation()}),this.mutationObserver.observe(this.table,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["colspan"]})}onResize(){this.isDestroyed||(this.rafId!==null&&cancelAnimationFrame(this.rafId),this.rafId=requestAnimationFrame(()=>{this.detectColumns(),this.updateScrollState(),this.render(),this.options.mode==="columns"&&this.columnsEl&&this.minimapEl&&(this.columnsEl.innerHTML="",this.columns.forEach(()=>{const t=document.createElement("div");t.className="tm-column",this.columnsEl.appendChild(t)})),this.rafId=null}))}onTableMutation(){this.isDestroyed||(this.detectColumns(),this.updateScrollState(),this.render(),this.options.mode==="columns"&&this.columnsEl&&(this.columnsEl.innerHTML="",this.columns.forEach(()=>{const t=document.createElement("div");t.className="tm-column",this.columnsEl.appendChild(t)})))}getScrollState(){return{...this.scrollState}}getColumns(){return[...this.columns]}scrollToColumn(t,e=!0){if(!this.scrollContainer||t<0||t>=this.columns.length)return;const n=this.columns.slice(0,t).reduce((a,s)=>a+s.width,0);this.scrollContainer.scrollTo({left:n,behavior:e?"smooth":"auto"})}refresh(){this.isDestroyed||(this.scrollContainer=this.findScrollContainer(),this.detectColumns(),this.updateScrollState(),this.render(),this.options.mode==="columns"&&this.columnsEl&&(this.columnsEl.innerHTML="",this.columns.forEach(()=>{const t=document.createElement("div");t.className="tm-column",this.columnsEl.appendChild(t)})))}getZoomState(){return{...this.zoomState}}setZoom(t,e){if(this.isDestroyed||this.options.mode!=="canvas"||!this.scrollContainer)return;const i=Math.max(this.options.minZoom,Math.min(this.options.maxZoom,t)),n=1/i,a=1-n;let s=e!==void 0?e:0;if(s=Math.max(0,Math.min(a,s)),this.zoomState={level:i,panX:0,isMinZoom:i<=this.options.minZoom,isMaxZoom:i>=this.options.maxZoom},i>1&&s>0){const{scrollWidth:l,clientWidth:r}=this.scrollContainer,m=Math.max(l-r,1),u=s/(1-n);this.scrollContainer.scrollLeft=Math.max(0,Math.min(m,u*m))}else i<=1&&(this.scrollContainer.scrollLeft=0);this.updateScrollState(),this.render()}resetZoom(){this.setZoom(1,0)}zoomToColumns(t,e){if(this.isDestroyed||this.options.mode!=="canvas")return;const i=this.columns.length;if(i===0)return;const n=Math.max(0,Math.min(i-1,t)),s=Math.max(n+1,Math.min(i,e))-n,l=i/s,r=n/i;this.setZoom(l,r)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.clearCompactCollapseTimer(),this.clearMinimapClickTimer(),this.clearCanvasPanFrame(),this.pendingPanClientX=null,this.rafId!==null&&(cancelAnimationFrame(this.rafId),this.rafId=null),this.scrollContainer&&this.scrollContainer.removeEventListener("scroll",this.boundHandlers.onScroll),this.minimapEl&&(this.minimapEl.removeEventListener("click",this.boundHandlers.onMinimapClick),this.minimapEl.removeEventListener("dblclick",this.boundHandlers.onMinimapDoubleClick),this.minimapEl.removeEventListener("focusin",this.boundHandlers.onCompactFocusIn),this.minimapEl.removeEventListener("focusout",this.boundHandlers.onCompactFocusOut),this.minimapEl.removeEventListener("keydown",this.boundHandlers.onCompactKeyDown)),document.removeEventListener("click",this.boundHandlers.onDocumentClick),this.viewportEl&&(this.viewportEl.removeEventListener("pointerdown",this.boundHandlers.onPointerDown),this.viewportEl.removeEventListener("wheel",this.boundHandlers.onWheel)),this.canvasEl&&(this.canvasEl.removeEventListener("wheel",this.boundHandlers.onWheel),this.canvasEl.removeEventListener("pointerdown",this.boundHandlers.onCanvasPointerDown),this.canvasEl.removeEventListener("mousemove",this.boundHandlers.onCanvasMouseMove),this.canvasEl.removeEventListener("mouseleave",this.boundHandlers.onCanvasMouseLeave)),document.removeEventListener("pointermove",this.boundHandlers.onPointerMove),document.removeEventListener("pointerup",this.boundHandlers.onPointerUp),this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.minimapEl&&this.minimapEl.parentNode&&this.minimapEl.parentNode.removeChild(this.minimapEl),this.minimapEl=null,this.columnsEl=null,this.canvasEl=null,this.canvasCtx=null,this.viewportEl=null,this.scrollContainer=null,this.columns=[])}}const V=':root{--tm-background: #e3f2fd;--tm-border: #90caf9;--tm-viewport-color: rgba(25, 118, 210, .3);--tm-viewport-border: #1976d2;--tm-height: 40px;--tm-column-color: #64b5f6;--tm-column-gap: 1px;--tm-border-radius: 4px;--tm-canvas-empty: #bbdefb;--tm-canvas-filled: #1565c0;--tm-compact-dot-size: 5px;--tm-compact-transition-duration: .18s}@media (prefers-color-scheme: dark){:root{--tm-background: #1a237e;--tm-border: #3949ab;--tm-viewport-color: rgba(100, 180, 255, .3);--tm-viewport-border: #64b5f6;--tm-column-color: #3f51b5;--tm-canvas-empty: #283593;--tm-canvas-filled: #90caf9}}.tm-minimap{position:relative;width:var(--tm-minimap-width, 100%);height:var(--tm-minimap-height, var(--tm-height));background:var(--tm-background);border:1px solid var(--tm-border);border-radius:var(--tm-border-radius);box-sizing:border-box;overflow:hidden;user-select:none;-webkit-user-select:none;cursor:pointer;transition:width var(--tm-compact-transition-duration) ease-in-out,height var(--tm-compact-transition-duration) ease-in-out,opacity var(--tm-compact-transition-duration) ease-in-out,transform var(--tm-compact-transition-duration) ease-in-out,background-color var(--tm-compact-transition-duration) ease-in-out,border-color var(--tm-compact-transition-duration) ease-in-out,box-shadow var(--tm-compact-transition-duration) ease-in-out;will-change:width,height,opacity,transform}.tm-minimap--top{margin-bottom:8px}.tm-minimap--bottom{margin-top:8px}.tm-minimap--fixed{z-index:100;background:color-mix(in srgb,var(--tm-background) 72%,transparent);border-color:color-mix(in srgb,var(--tm-border) 72%,transparent);box-shadow:0 4px 12px #00000026;border-radius:8px;opacity:.78;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px)}.tm-minimap--fixed:hover,.tm-minimap--fixed:focus-within{opacity:.96}.tm-minimap--compact-collapsed{border-radius:999px}.tm-minimap--compact-expanded{border-radius:8px}.tm-minimap--compact>*{transition:opacity var(--tm-compact-transition-duration) ease-in-out}.tm-minimap--compact-collapsed{background:color-mix(in srgb,var(--tm-background) 60%,transparent);border-color:color-mix(in srgb,var(--tm-border) 45%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--tm-border) 20%,transparent);opacity:.72;transform:translate(2px,2px)}.tm-minimap--compact-collapsed>*{opacity:0;pointer-events:none}.tm-minimap--compact-collapsed:after{content:"";position:absolute;right:calc((var(--tm-minimap-width, 24px) - var(--tm-compact-dot-size)) / 2);bottom:calc((var(--tm-minimap-height, 24px) - var(--tm-compact-dot-size)) / 2);width:var(--tm-compact-dot-size);height:var(--tm-compact-dot-size);border-radius:999px;background:color-mix(in srgb,var(--tm-viewport-border) 72%,transparent);box-shadow:0 0 0 1px color-mix(in srgb,var(--tm-viewport-border) 24%,transparent);opacity:.78;pointer-events:none;transition:opacity var(--tm-compact-transition-duration) ease-in-out,transform var(--tm-compact-transition-duration) ease-in-out,background-color var(--tm-compact-transition-duration) ease-in-out}.tm-minimap--compact-expanded{transform:translate(0)}.tm-minimap--compact-expanded:after{opacity:0;transform:scale(.7)}.tm-columns{display:flex;align-items:stretch;height:100%;gap:var(--tm-column-gap);padding:4px;box-sizing:border-box}.tm-column{flex:1 1 0;min-width:0;height:100%;background:var(--tm-column-color);border-radius:2px;transition:background-color .15s ease;cursor:pointer}.tm-column:hover{background:color-mix(in srgb,var(--tm-column-color) 80%,black)}.tm-canvas{width:100%;height:100%;display:block;cursor:pointer}.tm-viewport{position:absolute;top:0;height:100%;background:var(--tm-viewport-color);border-left:2px solid var(--tm-viewport-border);border-right:2px solid var(--tm-viewport-border);box-sizing:border-box;cursor:grab;transition:background-color .15s ease;z-index:10}.tm-viewport:hover{background:color-mix(in srgb,var(--tm-viewport-color) 100%,black 10%)}.tm-viewport--dragging{cursor:grabbing;background:color-mix(in srgb,var(--tm-viewport-color) 100%,black 20%);transition:none}.tm-viewport--disabled{cursor:default;pointer-events:none}.tm-minimap:focus-visible{outline:2px solid var(--tm-viewport-border);outline-offset:2px}.tm-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}';let R=!1;function W(){if(R||typeof document>"u")return;const v=document.createElement("style");v.id="table-minimap-styles",v.textContent=V,document.head.appendChild(v),R=!0}W();exports.TableMinimap=B;exports.injectStyles=W;
2
2
  //# sourceMappingURL=table-minimap.cjs.map