draw-table-vue 0.7.0 → 0.8.0

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/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "draw-table-vue",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "main": "./dist/draw-table.umd.js",
5
5
  "module": "./dist/draw-table.es.js",
6
- "types": "./dist/draw-table-vue.d.ts",
6
+ "types": "./dist/draw-table.d.ts",
7
7
  "exports": {
8
8
  ".": {
9
- "types": "./dist/draw-table-vue.d.ts",
9
+ "types": "./dist/draw-table.d.ts",
10
10
  "import": "./dist/draw-table.es.js",
11
11
  "require": "./dist/draw-table.umd.js",
12
12
  "default": "./dist/draw-table.es.js"
@@ -1 +0,0 @@
1
- .canvas-table-container[data-v-34fbfef2]{width:100%;height:100%;border:1px solid #ebeef5;box-sizing:border-box}.canvas-wrapper[data-v-34fbfef2]{background:#fff}.scrollbar[data-v-34fbfef2]{position:absolute;overflow:auto;z-index:10}.scrollbar.horizontal[data-v-34fbfef2]{bottom:0;left:0;right:0;height:12px}.scrollbar.vertical[data-v-34fbfef2]{top:0;right:0;bottom:0;width:12px}.scrollbar[data-v-34fbfef2]::-webkit-scrollbar{width:8px;height:8px}.scrollbar[data-v-34fbfef2]::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:4px}.scrollbar[data-v-34fbfef2]::-webkit-scrollbar-thumb:hover{background:#a8a8a8}.table-overlays[data-v-34fbfef2]{z-index:5}.edit-btn[data-v-34fbfef2]{width:20px;height:20px;background:#fff;border:1px solid #dcdfe6;border-radius:4px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:#409eff;box-shadow:0 2px 4px #0000001a}.edit-btn[data-v-34fbfef2]:hover{background:#f5f7fa}.header-menu-overlay[data-v-34fbfef2]{position:absolute;inset:0;pointer-events:auto;z-index:20}.header-menu[data-v-34fbfef2]{background:#fff;border:1px solid #ebeef5;border-radius:4px;box-shadow:0 2px 12px #0000001a;padding:5px 0;min-width:120px}.menu-item[data-v-34fbfef2]{padding:8px 12px;cursor:pointer;display:flex;align-items:center;gap:8px;font-size:14px}.menu-item[data-v-34fbfef2]:hover{background:#f5f7fa;color:#409eff}.edit-dialog-popover[data-v-34fbfef2]{background:#fff;border-radius:4px;width:300px;box-shadow:0 2px 12px #0000001a;border:1px solid #ebeef5;display:flex;flex-direction:column;z-index:2000}.popover-click-mask[data-v-34fbfef2]{position:fixed;inset:0;z-index:1999}.edit-dialog-content[data-v-34fbfef2]{padding:12px}.edit-dialog-footer[data-v-34fbfef2]{padding:8px 12px;border-top:1px solid #ebeef5;display:flex;justify-content:flex-end;gap:8px}button.small[data-v-34fbfef2]{padding:4px 12px;font-size:12px}button.primary[data-v-34fbfef2]{background:#409eff;color:#fff;border-color:#409eff}
package/dist/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export {}
package/dist/index.es.js DELETED
@@ -1,753 +0,0 @@
1
- import { defineComponent as J, ref as k, shallowRef as vt, computed as M, onMounted as gt, onUnmounted as mt, watch as O, openBlock as P, createElementBlock as z, createElementVNode as H, withModifiers as D, normalizeStyle as T, createCommentVNode as I, Fragment as U, renderList as q, toDisplayString as G, createBlock as Q, resolveDynamicComponent as wt, Teleport as pt, createVNode as yt, unref as Ct, h as B } from "vue";
2
- class Rt {
3
- ctx;
4
- canvas;
5
- columns = [];
6
- data = [];
7
- options = {
8
- rowHeight: 40,
9
- headerHeight: 48,
10
- border: !0,
11
- stripe: !0,
12
- multiSelect: !1,
13
- fixedHeader: !0,
14
- renderExpand: () => null,
15
- spanMethod: () => {
16
- }
17
- };
18
- scrollX = 0;
19
- scrollY = 0;
20
- width = 0;
21
- height = 0;
22
- // Layout info
23
- columnPositions = [];
24
- rowOffsets = [];
25
- totalWidth = 0;
26
- totalHeight = 0;
27
- fixedLeftWidth = 0;
28
- summaryRows = [];
29
- expandedRowKeys = /* @__PURE__ */ new Set();
30
- selectedRowKeys = /* @__PURE__ */ new Set();
31
- imageCache = /* @__PURE__ */ new Map();
32
- hoverHeaderIndex = -1;
33
- flattenedColumns = [];
34
- columnLevels = 0;
35
- constructor(t) {
36
- this.canvas = t;
37
- const i = t.getContext("2d");
38
- if (!i) throw new Error("Could not get canvas context");
39
- this.ctx = i;
40
- }
41
- destroy() {
42
- this.imageCache.forEach((t) => {
43
- t.onload = null, t.onerror = null, t.src = "";
44
- }), this.imageCache.clear(), this.data = [], this.columns = [], this.summaryRows = [];
45
- }
46
- setExpandedRows(t) {
47
- this.expandedRowKeys = new Set(t), this.calculateLayout(), this.render();
48
- }
49
- setData(t) {
50
- this.data = t, this.calculateLayout(), this.render();
51
- }
52
- setColumns(t) {
53
- this.columns = t, this.flattenColumns(), this.calculateLayout(), this.render();
54
- }
55
- flattenColumns() {
56
- this.flattenedColumns = [], this.columnLevels = 0;
57
- const t = (s, r = 0) => {
58
- this.columnLevels = Math.max(this.columnLevels, r + 1), s.forEach((o) => {
59
- o.children && o.children.length > 0 ? t(o.children, r + 1) : this.flattenedColumns.push(o);
60
- });
61
- };
62
- t(this.columns);
63
- const i = 40;
64
- this.columnLevels > 1 ? this.options.headerHeight = this.columnLevels * i : this.options.headerHeight = 48;
65
- }
66
- setOptions(t) {
67
- this.options = { ...this.options, ...t }, this.calculateLayout(), this.render();
68
- }
69
- resize(t, i) {
70
- this.width = t, this.height = i;
71
- const s = window.devicePixelRatio || 1;
72
- this.canvas.width = t * s, this.canvas.height = i * s, this.canvas.style.width = `${t}px`, this.canvas.style.height = `${i}px`, this.ctx.resetTransform(), this.ctx.scale(s, s), this.render();
73
- }
74
- scrollTo(t, i) {
75
- this.scrollX = t, this.scrollY = i, this.render();
76
- }
77
- calculateLayout() {
78
- let t = 0;
79
- this.columnPositions = [0];
80
- let i = 0;
81
- this.flattenedColumns.forEach((o) => {
82
- const l = o.width || 100;
83
- t += l, this.columnPositions.push(t), (o.fixed === "left" || o.fixed === !0) && (i = t);
84
- }), this.totalWidth = t, this.fixedLeftWidth = i;
85
- let s = 0;
86
- this.rowOffsets = [0];
87
- const { rowHeight: r } = this.options;
88
- this.data.forEach((o) => {
89
- s += r, this.expandedRowKeys.has(o.id) && (s += r * 3), this.rowOffsets.push(s);
90
- }), this.totalHeight = s, this.calculateSummaries();
91
- }
92
- getRowRange(t = 20) {
93
- const { headerHeight: i } = this.options, s = this.summaryRows.length * this.options.rowHeight, r = this.height - i - s, o = this.scrollY, l = o + r;
94
- let n = 0;
95
- for (; n < this.rowOffsets.length && (this.rowOffsets[n + 1] ?? 0) < o; )
96
- n++;
97
- let a = n;
98
- for (; a < this.rowOffsets.length && (this.rowOffsets[a] ?? 0) < l; )
99
- a++;
100
- return {
101
- startRow: Math.max(0, n - t),
102
- endRow: Math.min(this.data.length, a + 1)
103
- };
104
- }
105
- calculateSummaries() {
106
- this.summaryRows = [];
107
- const t = /* @__PURE__ */ new Map();
108
- this.flattenedColumns.forEach((i, s) => {
109
- i.summary && i.summary.forEach((r) => {
110
- try {
111
- const o = r(this.data);
112
- if (o && o.label) {
113
- const { label: l, value: n } = o;
114
- t.has(l) || t.set(l, new Array(this.flattenedColumns.length).fill("")), t.get(l)[s] = n;
115
- }
116
- } catch (o) {
117
- console.error("Summary calculation error:", o);
118
- }
119
- });
120
- }), t.forEach((i, s) => {
121
- i[0] = s, this.summaryRows.push(i);
122
- });
123
- }
124
- render() {
125
- this.ctx.clearRect(0, 0, this.width, this.height), this.drawBody(), this.drawFixedLeftBody(), this.drawHeader(), this.drawSummaryRows();
126
- }
127
- getColumnWidth(t) {
128
- return t.children && t.children.length > 0 ? t.children.reduce((s, r) => s + this.getColumnWidth(r), 0) : t.width || 100;
129
- }
130
- isColumnFixed(t) {
131
- return t.fixed === "left" || t.fixed === "right" || t.fixed === !0 ? !0 : t.children && t.children.length > 0 ? t.children.some((i) => this.isColumnFixed(i)) : !1;
132
- }
133
- drawHeader() {
134
- const { headerHeight: t } = this.options, i = this.columnLevels > 1 ? 40 : t;
135
- this.ctx.save(), this.ctx.fillStyle = "#f5f7fa", this.ctx.fillRect(0, 0, this.width, t);
136
- const s = (r, o, l, n, a) => {
137
- let e = o;
138
- r.forEach((c) => {
139
- const f = this.getColumnWidth(c), d = this.isColumnFixed(c);
140
- if (a !== d) {
141
- e += f;
142
- return;
143
- }
144
- const v = !c.children || c.children.length === 0, g = v ? (this.columnLevels - n) * i : i, R = a ? e : e - this.scrollX;
145
- (a || R + f > this.fixedLeftWidth && R < this.width) && (a || (this.ctx.save(), this.ctx.beginPath(), this.ctx.rect(this.fixedLeftWidth, 0, this.width - this.fixedLeftWidth, t), this.ctx.clip()), this.drawHeaderCell(c, R, f, g, l, v), a || this.ctx.restore()), c.children && c.children.length > 0 && s(c.children, e, l + i, n + 1, a), e += f;
146
- });
147
- };
148
- s(this.columns, 0, 0, 0, !1), s(this.columns, 0, 0, 0, !0), this.ctx.restore();
149
- }
150
- setHoverHeader(t) {
151
- this.hoverHeaderIndex !== t && (this.hoverHeaderIndex = t, this.render());
152
- }
153
- setSelectedRows(t) {
154
- this.selectedRowKeys = new Set(t), this.render();
155
- }
156
- drawHeaderCell(t, i, s, r, o, l) {
157
- if (this.ctx.save(), this.ctx.beginPath(), this.ctx.rect(i, o, s, r), this.ctx.clip(), this.ctx.fillStyle = "#f5f7fa", this.ctx.fillRect(i, o, s, r), this.options.border && (this.ctx.strokeStyle = "#ebeef5", this.ctx.lineWidth = 1, this.ctx.strokeRect(i + 0.5, o + 0.5, s, r)), t.type === "selection") {
158
- const n = this.data.length > 0 && this.selectedRowKeys.size === this.data.length;
159
- this.drawCheckboxCell(n, i, o, s, r, "center");
160
- } else {
161
- this.ctx.fillStyle = "#303133", this.ctx.font = "bold 14px sans-serif", this.ctx.textBaseline = "middle";
162
- const n = t.align || (l ? "left" : "center");
163
- this.ctx.textAlign = n;
164
- let a = i + 10;
165
- n === "center" && (a = i + s / 2), n === "right" && (a = i + s - 24);
166
- const e = t.title || "";
167
- if (this.ctx.fillText(e, a, o + r / 2), l && t.type !== "selection" && t.type !== "expand") {
168
- const c = this.flattenedColumns.indexOf(t);
169
- if (this.hoverHeaderIndex === c) {
170
- this.ctx.fillStyle = "#909399", this.ctx.beginPath();
171
- const f = i + s - 18, d = o + r / 2;
172
- this.ctx.arc(f, d - 4, 1.5, 0, Math.PI * 2), this.ctx.arc(f, d, 1.5, 0, Math.PI * 2), this.ctx.arc(f, d + 4, 1.5, 0, Math.PI * 2), this.ctx.fill();
173
- }
174
- }
175
- }
176
- this.ctx.restore();
177
- }
178
- getHeaderAt(t, i) {
179
- const { headerHeight: s } = this.options;
180
- if (i > s) return null;
181
- const r = this.columnLevels > 1 ? 40 : s, o = (n, a, e, c) => {
182
- let f = a;
183
- for (const d of n) {
184
- const v = this.isColumnFixed(d);
185
- if (c !== v) {
186
- f += this.getColumnWidth(d);
187
- continue;
188
- }
189
- const g = this.getColumnWidth(d), R = !d.children || d.children.length === 0, y = R ? (this.columnLevels - e) * r : r, C = e * r, S = c ? f : f - this.scrollX;
190
- if (!c && S < this.fixedLeftWidth) {
191
- f += g;
192
- continue;
193
- }
194
- if (t >= S && t < S + g && i >= C && i < C + y) {
195
- const w = R && d.type !== "selection" && d.type !== "expand" && t >= S + g - 24;
196
- return {
197
- column: d,
198
- rect: { x: S, y: C, width: g, height: y },
199
- isMenu: w
200
- };
201
- }
202
- if (d.children && d.children.length > 0) {
203
- const w = o(d.children, f, e + 1, c);
204
- if (w) return w;
205
- }
206
- f += g;
207
- }
208
- return null;
209
- }, l = o(this.columns, 0, 0, !0);
210
- return l || o(this.columns, 0, 0, !1);
211
- }
212
- drawBody() {
213
- const { headerHeight: t } = this.options, { startRow: i, endRow: s } = this.getRowRange(this.height), r = this.summaryRows.length * this.options.rowHeight;
214
- this.ctx.save(), this.ctx.beginPath(), this.ctx.rect(this.fixedLeftWidth, t, this.width - this.fixedLeftWidth, this.height - t - r), this.ctx.clip();
215
- const o = /* @__PURE__ */ new Set(), l = [];
216
- for (let n = i; n < s; n++) {
217
- const a = this.data[n];
218
- if (!a) continue;
219
- const e = (this.rowOffsets[n] ?? 0) - this.scrollY + t, c = (this.rowOffsets[n + 1] ?? 0) - (this.rowOffsets[n] ?? 0), f = n % 2 === 1 && this.options.stripe ? "#fafafa" : "#fff";
220
- if (this.flattenedColumns.forEach((d, v) => {
221
- if (d.fixed === "left" || d.fixed === !0 || o.has(`${n},${v}`)) return;
222
- const g = (this.columnPositions[v] ?? 0) - this.scrollX, R = (this.columnPositions[v + 1] ?? 0) - (this.columnPositions[v] ?? 0), y = this.options.spanMethod({ row: n, column: d, rowIndex: n, columnIndex: v });
223
- if (y) {
224
- const { rowspan: C, colspan: S } = y;
225
- if (C === 0 || S === 0) return;
226
- const w = (this.columnPositions[v + S] ?? this.totalWidth) - (this.columnPositions[v] ?? 0), L = (this.rowOffsets[n + C] ?? this.totalHeight) - (this.rowOffsets[n] ?? 0);
227
- for (let b = 0; b < C; b++)
228
- for (let Y = 0; Y < S; Y++)
229
- o.add(`${n + b},${v + Y}`);
230
- l.push({ col: d, val: a[d.key || ""], x: g, y: e, w, h: L, r: n, c: v, bgColor: f });
231
- } else
232
- this.ctx.fillStyle = f, this.ctx.fillRect(g, e, R, this.options.rowHeight), this.drawCell(d, a[d.key || ""], g, e, R, this.options.rowHeight, n), this.options.border && (this.ctx.strokeStyle = "#ebeef5", this.ctx.strokeRect(g + 0.5, e + 0.5, R, this.options.rowHeight));
233
- }), this.expandedRowKeys.has(a.id)) {
234
- const d = e + this.options.rowHeight, v = c - this.options.rowHeight;
235
- this.ctx.fillStyle = "#fdfdfd", this.ctx.fillRect(0, d, this.width, v), this.options.border && (this.ctx.strokeStyle = "#ebeef5", this.ctx.beginPath(), this.ctx.moveTo(0, d), this.ctx.lineTo(this.width, d), this.ctx.stroke()), this.drawExpandPlaceholder(a, this.fixedLeftWidth - this.scrollX, d, this.totalWidth - this.fixedLeftWidth, v);
236
- }
237
- }
238
- l.forEach(({ col: n, val: a, x: e, y: c, w: f, h: d, r: v, bgColor: g }) => {
239
- this.ctx.fillStyle = g, this.ctx.fillRect(e, c, f, d), this.drawCell(n, a, e, c, f, d, v), this.options.border && (this.ctx.strokeStyle = "#ebeef5", this.ctx.strokeRect(e + 0.5, c + 0.5, f, d));
240
- }), this.ctx.restore();
241
- }
242
- drawFixedLeftBody() {
243
- const { headerHeight: t } = this.options, { startRow: i, endRow: s } = this.getRowRange(this.height), r = this.summaryRows.length * this.options.rowHeight;
244
- this.ctx.save(), this.ctx.beginPath(), this.ctx.rect(0, t, this.fixedLeftWidth, this.height - t - r), this.ctx.clip();
245
- const o = /* @__PURE__ */ new Set(), l = [];
246
- for (let n = i; n < s; n++) {
247
- const a = this.data[n];
248
- if (!a) continue;
249
- const e = (this.rowOffsets[n] ?? 0) - this.scrollY + t, c = n % 2 === 1 && this.options.stripe ? "#fafafa" : "#fff";
250
- this.flattenedColumns.forEach((f, d) => {
251
- if (!(f.fixed === "left" || f.fixed === !0) || o.has(`${n},${d}`)) return;
252
- const v = this.columnPositions[d] ?? 0, g = (this.columnPositions[d + 1] ?? 0) - (this.columnPositions[d] ?? 0), R = this.options.spanMethod({ row: n, column: f, rowIndex: n, columnIndex: d });
253
- if (R) {
254
- const { rowspan: y, colspan: C } = R;
255
- if (y === 0 || C === 0) return;
256
- const S = (this.columnPositions[d + C] ?? this.fixedLeftWidth) - (this.columnPositions[d] ?? 0), w = (this.rowOffsets[n + y] ?? this.totalHeight) - (this.rowOffsets[n] ?? 0);
257
- for (let L = 0; L < y; L++)
258
- for (let b = 0; b < C; b++)
259
- o.add(`${n + L},${d + b}`);
260
- l.push({ col: f, val: a[f.key || ""], x: v, y: e, w: S, h: w, r: n, c: d, bgColor: c });
261
- } else
262
- this.ctx.fillStyle = c, this.ctx.fillRect(v, e, g, this.options.rowHeight), this.drawCell(f, a[f.key || ""], v, e, g, this.options.rowHeight, n), this.options.border && (this.ctx.strokeStyle = "#ebeef5", this.ctx.strokeRect(v + 0.5, e + 0.5, g, this.options.rowHeight));
263
- });
264
- }
265
- l.forEach(({ col: n, val: a, x: e, y: c, w: f, h: d, r: v, bgColor: g }) => {
266
- this.ctx.fillStyle = g, this.ctx.fillRect(e, c, f, d), this.drawCell(n, a, e, c, f, d, v), this.options.border && (this.ctx.strokeStyle = "#ebeef5", this.ctx.strokeRect(e + 0.5, c + 0.5, f, d));
267
- }), this.ctx.restore();
268
- }
269
- drawExpandPlaceholder(t, i, s, r, o) {
270
- this.ctx.save(), this.ctx.fillStyle = "#fef0f0", this.ctx.fillRect(i, s, r, o), this.ctx.fillStyle = "#f56c6c", this.ctx.font = "italic 12px sans-serif", this.ctx.textAlign = "center", this.ctx.fillText(`Expanded content for row ${t.id} (Rendered via h function in overlay)`, i + r / 2, s + o / 2), this.ctx.restore();
271
- }
272
- drawSummaryRows() {
273
- if (this.summaryRows.length === 0) return;
274
- const { rowHeight: t } = this.options, i = this.summaryRows.length * t, s = this.height - i;
275
- this.ctx.save(), this.ctx.fillStyle = "#fdf6ec", this.ctx.fillRect(0, s, this.width, i);
276
- let r = 0;
277
- for (let o = 0; o < this.flattenedColumns.length; o++) {
278
- const l = this.flattenedColumns[o];
279
- if (l && (l.type === "selection" || l.type === "expand" || l.key === "id"))
280
- r++;
281
- else
282
- break;
283
- }
284
- r === 0 && (r = 1), this.summaryRows.forEach((o, l) => {
285
- const n = s + l * t;
286
- this.ctx.save(), this.ctx.beginPath(), this.ctx.rect(this.fixedLeftWidth, n, this.width - this.fixedLeftWidth, t), this.ctx.clip(), this.flattenedColumns.forEach((a, e) => {
287
- if (a.fixed === "left" || a.fixed === !0 || e < r) return;
288
- const c = (this.columnPositions[e] ?? 0) - this.scrollX, f = (this.columnPositions[e + 1] ?? 0) - (this.columnPositions[e] ?? 0);
289
- this.drawTextCell(o[e], c, n, f, t, a.align), this.options.border && (this.ctx.strokeStyle = "#ebeef5", this.ctx.strokeRect(c + 0.5, n + 0.5, f, t));
290
- }), this.ctx.restore(), this.flattenedColumns.forEach((a, e) => {
291
- if (a.fixed === "left" || a.fixed === !0) {
292
- const c = this.columnPositions[e] ?? 0, f = (this.columnPositions[e + 1] ?? 0) - (this.columnPositions[e] ?? 0);
293
- if (e === 0) {
294
- const d = (this.columnPositions[r] ?? this.fixedLeftWidth) - (this.columnPositions[0] ?? 0);
295
- this.ctx.save(), this.ctx.font = "bold 13px sans-serif", this.ctx.fillStyle = "#e6a23c", this.drawTextCell(o[0], c, n, d, t, "center"), this.ctx.restore(), this.options.border && (this.ctx.strokeStyle = "#ebeef5", this.ctx.strokeRect(c + 0.5, n + 0.5, d, t));
296
- } else {
297
- if (e < r)
298
- return;
299
- this.drawTextCell(o[e], c, n, f, t, a.align), this.options.border && (this.ctx.strokeStyle = "#ebeef5", this.ctx.strokeRect(c + 0.5, n + 0.5, f, t));
300
- }
301
- }
302
- });
303
- }), this.ctx.restore();
304
- }
305
- drawCell(t, i, s, r, o, l, n) {
306
- if (this.ctx.save(), this.ctx.beginPath(), this.ctx.rect(s, r, o, l), this.ctx.clip(), t.renderCell)
307
- this.drawTextCell(i, s, r, o, l, t.align);
308
- else
309
- switch (t.type) {
310
- case "expand":
311
- this.drawExpandButton(s + (o - 16) / 2, r + (this.options.rowHeight - 16) / 2, this.expandedRowKeys.has(this.data[n]?.id ?? ""));
312
- break;
313
- case "selection":
314
- const a = this.selectedRowKeys.has(this.data[n]?.id ?? "");
315
- this.drawCheckboxCell(a, s, r, o, this.options.rowHeight, "center");
316
- break;
317
- case "image":
318
- this.drawImageCell(i, s, r, o, l, t.align);
319
- break;
320
- case "checkbox":
321
- this.drawCheckboxCell(i, s, r, o, l, t.align);
322
- break;
323
- case "radio":
324
- this.drawRadioCell(i, s, r, o, l, t.align);
325
- break;
326
- case "switch":
327
- this.drawSwitchCell(i, s, r, o, l, t.align);
328
- break;
329
- case "color-picker":
330
- this.drawColorPickerCell(i, s, r, o, l, t.align);
331
- break;
332
- case "tags":
333
- this.drawTagsCell(i, s, r, o, l);
334
- break;
335
- default:
336
- this.drawTextCell(i, s, r, o, l, t.align);
337
- break;
338
- }
339
- this.ctx.restore();
340
- }
341
- drawExpandButton(t, i, s) {
342
- this.ctx.save(), this.ctx.translate(t + 8, i + 8), s && this.ctx.rotate(Math.PI / 2), this.ctx.strokeStyle = "#909399", this.ctx.lineWidth = 2, this.ctx.beginPath(), this.ctx.moveTo(-3, -5), this.ctx.lineTo(3, 0), this.ctx.lineTo(-3, 5), this.ctx.stroke(), this.ctx.restore();
343
- }
344
- drawTextCell(t, i, s, r, o, l) {
345
- this.ctx.fillStyle = "#606266", this.ctx.font = "14px sans-serif", this.ctx.textAlign = l || "left", this.ctx.textBaseline = "middle";
346
- let n = i + 10;
347
- l === "center" && (n = i + r / 2), l === "right" && (n = i + r - 10);
348
- const a = t == null ? "" : String(t);
349
- this.ctx.fillText(a, n, s + o / 2);
350
- }
351
- drawImageCell(t, i, s, r, o, l) {
352
- if (!t) return;
353
- const n = String(t), a = Math.min(r, o) - 10;
354
- let e = i + 5;
355
- l === "center" && (e = i + (r - a) / 2), l === "right" && (e = i + r - a - 5);
356
- let c = this.imageCache.get(n);
357
- c || (c = new Image(), c.src = n, this.imageCache.set(n, c), c.onload = () => this.render(), c.onerror = () => {
358
- console.error(`Failed to load image: ${n}`), this.imageCache.delete(n);
359
- }), c.complete && c.naturalWidth > 0 ? this.ctx.drawImage(c, e, s + (o - a) / 2, a, a) : (this.ctx.fillStyle = "#f5f7fa", this.ctx.fillRect(e, s + (o - a) / 2, a, a));
360
- }
361
- drawCheckboxCell(t, i, s, r, o, l) {
362
- let a = i + 10;
363
- l === "center" && (a = i + (r - 16) / 2), l === "right" && (a = i + r - 16 - 10);
364
- const e = s + (o - 16) / 2;
365
- this.ctx.strokeStyle = t ? "#409eff" : "#dcdfe6", this.ctx.fillStyle = t ? "#409eff" : "#fff", this.ctx.lineWidth = 1, this.ctx.strokeRect(a + 0.5, e + 0.5, 16, 16), t && (this.ctx.fillRect(a + 1, e + 1, 15, 15), this.ctx.strokeStyle = "#fff", this.ctx.beginPath(), this.ctx.moveTo(a + 4, e + 8), this.ctx.lineTo(a + 7, e + 11), this.ctx.lineTo(a + 12, e + 5), this.ctx.stroke());
366
- }
367
- drawRadioCell(t, i, s, r, o, l) {
368
- let a = i + 10;
369
- l === "center" && (a = i + (r - 16) / 2), l === "right" && (a = i + r - 16 - 10);
370
- const e = s + (o - 16) / 2, c = a + 16 / 2, f = e + 16 / 2;
371
- this.ctx.strokeStyle = t ? "#409eff" : "#dcdfe6", this.ctx.fillStyle = "#fff", this.ctx.beginPath(), this.ctx.arc(c, f, 16 / 2, 0, Math.PI * 2), this.ctx.stroke(), this.ctx.fill(), t && (this.ctx.fillStyle = "#409eff", this.ctx.beginPath(), this.ctx.arc(c, f, 16 / 4, 0, Math.PI * 2), this.ctx.fill());
372
- }
373
- drawSwitchCell(t, i, s, r, o, l) {
374
- let e = i + 10;
375
- l === "center" && (e = i + (r - 32) / 2), l === "right" && (e = i + r - 32 - 10);
376
- const c = s + (o - 16) / 2;
377
- this.ctx.fillStyle = t ? "#13ce66" : "#ff4949", this.ctx.beginPath(), this.ctx.roundRect?.(e, c, 32, 16, 16 / 2), this.ctx.fill(), this.ctx.fillStyle = "#fff", this.ctx.beginPath();
378
- const f = t ? e + 32 - 16 + 2 : e + 2;
379
- this.ctx.arc(f + 12 / 2, c + 16 / 2, 12 / 2, 0, Math.PI * 2), this.ctx.fill();
380
- }
381
- drawColorPickerCell(t, i, s, r, o, l) {
382
- let a = i + 10;
383
- l === "center" && (a = i + (r - 20) / 2), l === "right" && (a = i + r - 20 - 10);
384
- const e = s + (o - 20) / 2;
385
- this.ctx.fillStyle = t || "#000", this.ctx.fillRect(a, e, 20, 20), this.ctx.strokeStyle = "#dcdfe6", this.ctx.strokeRect(a + 0.5, e + 0.5, 20, 20);
386
- }
387
- drawTagsCell(t, i, s, r, o) {
388
- if (!Array.isArray(t)) return;
389
- let l = i + 5;
390
- const n = 20, a = 5, e = 12;
391
- t.forEach((c) => {
392
- const f = String(c);
393
- this.ctx.font = `${e}px sans-serif`;
394
- const v = this.ctx.measureText(f).width + a * 2;
395
- if (l + v > i + r - 5) return;
396
- const g = s + (o - n) / 2;
397
- this.ctx.fillStyle = "#ecf5ff", this.ctx.strokeStyle = "#d9ecff", this.ctx.beginPath(), this.ctx.roundRect?.(l, g, v, n, 4), this.ctx.fill(), this.ctx.stroke(), this.ctx.fillStyle = "#409eff", this.ctx.textAlign = "center", this.ctx.fillText(f, l + v / 2, g + n - e / 2), l += v + 5;
398
- });
399
- }
400
- getCellAt(t, i) {
401
- const { headerHeight: s } = this.options;
402
- if (i < s) return null;
403
- const { startRow: r, endRow: o } = this.getRowRange(this.height);
404
- for (let l = r; l < o; l++) {
405
- const n = this.data[l];
406
- if (!n) continue;
407
- const a = (this.rowOffsets[l] ?? 0) - this.scrollY + s, e = (this.rowOffsets[l + 1] ?? 0) - (this.rowOffsets[l] ?? 0);
408
- if (i >= a && i < a + e)
409
- for (let c = 0; c < this.flattenedColumns.length; c++) {
410
- const f = this.flattenedColumns[c], d = (this.columnPositions[c + 1] ?? 0) - (this.columnPositions[c] ?? 0);
411
- let v = 0;
412
- if (f.fixed === "left" || f.fixed === !0)
413
- v = this.columnPositions[c] ?? 0;
414
- else if (v = (this.columnPositions[c] ?? 0) - this.scrollX, v < this.fixedLeftWidth) continue;
415
- if (t >= v && t < v + d) {
416
- const g = f.type === "expand", R = f.type === "selection";
417
- return {
418
- row: l,
419
- col: c,
420
- rect: { x: v, y: a, width: d, height: e },
421
- column: f,
422
- data: n,
423
- isExpandBtn: g,
424
- isSelection: R
425
- };
426
- }
427
- }
428
- }
429
- return null;
430
- }
431
- getRowOffsets() {
432
- return this.rowOffsets;
433
- }
434
- getScrollX() {
435
- return this.scrollX;
436
- }
437
- getScrollY() {
438
- return this.scrollY;
439
- }
440
- getFixedLeftWidth() {
441
- return this.fixedLeftWidth;
442
- }
443
- getTotalWidth() {
444
- return this.totalWidth;
445
- }
446
- getTotalHeight() {
447
- return this.totalHeight;
448
- }
449
- }
450
- const St = ["onClick"], bt = { class: "icon" }, kt = { class: "label" }, Ht = { class: "edit-dialog-content" }, Et = /* @__PURE__ */ J({
451
- __name: "CanvasTable",
452
- props: {
453
- columns: {},
454
- data: {},
455
- options: {}
456
- },
457
- emits: ["update:data", "select-change", "header-command"],
458
- setup(X, { emit: t }) {
459
- const i = J({
460
- props: ["vnode"],
461
- setup(h) {
462
- return () => h.vnode;
463
- }
464
- }), s = X, r = t, o = k(null), l = k(null), n = k(null), a = k(null), e = vt(null), c = k(0), f = k(0), d = k(0), v = k(0), g = k(0), R = k(0), y = k(null), C = k(null), S = k(null), w = k(/* @__PURE__ */ new Set()), L = k(/* @__PURE__ */ new Set()), b = k(null), Y = M(() => ({
465
- width: "100%",
466
- height: "100%",
467
- position: "relative",
468
- overflow: "hidden"
469
- })), Z = M(() => ({
470
- position: "absolute",
471
- top: 0,
472
- left: 0,
473
- pointerEvents: "none",
474
- width: "100%",
475
- height: "100%"
476
- })), j = M(() => {
477
- if (!y.value) return {};
478
- const { rect: h } = y.value;
479
- return {
480
- position: "absolute",
481
- left: `${h.x + h.width - 24}px`,
482
- top: `${h.y + (h.height - 20) / 2}px`,
483
- pointerEvents: "auto"
484
- };
485
- }), tt = M(() => {
486
- if (!C.value || !l.value) return {};
487
- const h = l.value.getBoundingClientRect(), { rect: x } = C.value;
488
- let u = h.top + x.y + x.height + 5, m = h.left + x.x;
489
- const p = 300;
490
- return m + p > window.innerWidth && (m = window.innerWidth - p - 20), {
491
- position: "fixed",
492
- top: `${u}px`,
493
- left: `${m}px`,
494
- zIndex: 2e3,
495
- pointerEvents: "auto"
496
- };
497
- }), et = M(() => {
498
- if (!b.value) return {};
499
- const { rect: h } = b.value;
500
- return {
501
- position: "absolute",
502
- left: `${h.x + h.width - 120}px`,
503
- top: `${h.y + h.height}px`,
504
- pointerEvents: "auto"
505
- };
506
- }), st = M(() => {
507
- if (!b.value) return [];
508
- const { column: h } = b.value, x = [
509
- {
510
- label: "Fix to Left",
511
- onCommand: (u) => {
512
- const m = s.columns.findIndex((p) => p.key === u.key);
513
- s.columns.forEach((p, E) => {
514
- E <= m && (p.fixed = "left");
515
- }), e.value?.setColumns(s.columns);
516
- }
517
- },
518
- {
519
- label: "Unfix",
520
- onCommand: (u) => {
521
- u.fixed = !1, e.value?.setColumns(s.columns);
522
- }
523
- }
524
- ];
525
- return h.renderHeaderMenu ? h.renderHeaderMenu(h, x) : x;
526
- }), it = (h) => {
527
- b.value && (h.onCommand(b.value.column), b.value = null);
528
- }, K = (h) => {
529
- if (!l.value || !e.value) return;
530
- const x = l.value.getBoundingClientRect(), u = h.clientX - x.left, m = h.clientY - x.top, p = e.value.getHeaderAt(u, m);
531
- if (p) {
532
- const E = s.columns.findIndex((W) => W.key === p.column.key);
533
- e.value.setHoverHeader(E), p.isMenu || p.column.type === "selection" ? l.value.style.cursor = "pointer" : l.value.style.cursor = "default";
534
- } else
535
- e.value.setHoverHeader(-1), l.value.style.cursor = "default";
536
- y.value = e.value.getCellAt(u, m), y.value && (y.value.isExpandBtn || y.value.isSelection) && (l.value.style.cursor = "pointer");
537
- }, V = (h) => {
538
- if (!l.value || !e.value) return;
539
- const x = l.value.getBoundingClientRect(), u = h.clientX - x.left, m = h.clientY - x.top, p = e.value.getHeaderAt(u, m);
540
- if (p) {
541
- p.isMenu ? b.value = { column: p.column, rect: p.rect } : p.column.type === "selection" && (w.value.size === s.data.length ? w.value.clear() : s.data.forEach((xt) => w.value.add(xt.id)), e.value.setSelectedRows(Array.from(w.value)), r("select-change", Array.from(w.value)));
542
- return;
543
- }
544
- const E = e.value.getCellAt(u, m);
545
- if (E) {
546
- if (E.isExpandBtn) {
547
- lt(E.data.id);
548
- return;
549
- }
550
- const W = E.data.id;
551
- if (E.isSelection) {
552
- w.value.has(W) ? w.value.delete(W) : w.value.add(W), e.value.setSelectedRows(Array.from(w.value)), r("select-change", Array.from(w.value));
553
- return;
554
- }
555
- s.options?.multiSelect ? w.value.has(W) ? w.value.delete(W) : w.value.add(W) : (w.value.clear(), w.value.add(W)), r("select-change", Array.from(w.value));
556
- }
557
- }, N = (h) => {
558
- if (!l.value || !e.value) return;
559
- const x = l.value.getBoundingClientRect(), u = h.clientX - x.left, m = h.clientY - x.top, p = e.value.getCellAt(u, m);
560
- p && p.column.renderEdit && F(p);
561
- }, F = (h) => {
562
- C.value = h, S.value = JSON.parse(JSON.stringify(h.data));
563
- }, lt = (h) => {
564
- L.value.has(h) ? L.value.delete(h) : L.value.add(h), e.value?.setExpandedRows(Array.from(L.value)), $();
565
- }, A = () => {
566
- C.value = null, S.value = null;
567
- }, nt = () => {
568
- if (C.value && S.value) {
569
- const h = C.value.data.id, x = s.data.findIndex((u) => u.id === h);
570
- if (x !== -1) {
571
- const u = [...s.data];
572
- u[x] = S.value, r("update:data", u), e.value?.setData(u);
573
- }
574
- }
575
- A();
576
- }, ot = (h) => !h.column.renderEdit || !S.value ? null : h.column.renderEdit(S.value, (x, u, m) => u && (typeof u == "string" || Array.isArray(u) || u.__v_isVNode) ? B(x, null, u) : B(x, u, m)), rt = (h) => {
577
- if (!e.value) return {};
578
- const x = s.data.findIndex((W) => W.id === h);
579
- if (x === -1) return {};
580
- const u = e.value.getRowOffsets(), m = (u[x] ?? 0) - R.value + (s.options?.headerHeight || 48), p = (u[x + 1] ?? 0) - (u[x] ?? 0) - (s.options?.rowHeight || 40), E = e.value.getFixedLeftWidth();
581
- return {
582
- position: "absolute",
583
- top: `${m + (s.options?.rowHeight || 40)}px`,
584
- left: `${E}px`,
585
- width: `${d.value - E}px`,
586
- height: `${p}px`,
587
- pointerEvents: "auto",
588
- overflow: "hidden",
589
- backgroundColor: "#fff",
590
- borderBottom: "1px solid #ebeef5",
591
- // Sync inner scrolling content
592
- display: "flex"
593
- };
594
- }, at = () => ({
595
- marginLeft: `-${g.value}px`,
596
- minWidth: `${c.value - e.value?.getFixedLeftWidth()}px`
597
- }), ct = (h) => {
598
- const x = s.data.find((u) => u.id === h);
599
- return !x || !s.options?.renderExpand ? null : B("div", { style: at() }, [
600
- s.options.renderExpand(x, (u, m, p) => m && (typeof m == "string" || Array.isArray(m) || m.__v_isVNode) ? B(u, null, m) : B(u, m, p))
601
- ]);
602
- }, ht = (h) => {
603
- const x = h.target;
604
- g.value = x.scrollLeft, e.value?.scrollTo(g.value, R.value), y.value = null;
605
- }, dt = (h) => {
606
- const x = h.target;
607
- R.value = x.scrollTop, e.value?.scrollTo(g.value, R.value), y.value = null;
608
- }, ft = (h) => {
609
- if (!a.value || !n.value) return;
610
- const x = h.deltaY, u = h.shiftKey ? h.deltaY : h.deltaX;
611
- a.value.scrollTop += x, n.value.scrollLeft += u;
612
- }, ut = (h) => {
613
- const x = h[0];
614
- if (!x || !e.value) return;
615
- const { width: u, height: m } = x.contentRect;
616
- d.value = u, v.value = m, e.value.resize(u, m), $();
617
- }, $ = () => {
618
- e.value && (c.value = e.value.getTotalWidth(), f.value = e.value.getTotalHeight());
619
- };
620
- let _ = null;
621
- return gt(() => {
622
- l.value && (e.value = new Rt(l.value), e.value.setColumns(s.columns), e.value.setData(s.data), e.value.setOptions(s.options || {}), $(), _ = new ResizeObserver(ut), o.value && _.observe(o.value), l.value.addEventListener("mousemove", K), l.value.addEventListener("mousedown", V), l.value.addEventListener("dblclick", N));
623
- }), mt(() => {
624
- _?.disconnect(), l.value?.removeEventListener("mousemove", K), l.value?.removeEventListener("mousedown", V), l.value?.removeEventListener("dblclick", N), e.value?.destroy(), e.value = null;
625
- }), O(() => s.columns, (h) => {
626
- e.value?.setColumns(h), $();
627
- }, { deep: !0 }), O(() => s.data, (h) => {
628
- e.value?.setData(h), $();
629
- }, { deep: !0 }), O(() => s.options, (h) => {
630
- h && e.value?.setOptions(h);
631
- }, { deep: !0 }), (h, x) => (P(), z("div", {
632
- class: "canvas-table-container",
633
- ref_key: "containerRef",
634
- ref: o
635
- }, [
636
- H("div", {
637
- class: "canvas-wrapper",
638
- style: T(Y.value),
639
- onWheel: D(ft, ["prevent"])
640
- }, [
641
- H("canvas", {
642
- ref_key: "canvasRef",
643
- ref: l
644
- }, null, 512),
645
- H("div", {
646
- class: "scrollbar horizontal",
647
- ref_key: "hScrollRef",
648
- ref: n,
649
- onScroll: ht
650
- }, [
651
- H("div", {
652
- style: T({ width: c.value + "px", height: "1px" })
653
- }, null, 4)
654
- ], 544),
655
- H("div", {
656
- class: "scrollbar vertical",
657
- ref_key: "vScrollRef",
658
- ref: a,
659
- onScroll: dt
660
- }, [
661
- H("div", {
662
- style: T({ height: f.value + "px", width: "1px" })
663
- }, null, 4)
664
- ], 544),
665
- H("div", {
666
- class: "table-overlays",
667
- style: T(Z.value)
668
- }, [
669
- y.value && y.value.column.renderEdit ? (P(), z("div", {
670
- key: 0,
671
- class: "edit-btn",
672
- style: T(j.value),
673
- onClick: x[0] || (x[0] = D((u) => F(y.value), ["stop"]))
674
- }, [...x[2] || (x[2] = [
675
- H("svg", {
676
- viewBox: "0 0 24 24",
677
- width: "14",
678
- height: "14"
679
- }, [
680
- H("path", {
681
- fill: "currentColor",
682
- d: "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"
683
- })
684
- ], -1)
685
- ])], 4)) : I("", !0),
686
- b.value ? (P(), z("div", {
687
- key: 1,
688
- class: "header-menu-overlay",
689
- onClick: x[1] || (x[1] = D((u) => b.value = null, ["self"]))
690
- }, [
691
- H("div", {
692
- class: "header-menu",
693
- style: T(et.value)
694
- }, [
695
- (P(!0), z(U, null, q(st.value, (u) => (P(), z("div", {
696
- key: u.label,
697
- class: "menu-item",
698
- onClick: (m) => it(u)
699
- }, [
700
- H("span", bt, G(u.icon || "•"), 1),
701
- H("span", kt, G(u.label), 1)
702
- ], 8, St))), 128))
703
- ], 4)
704
- ])) : I("", !0),
705
- (P(!0), z(U, null, q(L.value, (u) => (P(), z("div", {
706
- key: u,
707
- class: "expand-row-overlay",
708
- style: T(rt(u))
709
- }, [
710
- (P(), Q(wt(ct(u))))
711
- ], 4))), 128)),
712
- (P(), Q(pt, { to: "body" }, [
713
- C.value ? (P(), z("div", {
714
- key: 0,
715
- class: "edit-dialog-popover",
716
- style: T(tt.value)
717
- }, [
718
- H("div", Ht, [
719
- yt(Ct(i), {
720
- vnode: ot(C.value)
721
- }, null, 8, ["vnode"])
722
- ]),
723
- H("div", { class: "edit-dialog-footer" }, [
724
- H("button", {
725
- class: "small",
726
- onClick: A
727
- }, "Cancel"),
728
- H("button", {
729
- class: "small primary",
730
- onClick: nt
731
- }, "Save")
732
- ])
733
- ], 4)) : I("", !0),
734
- C.value ? (P(), z("div", {
735
- key: 1,
736
- class: "popover-click-mask",
737
- onClick: A
738
- })) : I("", !0)
739
- ]))
740
- ], 4)
741
- ], 36)
742
- ], 512));
743
- }
744
- }), Wt = (X, t) => {
745
- const i = X.__vccOpts || X;
746
- for (const [s, r] of t)
747
- i[s] = r;
748
- return i;
749
- }, Pt = /* @__PURE__ */ Wt(Et, [["__scopeId", "data-v-34fbfef2"]]);
750
- export {
751
- Rt as CanvasRenderer,
752
- Pt as CanvasTable
753
- };
package/dist/index.umd.js DELETED
@@ -1 +0,0 @@
1
- (function(L,s){typeof exports=="object"&&typeof module<"u"?s(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],s):(L=typeof globalThis<"u"?globalThis:L||self,s(L.DrawTable={},L.Vue))})(this,(function(L,s){"use strict";class X{ctx;canvas;columns=[];data=[];options={rowHeight:40,headerHeight:48,border:!0,stripe:!0,multiSelect:!1,fixedHeader:!0,renderExpand:()=>null,spanMethod:()=>{}};scrollX=0;scrollY=0;width=0;height=0;columnPositions=[];rowOffsets=[];totalWidth=0;totalHeight=0;fixedLeftWidth=0;summaryRows=[];expandedRowKeys=new Set;selectedRowKeys=new Set;imageCache=new Map;hoverHeaderIndex=-1;flattenedColumns=[];columnLevels=0;constructor(t){this.canvas=t;const l=t.getContext("2d");if(!l)throw new Error("Could not get canvas context");this.ctx=l}destroy(){this.imageCache.forEach(t=>{t.onload=null,t.onerror=null,t.src=""}),this.imageCache.clear(),this.data=[],this.columns=[],this.summaryRows=[]}setExpandedRows(t){this.expandedRowKeys=new Set(t),this.calculateLayout(),this.render()}setData(t){this.data=t,this.calculateLayout(),this.render()}setColumns(t){this.columns=t,this.flattenColumns(),this.calculateLayout(),this.render()}flattenColumns(){this.flattenedColumns=[],this.columnLevels=0;const t=(i,c=0)=>{this.columnLevels=Math.max(this.columnLevels,c+1),i.forEach(r=>{r.children&&r.children.length>0?t(r.children,c+1):this.flattenedColumns.push(r)})};t(this.columns);const l=40;this.columnLevels>1?this.options.headerHeight=this.columnLevels*l:this.options.headerHeight=48}setOptions(t){this.options={...this.options,...t},this.calculateLayout(),this.render()}resize(t,l){this.width=t,this.height=l;const i=window.devicePixelRatio||1;this.canvas.width=t*i,this.canvas.height=l*i,this.canvas.style.width=`${t}px`,this.canvas.style.height=`${l}px`,this.ctx.resetTransform(),this.ctx.scale(i,i),this.render()}scrollTo(t,l){this.scrollX=t,this.scrollY=l,this.render()}calculateLayout(){let t=0;this.columnPositions=[0];let l=0;this.flattenedColumns.forEach(r=>{const n=r.width||100;t+=n,this.columnPositions.push(t),(r.fixed==="left"||r.fixed===!0)&&(l=t)}),this.totalWidth=t,this.fixedLeftWidth=l;let i=0;this.rowOffsets=[0];const{rowHeight:c}=this.options;this.data.forEach(r=>{i+=c,this.expandedRowKeys.has(r.id)&&(i+=c*3),this.rowOffsets.push(i)}),this.totalHeight=i,this.calculateSummaries()}getRowRange(t=20){const{headerHeight:l}=this.options,i=this.summaryRows.length*this.options.rowHeight,c=this.height-l-i,r=this.scrollY,n=r+c;let o=0;for(;o<this.rowOffsets.length&&(this.rowOffsets[o+1]??0)<r;)o++;let a=o;for(;a<this.rowOffsets.length&&(this.rowOffsets[a]??0)<n;)a++;return{startRow:Math.max(0,o-t),endRow:Math.min(this.data.length,a+1)}}calculateSummaries(){this.summaryRows=[];const t=new Map;this.flattenedColumns.forEach((l,i)=>{l.summary&&l.summary.forEach(c=>{try{const r=c(this.data);if(r&&r.label){const{label:n,value:o}=r;t.has(n)||t.set(n,new Array(this.flattenedColumns.length).fill("")),t.get(n)[i]=o}}catch(r){console.error("Summary calculation error:",r)}})}),t.forEach((l,i)=>{l[0]=i,this.summaryRows.push(l)})}render(){this.ctx.clearRect(0,0,this.width,this.height),this.drawBody(),this.drawFixedLeftBody(),this.drawHeader(),this.drawSummaryRows()}getColumnWidth(t){return t.children&&t.children.length>0?t.children.reduce((i,c)=>i+this.getColumnWidth(c),0):t.width||100}isColumnFixed(t){return t.fixed==="left"||t.fixed==="right"||t.fixed===!0?!0:t.children&&t.children.length>0?t.children.some(l=>this.isColumnFixed(l)):!1}drawHeader(){const{headerHeight:t}=this.options,l=this.columnLevels>1?40:t;this.ctx.save(),this.ctx.fillStyle="#f5f7fa",this.ctx.fillRect(0,0,this.width,t);const i=(c,r,n,o,a)=>{let e=r;c.forEach(h=>{const u=this.getColumnWidth(h),f=this.isColumnFixed(h);if(a!==f){e+=u;return}const g=!h.children||h.children.length===0,p=g?(this.columnLevels-o)*l:l,S=a?e:e-this.scrollX;(a||S+u>this.fixedLeftWidth&&S<this.width)&&(a||(this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(this.fixedLeftWidth,0,this.width-this.fixedLeftWidth,t),this.ctx.clip()),this.drawHeaderCell(h,S,u,p,n,g),a||this.ctx.restore()),h.children&&h.children.length>0&&i(h.children,e,n+l,o+1,a),e+=u})};i(this.columns,0,0,0,!1),i(this.columns,0,0,0,!0),this.ctx.restore()}setHoverHeader(t){this.hoverHeaderIndex!==t&&(this.hoverHeaderIndex=t,this.render())}setSelectedRows(t){this.selectedRowKeys=new Set(t),this.render()}drawHeaderCell(t,l,i,c,r,n){if(this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(l,r,i,c),this.ctx.clip(),this.ctx.fillStyle="#f5f7fa",this.ctx.fillRect(l,r,i,c),this.options.border&&(this.ctx.strokeStyle="#ebeef5",this.ctx.lineWidth=1,this.ctx.strokeRect(l+.5,r+.5,i,c)),t.type==="selection"){const o=this.data.length>0&&this.selectedRowKeys.size===this.data.length;this.drawCheckboxCell(o,l,r,i,c,"center")}else{this.ctx.fillStyle="#303133",this.ctx.font="bold 14px sans-serif",this.ctx.textBaseline="middle";const o=t.align||(n?"left":"center");this.ctx.textAlign=o;let a=l+10;o==="center"&&(a=l+i/2),o==="right"&&(a=l+i-24);const e=t.title||"";if(this.ctx.fillText(e,a,r+c/2),n&&t.type!=="selection"&&t.type!=="expand"){const h=this.flattenedColumns.indexOf(t);if(this.hoverHeaderIndex===h){this.ctx.fillStyle="#909399",this.ctx.beginPath();const u=l+i-18,f=r+c/2;this.ctx.arc(u,f-4,1.5,0,Math.PI*2),this.ctx.arc(u,f,1.5,0,Math.PI*2),this.ctx.arc(u,f+4,1.5,0,Math.PI*2),this.ctx.fill()}}}this.ctx.restore()}getHeaderAt(t,l){const{headerHeight:i}=this.options;if(l>i)return null;const c=this.columnLevels>1?40:i,r=(o,a,e,h)=>{let u=a;for(const f of o){const g=this.isColumnFixed(f);if(h!==g){u+=this.getColumnWidth(f);continue}const p=this.getColumnWidth(f),S=!f.children||f.children.length===0,C=S?(this.columnLevels-e)*c:c,k=e*c,R=h?u:u-this.scrollX;if(!h&&R<this.fixedLeftWidth){u+=p;continue}if(t>=R&&t<R+p&&l>=k&&l<k+C){const y=S&&f.type!=="selection"&&f.type!=="expand"&&t>=R+p-24;return{column:f,rect:{x:R,y:k,width:p,height:C},isMenu:y}}if(f.children&&f.children.length>0){const y=r(f.children,u,e+1,h);if(y)return y}u+=p}return null},n=r(this.columns,0,0,!0);return n||r(this.columns,0,0,!1)}drawBody(){const{headerHeight:t}=this.options,{startRow:l,endRow:i}=this.getRowRange(this.height),c=this.summaryRows.length*this.options.rowHeight;this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(this.fixedLeftWidth,t,this.width-this.fixedLeftWidth,this.height-t-c),this.ctx.clip();const r=new Set,n=[];for(let o=l;o<i;o++){const a=this.data[o];if(!a)continue;const e=(this.rowOffsets[o]??0)-this.scrollY+t,h=(this.rowOffsets[o+1]??0)-(this.rowOffsets[o]??0),u=o%2===1&&this.options.stripe?"#fafafa":"#fff";if(this.flattenedColumns.forEach((f,g)=>{if(f.fixed==="left"||f.fixed===!0||r.has(`${o},${g}`))return;const p=(this.columnPositions[g]??0)-this.scrollX,S=(this.columnPositions[g+1]??0)-(this.columnPositions[g]??0),C=this.options.spanMethod({row:o,column:f,rowIndex:o,columnIndex:g});if(C){const{rowspan:k,colspan:R}=C;if(k===0||R===0)return;const y=(this.columnPositions[g+R]??this.totalWidth)-(this.columnPositions[g]??0),W=(this.rowOffsets[o+k]??this.totalHeight)-(this.rowOffsets[o]??0);for(let b=0;b<k;b++)for(let P=0;P<R;P++)r.add(`${o+b},${g+P}`);n.push({col:f,val:a[f.key||""],x:p,y:e,w:y,h:W,r:o,c:g,bgColor:u})}else this.ctx.fillStyle=u,this.ctx.fillRect(p,e,S,this.options.rowHeight),this.drawCell(f,a[f.key||""],p,e,S,this.options.rowHeight,o),this.options.border&&(this.ctx.strokeStyle="#ebeef5",this.ctx.strokeRect(p+.5,e+.5,S,this.options.rowHeight))}),this.expandedRowKeys.has(a.id)){const f=e+this.options.rowHeight,g=h-this.options.rowHeight;this.ctx.fillStyle="#fdfdfd",this.ctx.fillRect(0,f,this.width,g),this.options.border&&(this.ctx.strokeStyle="#ebeef5",this.ctx.beginPath(),this.ctx.moveTo(0,f),this.ctx.lineTo(this.width,f),this.ctx.stroke()),this.drawExpandPlaceholder(a,this.fixedLeftWidth-this.scrollX,f,this.totalWidth-this.fixedLeftWidth,g)}}n.forEach(({col:o,val:a,x:e,y:h,w:u,h:f,r:g,bgColor:p})=>{this.ctx.fillStyle=p,this.ctx.fillRect(e,h,u,f),this.drawCell(o,a,e,h,u,f,g),this.options.border&&(this.ctx.strokeStyle="#ebeef5",this.ctx.strokeRect(e+.5,h+.5,u,f))}),this.ctx.restore()}drawFixedLeftBody(){const{headerHeight:t}=this.options,{startRow:l,endRow:i}=this.getRowRange(this.height),c=this.summaryRows.length*this.options.rowHeight;this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(0,t,this.fixedLeftWidth,this.height-t-c),this.ctx.clip();const r=new Set,n=[];for(let o=l;o<i;o++){const a=this.data[o];if(!a)continue;const e=(this.rowOffsets[o]??0)-this.scrollY+t,h=o%2===1&&this.options.stripe?"#fafafa":"#fff";this.flattenedColumns.forEach((u,f)=>{if(!(u.fixed==="left"||u.fixed===!0)||r.has(`${o},${f}`))return;const g=this.columnPositions[f]??0,p=(this.columnPositions[f+1]??0)-(this.columnPositions[f]??0),S=this.options.spanMethod({row:o,column:u,rowIndex:o,columnIndex:f});if(S){const{rowspan:C,colspan:k}=S;if(C===0||k===0)return;const R=(this.columnPositions[f+k]??this.fixedLeftWidth)-(this.columnPositions[f]??0),y=(this.rowOffsets[o+C]??this.totalHeight)-(this.rowOffsets[o]??0);for(let W=0;W<C;W++)for(let b=0;b<k;b++)r.add(`${o+W},${f+b}`);n.push({col:u,val:a[u.key||""],x:g,y:e,w:R,h:y,r:o,c:f,bgColor:h})}else this.ctx.fillStyle=h,this.ctx.fillRect(g,e,p,this.options.rowHeight),this.drawCell(u,a[u.key||""],g,e,p,this.options.rowHeight,o),this.options.border&&(this.ctx.strokeStyle="#ebeef5",this.ctx.strokeRect(g+.5,e+.5,p,this.options.rowHeight))})}n.forEach(({col:o,val:a,x:e,y:h,w:u,h:f,r:g,bgColor:p})=>{this.ctx.fillStyle=p,this.ctx.fillRect(e,h,u,f),this.drawCell(o,a,e,h,u,f,g),this.options.border&&(this.ctx.strokeStyle="#ebeef5",this.ctx.strokeRect(e+.5,h+.5,u,f))}),this.ctx.restore()}drawExpandPlaceholder(t,l,i,c,r){this.ctx.save(),this.ctx.fillStyle="#fef0f0",this.ctx.fillRect(l,i,c,r),this.ctx.fillStyle="#f56c6c",this.ctx.font="italic 12px sans-serif",this.ctx.textAlign="center",this.ctx.fillText(`Expanded content for row ${t.id} (Rendered via h function in overlay)`,l+c/2,i+r/2),this.ctx.restore()}drawSummaryRows(){if(this.summaryRows.length===0)return;const{rowHeight:t}=this.options,l=this.summaryRows.length*t,i=this.height-l;this.ctx.save(),this.ctx.fillStyle="#fdf6ec",this.ctx.fillRect(0,i,this.width,l);let c=0;for(let r=0;r<this.flattenedColumns.length;r++){const n=this.flattenedColumns[r];if(n&&(n.type==="selection"||n.type==="expand"||n.key==="id"))c++;else break}c===0&&(c=1),this.summaryRows.forEach((r,n)=>{const o=i+n*t;this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(this.fixedLeftWidth,o,this.width-this.fixedLeftWidth,t),this.ctx.clip(),this.flattenedColumns.forEach((a,e)=>{if(a.fixed==="left"||a.fixed===!0||e<c)return;const h=(this.columnPositions[e]??0)-this.scrollX,u=(this.columnPositions[e+1]??0)-(this.columnPositions[e]??0);this.drawTextCell(r[e],h,o,u,t,a.align),this.options.border&&(this.ctx.strokeStyle="#ebeef5",this.ctx.strokeRect(h+.5,o+.5,u,t))}),this.ctx.restore(),this.flattenedColumns.forEach((a,e)=>{if(a.fixed==="left"||a.fixed===!0){const h=this.columnPositions[e]??0,u=(this.columnPositions[e+1]??0)-(this.columnPositions[e]??0);if(e===0){const f=(this.columnPositions[c]??this.fixedLeftWidth)-(this.columnPositions[0]??0);this.ctx.save(),this.ctx.font="bold 13px sans-serif",this.ctx.fillStyle="#e6a23c",this.drawTextCell(r[0],h,o,f,t,"center"),this.ctx.restore(),this.options.border&&(this.ctx.strokeStyle="#ebeef5",this.ctx.strokeRect(h+.5,o+.5,f,t))}else{if(e<c)return;this.drawTextCell(r[e],h,o,u,t,a.align),this.options.border&&(this.ctx.strokeStyle="#ebeef5",this.ctx.strokeRect(h+.5,o+.5,u,t))}}})}),this.ctx.restore()}drawCell(t,l,i,c,r,n,o){if(this.ctx.save(),this.ctx.beginPath(),this.ctx.rect(i,c,r,n),this.ctx.clip(),t.renderCell)this.drawTextCell(l,i,c,r,n,t.align);else switch(t.type){case"expand":this.drawExpandButton(i+(r-16)/2,c+(this.options.rowHeight-16)/2,this.expandedRowKeys.has(this.data[o]?.id??""));break;case"selection":const a=this.selectedRowKeys.has(this.data[o]?.id??"");this.drawCheckboxCell(a,i,c,r,this.options.rowHeight,"center");break;case"image":this.drawImageCell(l,i,c,r,n,t.align);break;case"checkbox":this.drawCheckboxCell(l,i,c,r,n,t.align);break;case"radio":this.drawRadioCell(l,i,c,r,n,t.align);break;case"switch":this.drawSwitchCell(l,i,c,r,n,t.align);break;case"color-picker":this.drawColorPickerCell(l,i,c,r,n,t.align);break;case"tags":this.drawTagsCell(l,i,c,r,n);break;default:this.drawTextCell(l,i,c,r,n,t.align);break}this.ctx.restore()}drawExpandButton(t,l,i){this.ctx.save(),this.ctx.translate(t+8,l+8),i&&this.ctx.rotate(Math.PI/2),this.ctx.strokeStyle="#909399",this.ctx.lineWidth=2,this.ctx.beginPath(),this.ctx.moveTo(-3,-5),this.ctx.lineTo(3,0),this.ctx.lineTo(-3,5),this.ctx.stroke(),this.ctx.restore()}drawTextCell(t,l,i,c,r,n){this.ctx.fillStyle="#606266",this.ctx.font="14px sans-serif",this.ctx.textAlign=n||"left",this.ctx.textBaseline="middle";let o=l+10;n==="center"&&(o=l+c/2),n==="right"&&(o=l+c-10);const a=t==null?"":String(t);this.ctx.fillText(a,o,i+r/2)}drawImageCell(t,l,i,c,r,n){if(!t)return;const o=String(t),a=Math.min(c,r)-10;let e=l+5;n==="center"&&(e=l+(c-a)/2),n==="right"&&(e=l+c-a-5);let h=this.imageCache.get(o);h||(h=new Image,h.src=o,this.imageCache.set(o,h),h.onload=()=>this.render(),h.onerror=()=>{console.error(`Failed to load image: ${o}`),this.imageCache.delete(o)}),h.complete&&h.naturalWidth>0?this.ctx.drawImage(h,e,i+(r-a)/2,a,a):(this.ctx.fillStyle="#f5f7fa",this.ctx.fillRect(e,i+(r-a)/2,a,a))}drawCheckboxCell(t,l,i,c,r,n){let a=l+10;n==="center"&&(a=l+(c-16)/2),n==="right"&&(a=l+c-16-10);const e=i+(r-16)/2;this.ctx.strokeStyle=t?"#409eff":"#dcdfe6",this.ctx.fillStyle=t?"#409eff":"#fff",this.ctx.lineWidth=1,this.ctx.strokeRect(a+.5,e+.5,16,16),t&&(this.ctx.fillRect(a+1,e+1,15,15),this.ctx.strokeStyle="#fff",this.ctx.beginPath(),this.ctx.moveTo(a+4,e+8),this.ctx.lineTo(a+7,e+11),this.ctx.lineTo(a+12,e+5),this.ctx.stroke())}drawRadioCell(t,l,i,c,r,n){let a=l+10;n==="center"&&(a=l+(c-16)/2),n==="right"&&(a=l+c-16-10);const e=i+(r-16)/2,h=a+16/2,u=e+16/2;this.ctx.strokeStyle=t?"#409eff":"#dcdfe6",this.ctx.fillStyle="#fff",this.ctx.beginPath(),this.ctx.arc(h,u,16/2,0,Math.PI*2),this.ctx.stroke(),this.ctx.fill(),t&&(this.ctx.fillStyle="#409eff",this.ctx.beginPath(),this.ctx.arc(h,u,16/4,0,Math.PI*2),this.ctx.fill())}drawSwitchCell(t,l,i,c,r,n){let e=l+10;n==="center"&&(e=l+(c-32)/2),n==="right"&&(e=l+c-32-10);const h=i+(r-16)/2;this.ctx.fillStyle=t?"#13ce66":"#ff4949",this.ctx.beginPath(),this.ctx.roundRect?.(e,h,32,16,16/2),this.ctx.fill(),this.ctx.fillStyle="#fff",this.ctx.beginPath();const u=t?e+32-16+2:e+2;this.ctx.arc(u+12/2,h+16/2,12/2,0,Math.PI*2),this.ctx.fill()}drawColorPickerCell(t,l,i,c,r,n){let a=l+10;n==="center"&&(a=l+(c-20)/2),n==="right"&&(a=l+c-20-10);const e=i+(r-20)/2;this.ctx.fillStyle=t||"#000",this.ctx.fillRect(a,e,20,20),this.ctx.strokeStyle="#dcdfe6",this.ctx.strokeRect(a+.5,e+.5,20,20)}drawTagsCell(t,l,i,c,r){if(!Array.isArray(t))return;let n=l+5;const o=20,a=5,e=12;t.forEach(h=>{const u=String(h);this.ctx.font=`${e}px sans-serif`;const g=this.ctx.measureText(u).width+a*2;if(n+g>l+c-5)return;const p=i+(r-o)/2;this.ctx.fillStyle="#ecf5ff",this.ctx.strokeStyle="#d9ecff",this.ctx.beginPath(),this.ctx.roundRect?.(n,p,g,o,4),this.ctx.fill(),this.ctx.stroke(),this.ctx.fillStyle="#409eff",this.ctx.textAlign="center",this.ctx.fillText(u,n+g/2,p+o-e/2),n+=g+5})}getCellAt(t,l){const{headerHeight:i}=this.options;if(l<i)return null;const{startRow:c,endRow:r}=this.getRowRange(this.height);for(let n=c;n<r;n++){const o=this.data[n];if(!o)continue;const a=(this.rowOffsets[n]??0)-this.scrollY+i,e=(this.rowOffsets[n+1]??0)-(this.rowOffsets[n]??0);if(l>=a&&l<a+e)for(let h=0;h<this.flattenedColumns.length;h++){const u=this.flattenedColumns[h],f=(this.columnPositions[h+1]??0)-(this.columnPositions[h]??0);let g=0;if(u.fixed==="left"||u.fixed===!0)g=this.columnPositions[h]??0;else if(g=(this.columnPositions[h]??0)-this.scrollX,g<this.fixedLeftWidth)continue;if(t>=g&&t<g+f){const p=u.type==="expand",S=u.type==="selection";return{row:n,col:h,rect:{x:g,y:a,width:f,height:e},column:u,data:o,isExpandBtn:p,isSelection:S}}}}return null}getRowOffsets(){return this.rowOffsets}getScrollX(){return this.scrollX}getScrollY(){return this.scrollY}getFixedLeftWidth(){return this.fixedLeftWidth}getTotalWidth(){return this.totalWidth}getTotalHeight(){return this.totalHeight}}const N=["onClick"],I={class:"icon"},A={class:"label"},O={class:"edit-dialog-content"},D=((z,t)=>{const l=z.__vccOpts||z;for(const[i,c]of t)l[i]=c;return l})(s.defineComponent({__name:"CanvasTable",props:{columns:{},data:{},options:{}},emits:["update:data","select-change","header-command"],setup(z,{emit:t}){const l=s.defineComponent({props:["vnode"],setup(d){return()=>d.vnode}}),i=z,c=t,r=s.ref(null),n=s.ref(null),o=s.ref(null),a=s.ref(null),e=s.shallowRef(null),h=s.ref(0),u=s.ref(0),f=s.ref(0),g=s.ref(0),p=s.ref(0),S=s.ref(0),C=s.ref(null),k=s.ref(null),R=s.ref(null),y=s.ref(new Set),W=s.ref(new Set),b=s.ref(null),P=s.computed(()=>({width:"100%",height:"100%",position:"relative",overflow:"hidden"})),K=s.computed(()=>({position:"absolute",top:0,left:0,pointerEvents:"none",width:"100%",height:"100%"})),F=s.computed(()=>{if(!C.value)return{};const{rect:d}=C.value;return{position:"absolute",left:`${d.x+d.width-24}px`,top:`${d.y+(d.height-20)/2}px`,pointerEvents:"auto"}}),J=s.computed(()=>{if(!k.value||!n.value)return{};const d=n.value.getBoundingClientRect(),{rect:m}=k.value;let x=d.top+m.y+m.height+5,w=d.left+m.x;const v=300;return w+v>window.innerWidth&&(w=window.innerWidth-v-20),{position:"fixed",top:`${x}px`,left:`${w}px`,zIndex:2e3,pointerEvents:"auto"}}),U=s.computed(()=>{if(!b.value)return{};const{rect:d}=b.value;return{position:"absolute",left:`${d.x+d.width-120}px`,top:`${d.y+d.height}px`,pointerEvents:"auto"}}),q=s.computed(()=>{if(!b.value)return[];const{column:d}=b.value,m=[{label:"Fix to Left",onCommand:x=>{const w=i.columns.findIndex(v=>v.key===x.key);i.columns.forEach((v,H)=>{H<=w&&(v.fixed="left")}),e.value?.setColumns(i.columns)}},{label:"Unfix",onCommand:x=>{x.fixed=!1,e.value?.setColumns(i.columns)}}];return d.renderHeaderMenu?d.renderHeaderMenu(d,m):m}),G=d=>{b.value&&(d.onCommand(b.value.column),b.value=null)},Y=d=>{if(!n.value||!e.value)return;const m=n.value.getBoundingClientRect(),x=d.clientX-m.left,w=d.clientY-m.top,v=e.value.getHeaderAt(x,w);if(v){const H=i.columns.findIndex(E=>E.key===v.column.key);e.value.setHoverHeader(H),v.isMenu||v.column.type==="selection"?n.value.style.cursor="pointer":n.value.style.cursor="default"}else e.value.setHoverHeader(-1),n.value.style.cursor="default";C.value=e.value.getCellAt(x,w),C.value&&(C.value.isExpandBtn||C.value.isSelection)&&(n.value.style.cursor="pointer")},V=d=>{if(!n.value||!e.value)return;const m=n.value.getBoundingClientRect(),x=d.clientX-m.left,w=d.clientY-m.top,v=e.value.getHeaderAt(x,w);if(v){v.isMenu?b.value={column:v.column,rect:v.rect}:v.column.type==="selection"&&(y.value.size===i.data.length?y.value.clear():i.data.forEach(rt=>y.value.add(rt.id)),e.value.setSelectedRows(Array.from(y.value)),c("select-change",Array.from(y.value)));return}const H=e.value.getCellAt(x,w);if(H){if(H.isExpandBtn){Q(H.data.id);return}const E=H.data.id;if(H.isSelection){y.value.has(E)?y.value.delete(E):y.value.add(E),e.value.setSelectedRows(Array.from(y.value)),c("select-change",Array.from(y.value));return}i.options?.multiSelect?y.value.has(E)?y.value.delete(E):y.value.add(E):(y.value.clear(),y.value.add(E)),c("select-change",Array.from(y.value))}},_=d=>{if(!n.value||!e.value)return;const m=n.value.getBoundingClientRect(),x=d.clientX-m.left,w=d.clientY-m.top,v=e.value.getCellAt(x,w);v&&v.column.renderEdit&&$(v)},$=d=>{k.value=d,R.value=JSON.parse(JSON.stringify(d.data))},Q=d=>{W.value.has(d)?W.value.delete(d):W.value.add(d),e.value?.setExpandedRows(Array.from(W.value)),B()},T=()=>{k.value=null,R.value=null},Z=()=>{if(k.value&&R.value){const d=k.value.data.id,m=i.data.findIndex(x=>x.id===d);if(m!==-1){const x=[...i.data];x[m]=R.value,c("update:data",x),e.value?.setData(x)}}T()},j=d=>!d.column.renderEdit||!R.value?null:d.column.renderEdit(R.value,(m,x,w)=>x&&(typeof x=="string"||Array.isArray(x)||x.__v_isVNode)?s.h(m,null,x):s.h(m,x,w)),tt=d=>{if(!e.value)return{};const m=i.data.findIndex(E=>E.id===d);if(m===-1)return{};const x=e.value.getRowOffsets(),w=(x[m]??0)-S.value+(i.options?.headerHeight||48),v=(x[m+1]??0)-(x[m]??0)-(i.options?.rowHeight||40),H=e.value.getFixedLeftWidth();return{position:"absolute",top:`${w+(i.options?.rowHeight||40)}px`,left:`${H}px`,width:`${f.value-H}px`,height:`${v}px`,pointerEvents:"auto",overflow:"hidden",backgroundColor:"#fff",borderBottom:"1px solid #ebeef5",display:"flex"}},et=()=>({marginLeft:`-${p.value}px`,minWidth:`${h.value-e.value?.getFixedLeftWidth()}px`}),st=d=>{const m=i.data.find(x=>x.id===d);return!m||!i.options?.renderExpand?null:s.h("div",{style:et()},[i.options.renderExpand(m,(x,w,v)=>w&&(typeof w=="string"||Array.isArray(w)||w.__v_isVNode)?s.h(x,null,w):s.h(x,w,v))])},it=d=>{const m=d.target;p.value=m.scrollLeft,e.value?.scrollTo(p.value,S.value),C.value=null},lt=d=>{const m=d.target;S.value=m.scrollTop,e.value?.scrollTo(p.value,S.value),C.value=null},nt=d=>{if(!a.value||!o.value)return;const m=d.deltaY,x=d.shiftKey?d.deltaY:d.deltaX;a.value.scrollTop+=m,o.value.scrollLeft+=x},ot=d=>{const m=d[0];if(!m||!e.value)return;const{width:x,height:w}=m.contentRect;f.value=x,g.value=w,e.value.resize(x,w),B()},B=()=>{e.value&&(h.value=e.value.getTotalWidth(),u.value=e.value.getTotalHeight())};let M=null;return s.onMounted(()=>{n.value&&(e.value=new X(n.value),e.value.setColumns(i.columns),e.value.setData(i.data),e.value.setOptions(i.options||{}),B(),M=new ResizeObserver(ot),r.value&&M.observe(r.value),n.value.addEventListener("mousemove",Y),n.value.addEventListener("mousedown",V),n.value.addEventListener("dblclick",_))}),s.onUnmounted(()=>{M?.disconnect(),n.value?.removeEventListener("mousemove",Y),n.value?.removeEventListener("mousedown",V),n.value?.removeEventListener("dblclick",_),e.value?.destroy(),e.value=null}),s.watch(()=>i.columns,d=>{e.value?.setColumns(d),B()},{deep:!0}),s.watch(()=>i.data,d=>{e.value?.setData(d),B()},{deep:!0}),s.watch(()=>i.options,d=>{d&&e.value?.setOptions(d)},{deep:!0}),(d,m)=>(s.openBlock(),s.createElementBlock("div",{class:"canvas-table-container",ref_key:"containerRef",ref:r},[s.createElementVNode("div",{class:"canvas-wrapper",style:s.normalizeStyle(P.value),onWheel:s.withModifiers(nt,["prevent"])},[s.createElementVNode("canvas",{ref_key:"canvasRef",ref:n},null,512),s.createElementVNode("div",{class:"scrollbar horizontal",ref_key:"hScrollRef",ref:o,onScroll:it},[s.createElementVNode("div",{style:s.normalizeStyle({width:h.value+"px",height:"1px"})},null,4)],544),s.createElementVNode("div",{class:"scrollbar vertical",ref_key:"vScrollRef",ref:a,onScroll:lt},[s.createElementVNode("div",{style:s.normalizeStyle({height:u.value+"px",width:"1px"})},null,4)],544),s.createElementVNode("div",{class:"table-overlays",style:s.normalizeStyle(K.value)},[C.value&&C.value.column.renderEdit?(s.openBlock(),s.createElementBlock("div",{key:0,class:"edit-btn",style:s.normalizeStyle(F.value),onClick:m[0]||(m[0]=s.withModifiers(x=>$(C.value),["stop"]))},[...m[2]||(m[2]=[s.createElementVNode("svg",{viewBox:"0 0 24 24",width:"14",height:"14"},[s.createElementVNode("path",{fill:"currentColor",d:"M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"})],-1)])],4)):s.createCommentVNode("",!0),b.value?(s.openBlock(),s.createElementBlock("div",{key:1,class:"header-menu-overlay",onClick:m[1]||(m[1]=s.withModifiers(x=>b.value=null,["self"]))},[s.createElementVNode("div",{class:"header-menu",style:s.normalizeStyle(U.value)},[(s.openBlock(!0),s.createElementBlock(s.Fragment,null,s.renderList(q.value,x=>(s.openBlock(),s.createElementBlock("div",{key:x.label,class:"menu-item",onClick:w=>G(x)},[s.createElementVNode("span",I,s.toDisplayString(x.icon||"•"),1),s.createElementVNode("span",A,s.toDisplayString(x.label),1)],8,N))),128))],4)])):s.createCommentVNode("",!0),(s.openBlock(!0),s.createElementBlock(s.Fragment,null,s.renderList(W.value,x=>(s.openBlock(),s.createElementBlock("div",{key:x,class:"expand-row-overlay",style:s.normalizeStyle(tt(x))},[(s.openBlock(),s.createBlock(s.resolveDynamicComponent(st(x))))],4))),128)),(s.openBlock(),s.createBlock(s.Teleport,{to:"body"},[k.value?(s.openBlock(),s.createElementBlock("div",{key:0,class:"edit-dialog-popover",style:s.normalizeStyle(J.value)},[s.createElementVNode("div",O,[s.createVNode(s.unref(l),{vnode:j(k.value)},null,8,["vnode"])]),s.createElementVNode("div",{class:"edit-dialog-footer"},[s.createElementVNode("button",{class:"small",onClick:T},"Cancel"),s.createElementVNode("button",{class:"small primary",onClick:Z},"Save")])],4)):s.createCommentVNode("",!0),k.value?(s.openBlock(),s.createElementBlock("div",{key:1,class:"popover-click-mask",onClick:T})):s.createCommentVNode("",!0)]))],4)],36)],512))}}),[["__scopeId","data-v-34fbfef2"]]);L.CanvasRenderer=X,L.CanvasTable=D,Object.defineProperty(L,Symbol.toStringTag,{value:"Module"})}));