table-minimap 1.0.7 → 1.1.1
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/LICENSE +22 -0
- package/README.md +7 -0
- package/dist/index.d.ts +11 -6
- package/dist/shadcn.css +16 -2
- package/dist/table-minimap.cjs +1 -1
- package/dist/table-minimap.cjs.map +1 -1
- package/dist/table-minimap.js +124 -121
- package/dist/table-minimap.js.map +1 -1
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kevin Imig
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
CHANGED
|
@@ -190,6 +190,12 @@ interface TableMinimapOptions {
|
|
|
190
190
|
*/
|
|
191
191
|
position?: 'top' | 'bottom' | 'fixed';
|
|
192
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Corner position when using position: 'fixed'
|
|
195
|
+
* @default "bottom-right"
|
|
196
|
+
*/
|
|
197
|
+
fixedPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
198
|
+
|
|
193
199
|
/**
|
|
194
200
|
* Enable compact floating mode for fixed minimaps
|
|
195
201
|
* @default false
|
|
@@ -241,6 +247,7 @@ interface TableMinimapOptions {
|
|
|
241
247
|
| `mode` | `'columns'` |
|
|
242
248
|
| `height` | `40` |
|
|
243
249
|
| `position` | `'bottom'` |
|
|
250
|
+
| `fixedPosition` | `'bottom-right'` |
|
|
244
251
|
| `compact` | `false` |
|
|
245
252
|
| `draggable` | `true` |
|
|
246
253
|
| `showViewport` | `true` |
|
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,8 @@ export declare class TableMinimap {
|
|
|
78
78
|
private readonly isCompactMode;
|
|
79
79
|
/** Whether the compact minimap is currently collapsed */
|
|
80
80
|
private isCompactCollapsed;
|
|
81
|
+
/** Whether the compact minimap is currently expanding (transition in progress) */
|
|
82
|
+
private isCompactExpanding;
|
|
81
83
|
/** Timeout used to collapse compact mode after pointer leave */
|
|
82
84
|
private compactCollapseTimer;
|
|
83
85
|
/** The scrollable container (parent of table) */
|
|
@@ -108,9 +110,7 @@ export declare class TableMinimap {
|
|
|
108
110
|
private panStartX;
|
|
109
111
|
/** Currently hovered column index (-1 = none) */
|
|
110
112
|
private hoveredColumn;
|
|
111
|
-
/**
|
|
112
|
-
private focusedColumn;
|
|
113
|
-
/** Drag start position */
|
|
113
|
+
/** Drag start X position */
|
|
114
114
|
private dragStartX;
|
|
115
115
|
/** Drag start scroll position */
|
|
116
116
|
private dragStartScrollLeft;
|
|
@@ -192,7 +192,7 @@ export declare class TableMinimap {
|
|
|
192
192
|
private getColumnAtX;
|
|
193
193
|
/**
|
|
194
194
|
* Updates the viewport indicator position and size
|
|
195
|
-
*
|
|
195
|
+
* Shows the visible portion of the table (columns mode only)
|
|
196
196
|
*/
|
|
197
197
|
private updateViewport;
|
|
198
198
|
/**
|
|
@@ -338,7 +338,7 @@ export declare class TableMinimap {
|
|
|
338
338
|
* Sets the zoom level programmatically (canvas mode only)
|
|
339
339
|
*
|
|
340
340
|
* @param level - Zoom level (1 = no zoom)
|
|
341
|
-
* @param panX - Optional pan position (0-1)
|
|
341
|
+
* @param panX - Optional pan position (0-1), controls which part of table is visible
|
|
342
342
|
*/
|
|
343
343
|
setZoom(level: number, panX?: number): void;
|
|
344
344
|
/**
|
|
@@ -386,6 +386,11 @@ export declare interface TableMinimapOptions {
|
|
|
386
386
|
* @default 300
|
|
387
387
|
*/
|
|
388
388
|
fixedWidth?: number;
|
|
389
|
+
/**
|
|
390
|
+
* Corner position when using position: 'fixed'
|
|
391
|
+
* @default "bottom-right"
|
|
392
|
+
*/
|
|
393
|
+
fixedPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
389
394
|
/**
|
|
390
395
|
* Enable compact floating mode for fixed minimaps.
|
|
391
396
|
* When enabled, the minimap collapses into a small dot handle in the
|
|
@@ -436,7 +441,7 @@ export declare type TableSelector = string | HTMLTableElement;
|
|
|
436
441
|
export declare interface ZoomState {
|
|
437
442
|
/** Current zoom level (1 = no zoom) */
|
|
438
443
|
level: number;
|
|
439
|
-
/**
|
|
444
|
+
/** @deprecated Pan offset is now derived from scroll position */
|
|
440
445
|
panX: number;
|
|
441
446
|
/** Whether zoom is at minimum (showing full overview) */
|
|
442
447
|
isMinZoom: boolean;
|
package/dist/shadcn.css
CHANGED
|
@@ -58,6 +58,19 @@
|
|
|
58
58
|
margin-top: 8px;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
.tm-minimap--fixed {
|
|
62
|
+
background: color-mix(in srgb, var(--tm-background) 72%, transparent);
|
|
63
|
+
border-color: color-mix(in srgb, var(--tm-border) 72%, transparent);
|
|
64
|
+
opacity: 0.78;
|
|
65
|
+
backdrop-filter: blur(2px);
|
|
66
|
+
-webkit-backdrop-filter: blur(2px);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.tm-minimap--fixed:hover,
|
|
70
|
+
.tm-minimap--fixed:focus-within {
|
|
71
|
+
opacity: 0.96;
|
|
72
|
+
}
|
|
73
|
+
|
|
61
74
|
.tm-minimap--compact {
|
|
62
75
|
border-radius: 999px;
|
|
63
76
|
}
|
|
@@ -70,7 +83,7 @@
|
|
|
70
83
|
background: color-mix(in srgb, var(--tm-background) 60%, transparent);
|
|
71
84
|
border-color: color-mix(in srgb, var(--tm-border) 45%, transparent);
|
|
72
85
|
box-shadow: 0 0 0 1px color-mix(in srgb, var(--tm-border) 20%, transparent);
|
|
73
|
-
opacity: 0.
|
|
86
|
+
opacity: 0.72;
|
|
74
87
|
transform: translate(2px, 2px);
|
|
75
88
|
}
|
|
76
89
|
|
|
@@ -120,7 +133,8 @@
|
|
|
120
133
|
}
|
|
121
134
|
|
|
122
135
|
.tm-column {
|
|
123
|
-
flex
|
|
136
|
+
flex: 1 1 0;
|
|
137
|
+
min-width: 0;
|
|
124
138
|
height: 100%;
|
|
125
139
|
background: var(--tm-column-color);
|
|
126
140
|
border-radius: calc(var(--tm-border-radius) / 2);
|
package/dist/table-minimap.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var R=Object.defineProperty;var X=(u,t,e)=>t in u?R(u,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):u[t]=e;var n=(u,t,e)=>X(u,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const A={mode:"columns",height:40,position:"bottom",fixedWidth:300,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,"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,"focusedColumn",-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 r=o.colSpan||1,s=o.offsetWidth;for(let a=0;a<r;a++){const l=s/r;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.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(t=>{const e=document.createElement("div");e.className="tm-column",e.style.width=`${t.widthPercent}%`,this.columnsEl.appendChild(e)}),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;this.minimapEl.style.bottom=`${o}px`,this.minimapEl.style.right=`${o}px`,this.minimapEl.style.marginTop="0"}}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 m;const t=((m=this.minimapEl)==null?void 0:m.offsetWidth)??0,e=this.zoomState.level,i=this.columns.length,o=1/e,r=i*o,s=r>0?t/r:0;let a=0;if(e>1&&this.scrollContainer){const{scrollLeft:p,scrollWidth:E,clientWidth:g}=this.scrollContainer,c=Math.max(E-g,1);a=p/c*(1-o)}const l=a*i,d=Math.floor(l),v=Math.min(Math.ceil(l+r)+1,i),f=-(l-d)*s;return{width:t,zoom:e,numCols:i,visibleRatio:o,visibleCols:r,cellWidth:s,panX:a,startColFloat:l,startCol:d,endCol:v,xOffset:f}}getColumnAtX(t){const{width:e,numCols:i,panX:o,visibleRatio:r}=this.getCanvasMetrics();if(i===0||e===0)return-1;const s=t/e,a=o+s*r,l=Math.floor(a*i);return Math.max(0,Math.min(i-1,l))}updateViewport(){if(!this.viewportEl||!this.minimapEl)return;if(this.options.mode==="canvas"){if(this.focusedColumn>=0&&this.columns.length>0){const{cellWidth:r,startColFloat:s}=this.getCanvasMetrics(),a=(this.focusedColumn-s)*r;this.viewportEl.style.cssText=`width:${r}px;left:${a}px;display:block`}else 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 M,P,L,D;if(!this.canvasCtx)return;const i=this.canvasCtx,{width:o,numCols:r,cellWidth:s,startCol:a,endCol:l,xOffset:d}=t,v=Array.from(this.table.querySelectorAll("tr")),f=v.length;if(f===0||r===0)return;const m=Math.min(e*.15,30),p=(e-m)/f,E=Math.min(p*.6,s*.15,14),g=Math.min(m*.6,s*.15,14),c={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=c.bg,i.fillRect(0,0,o,e),i.fillStyle=c.headerBg,i.fillRect(0,0,o,m);const w=this.table.querySelector("thead tr")||v[0],y=w?Array.from(w.querySelectorAll("th, td")):[];i.font=`bold ${g}px system-ui, sans-serif`,i.textBaseline="middle";for(let h=a;h<l;h++){const b=d+(h-a)*s;if(b+s<0||b>o)continue;i.strokeStyle=c.border,i.lineWidth=1,i.strokeRect(b,0,s,m);const C=((P=(M=y[h])==null?void 0:M.textContent)==null?void 0:P.trim())||`Col ${h+1}`;i.fillStyle=c.headerText,i.save(),i.beginPath(),i.rect(b+2,0,s-4,m),i.clip(),i.fillText(C,b+4,m/2),i.restore()}i.font=`${E}px system-ui, sans-serif`;for(let h=0;h<v.length;h++){const b=v[h];if(b.closest("thead"))continue;const C=m+h*p;if(C+p<0||C>e)continue;h%2===1&&(i.fillStyle=c.altRow,i.fillRect(0,C,o,p));const H=Array.from(b.querySelectorAll("th, td"));for(let S=a;S<l;S++){const x=d+(S-a)*s;if(x+s<0||x>o)continue;i.strokeStyle=c.border,i.lineWidth=.5,i.strokeRect(x,C,s,p);const k=(D=(L=H[S])==null?void 0:L.textContent)==null?void 0:D.trim();k&&(i.fillStyle=c.text,i.save(),i.beginPath(),i.rect(x+2,C,s-4,p),i.clip(),i.fillText(k,x+4,C+p/2),i.restore())}}if(this.hoveredColumn>=a&&this.hoveredColumn<l){const h=d+(this.hoveredColumn-a)*s;i.fillStyle=c.hoverFill,i.fillRect(h,0,s,e),i.strokeStyle=c.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.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.isDragging||this.isPanning||this.wasPanning||t.target===this.viewportEl)return;const{scrollWidth:e,clientWidth:i}=this.scrollContainer,o=this.columns.length;if(this.hoveredColumn>=0&&o>0){this.focusedColumn=this.hoveredColumn;const E=e/o,c=(this.hoveredColumn+.5)*E-i/2,w=e-i,y=Math.max(0,Math.min(w,c));this.scrollContainer.scrollTo({left:y,behavior:"smooth"}),this.updateViewport();return}const r=this.minimapEl.getBoundingClientRect(),a=(t.clientX-r.left)/r.width,l=this.zoomState.level;let d;if(l>1){const g=this.scrollContainer.scrollLeft/Math.max(e-i,1),c=1/l;d=g*(1-c)+a*c}else d=a;const f=d*e-i/2,m=e-i,p=Math.max(0,Math.min(m,f));this.scrollContainer.scrollTo({left:p,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 a=t.clientX-this.panStartX,l=this.minimapEl.offsetWidth,{scrollWidth:d,clientWidth:v}=this.scrollContainer,f=d-v,m=a/l*f*this.zoomState.level,p=this.dragStartScrollLeft+m;this.scrollContainer.scrollLeft=Math.max(0,Math.min(f,p)),this.updateScrollState(),this.updateViewport(),this.render();return}if(!this.isDragging||!this.minimapEl||!this.scrollContainer)return;t.preventDefault();const e=t.clientX-this.dragStartX,i=this.minimapEl.offsetWidth,o=this.scrollContainer.scrollWidth-this.scrollContainer.clientWidth,r=e/i*o,s=this.dragStartScrollLeft+r;this.scrollContainer.scrollLeft=Math.max(0,Math.min(o,s)),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")return;t.preventDefault();const e=-t.deltaY*this.options.zoomSpeed,i=Math.max(this.options.minZoom,Math.min(this.options.maxZoom,this.zoomState.level+e));this.zoomState={level:i,panX:0,isMinZoom:i<=this.options.minZoom,isMaxZoom:i>=this.options.maxZoom},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.clearCompactCollapseTimer(),this.applyCompactDimensions(!1),this.render())}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(t=>{const e=document.createElement("div");e.className="tm-column",e.style.width=`${t.widthPercent}%`,this.columnsEl.appendChild(e)})),this.rafId=null}))}onTableMutation(){this.isDestroyed||(this.detectColumns(),this.updateScrollState(),this.render(),this.options.mode==="columns"&&this.columnsEl&&(this.columnsEl.innerHTML="",this.columns.forEach(t=>{const e=document.createElement("div");e.className="tm-column",e.style.width=`${t.widthPercent}%`,this.columnsEl.appendChild(e)})))}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((r,s)=>r+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(t=>{const e=document.createElement("div");e.className="tm-column",e.style.width=`${t.widthPercent}%`,this.columnsEl.appendChild(e)})))}getZoomState(){return{...this.zoomState}}setZoom(t,e){if(this.isDestroyed||this.options.mode!=="canvas")return;const i=Math.max(this.options.minZoom,Math.min(this.options.maxZoom,t)),r=1-1/i;let s=e!==void 0?e:this.zoomState.panX;s=Math.max(0,Math.min(r,s)),this.zoomState={level:i,panX:i>1?s:0,isMinZoom:i<=this.options.minZoom,isMaxZoom:i>=this.options.maxZoom},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,a=i/s,l=o/i;this.setZoom(a,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;box-shadow:0 4px 12px #00000026;border-radius:8px}.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:.92;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-shrink: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 z=!1;function W(){if(z||typeof document>"u")return;const u=document.createElement("style");u.id="table-minimap-styles",u.textContent=$,document.head.appendChild(u),z=!0}W();exports.TableMinimap=Z;exports.injectStyles=W;
|
|
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;
|
|
2
2
|
//# sourceMappingURL=table-minimap.cjs.map
|