@lembryo/voxsheet 0.0.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/dist/index.js ADDED
@@ -0,0 +1,1226 @@
1
+ import { jsx as v, jsxs as oe } from "react/jsx-runtime";
2
+ import { useRef as E, useState as V, useCallback as a, useEffect as I, useMemo as Se, forwardRef as Sn, useImperativeHandle as kn } from "react";
3
+ const De = 200, Nn = 80, Tn = (n) => {
4
+ const {
5
+ fetchRows: d,
6
+ totalRows: r,
7
+ columns: i,
8
+ sort: h,
9
+ filters: u,
10
+ search: m,
11
+ queryKey: b,
12
+ frozenRows: p,
13
+ startRow: R,
14
+ endRow: Y,
15
+ onError: W
16
+ } = n, w = E(/* @__PURE__ */ new Map()), A = E(/* @__PURE__ */ new Set()), G = E(/* @__PURE__ */ new Set()), [ye, re] = V(/* @__PURE__ */ new Map()), [P, le] = V(r), [de, g] = V("idle"), y = JSON.stringify({
17
+ columns: i.map((F) => F.name),
18
+ sort: h,
19
+ filters: u,
20
+ search: m ?? null
21
+ }), C = a(() => {
22
+ for (const F of G.current) F.abort();
23
+ G.current.clear(), w.current.clear(), A.current.clear(), re(/* @__PURE__ */ new Map());
24
+ }, []);
25
+ I(() => {
26
+ C();
27
+ }, [y, b, C]);
28
+ const j = a(() => {
29
+ const F = /* @__PURE__ */ new Map();
30
+ for (const [se, ke] of w.current)
31
+ ke.forEach((Ne, he) => F.set(se + he, Ne));
32
+ re(F);
33
+ }, []), T = a(async () => {
34
+ const F = P > 0 ? P : r, se = [];
35
+ p > 0 && se.push(0);
36
+ const ke = Math.floor(R / De) * De, Ne = Math.ceil(Y / De) * De;
37
+ for (let k = ke; k < Ne; k += De)
38
+ k >= 0 && se.push(k);
39
+ const he = se.filter(
40
+ (k) => k < F && !w.current.has(k) && !A.current.has(k)
41
+ );
42
+ if (he.length === 0) return;
43
+ g("loading");
44
+ const Te = he.map(async (k) => {
45
+ A.current.add(k);
46
+ const me = new AbortController();
47
+ G.current.add(me);
48
+ const $e = De;
49
+ try {
50
+ const B = await d(
51
+ { offset: k, limit: $e, sort: h, filters: u, search: m },
52
+ me.signal
53
+ ), Le = B.data.map((pe, $) => ({
54
+ values: pe,
55
+ id: B.ids[$] ?? k + $ + 1,
56
+ ordinal: B.ordinals[$] ?? k + $ + 1
57
+ }));
58
+ w.current.set(k, Le), typeof B.total == "number" && le(B.total);
59
+ } catch (B) {
60
+ me.signal.aborted || (W?.(B, { phase: "fetch" }), g("error"));
61
+ } finally {
62
+ A.current.delete(k), G.current.delete(me);
63
+ }
64
+ });
65
+ await Promise.all(Te), j(), g((k) => k === "error" ? k : "idle");
66
+ }, [
67
+ d,
68
+ h,
69
+ u,
70
+ m,
71
+ R,
72
+ Y,
73
+ p,
74
+ P,
75
+ r,
76
+ W,
77
+ j
78
+ ]);
79
+ I(() => {
80
+ const F = setTimeout(() => {
81
+ T();
82
+ }, Nn);
83
+ return () => clearTimeout(F);
84
+ }, [T]), I(() => {
85
+ le(r);
86
+ }, [r]);
87
+ const fe = a(() => {
88
+ C(), T();
89
+ }, [C, T]);
90
+ return { rows: ye, total: P > 0 ? P : r, status: de, invalidate: fe };
91
+ }, Ln = 200, at = (n, d) => `${n}:${d}`, An = ({ onCellChange: n, onDirtyChange: d }) => {
92
+ const r = E(/* @__PURE__ */ new Map()), i = E(/* @__PURE__ */ new Map()), h = E([]), u = E([]), [m, b] = V(0), p = a(() => {
93
+ d?.(r.current.size > 0);
94
+ }, [d]), R = a(
95
+ (g, y, C, j) => {
96
+ const T = at(g, y);
97
+ i.current.has(T) || i.current.set(T, j(g, y));
98
+ const fe = i.current.get(T) ?? null;
99
+ C === fe ? (r.current.delete(T), i.current.delete(T)) : r.current.set(T, C), n?.({ row: g, col: y, oldValue: fe, newValue: C });
100
+ },
101
+ [n]
102
+ ), Y = a(
103
+ (g, y) => {
104
+ if (g.length !== 0) {
105
+ for (const C of g) R(C.row, C.col, C.newValue, y);
106
+ h.current.push(g), h.current.length > Ln && h.current.shift(), u.current = [], b((C) => C + 1), p();
107
+ }
108
+ },
109
+ [R, p]
110
+ ), W = a(() => null, []), w = a(() => {
111
+ const g = h.current.pop();
112
+ if (g) {
113
+ for (let y = g.length - 1; y >= 0; y--) {
114
+ const C = g[y];
115
+ R(C.row, C.col, C.oldValue, W);
116
+ }
117
+ u.current.push(g), b((y) => y + 1), p();
118
+ }
119
+ }, [R, W, p]), A = a(() => {
120
+ const g = u.current.pop();
121
+ if (g) {
122
+ for (const y of g) R(y.row, y.col, y.newValue, W);
123
+ h.current.push(g), b((y) => y + 1), p();
124
+ }
125
+ }, [R, W, p]), G = a((g, y) => {
126
+ const C = at(g, y);
127
+ return r.current.has(C) ? r.current.get(C) : void 0;
128
+ }, []), ye = a(
129
+ (g, y) => r.current.has(at(g, y)),
130
+ []
131
+ ), re = a(() => {
132
+ const g = [];
133
+ for (const [y, C] of r.current) {
134
+ const [j, T] = y.split(":");
135
+ g.push({
136
+ row: Number(j),
137
+ col: Number(T),
138
+ oldValue: i.current.get(y) ?? null,
139
+ newValue: C
140
+ });
141
+ }
142
+ return g;
143
+ }, []), P = a(() => {
144
+ r.current.clear(), i.current.clear(), h.current = [], u.current = [], b((g) => g + 1), d?.(!1);
145
+ }, [d]), le = a(() => h.current.length > 0, []), de = a(() => u.current.length > 0, []);
146
+ return Se(
147
+ () => ({
148
+ version: m,
149
+ applyEdits: Y,
150
+ undo: w,
151
+ redo: A,
152
+ getEditedValue: G,
153
+ isDirty: ye,
154
+ getLocalEdits: re,
155
+ clear: P,
156
+ canUndo: le,
157
+ canRedo: de
158
+ }),
159
+ [
160
+ m,
161
+ Y,
162
+ w,
163
+ A,
164
+ G,
165
+ ye,
166
+ re,
167
+ P,
168
+ le,
169
+ de
170
+ ]
171
+ );
172
+ }, Hn = (n) => n === "number" || n === "date" ? "right" : n === "boolean" ? "center" : "left", zt = (n) => {
173
+ if (n === null || n === "") return null;
174
+ const d = typeof n == "number" ? new Date(n) : new Date(String(n));
175
+ return Number.isNaN(d.getTime()) ? null : d;
176
+ }, Vn = (n, d, r) => {
177
+ const i = d.format;
178
+ if (typeof i == "function") return i(n, { column: d, row: r });
179
+ if (n === null) return "";
180
+ if (i && i.kind === "number" && typeof n == "number")
181
+ return new Intl.NumberFormat(void 0, i.options).format(n);
182
+ if (i && i.kind === "date") {
183
+ const h = zt(n);
184
+ if (h) return new Intl.DateTimeFormat(void 0, i.options).format(h);
185
+ }
186
+ switch (d.type) {
187
+ case "boolean":
188
+ return n ? "✓" : "";
189
+ case "date": {
190
+ const h = zt(n);
191
+ return typeof n == "string" ? n : h ? h.toISOString().slice(0, 10) : "";
192
+ }
193
+ case "number":
194
+ return String(n);
195
+ default:
196
+ return String(n);
197
+ }
198
+ }, Ft = (n, d) => {
199
+ if (n === "") return d === "string" || d === void 0 ? "" : null;
200
+ switch (d) {
201
+ case "number": {
202
+ const r = Number(n.replace(/,/g, ""));
203
+ return Number.isNaN(r) ? n : r;
204
+ }
205
+ case "boolean": {
206
+ const r = n.trim().toLowerCase();
207
+ return ["true", "1", "yes", "y", "✓"].includes(r) ? !0 : ["false", "0", "no", "n", ""].includes(r) ? !1 : n;
208
+ }
209
+ case "date":
210
+ return n;
211
+ default:
212
+ return n;
213
+ }
214
+ }, zn = (n) => {
215
+ if (typeof n == "number") return n;
216
+ if (typeof n == "string" && n.trim() !== "") {
217
+ const d = Number(n.replace(/,/g, ""));
218
+ return Number.isNaN(d) ? null : d;
219
+ }
220
+ return null;
221
+ }, Fn = (n) => ({
222
+ r1: Math.min(n.start.row, n.end.row),
223
+ r2: Math.max(n.start.row, n.end.row),
224
+ c1: Math.min(n.start.col, n.end.col),
225
+ c2: Math.max(n.start.col, n.end.col)
226
+ }), Kn = (n) => n.map(Fn), $n = (n, d, r) => d >= n.r1 && d <= n.r2 && r >= n.c1 && r <= n.c2, On = (n, d, r) => n.some((i) => $n(i, d, r)), ut = (n) => n.reduce((d, r) => d + (r.r2 - r.r1 + 1) * (r.c2 - r.c1 + 1), 0), Kt = (n) => /[\t\n\r"]/.test(n) ? `"${n.replace(/"/g, '""')}"` : n, Pn = (n, d) => {
227
+ if (n.length === 0) return "";
228
+ const r = (i) => {
229
+ const h = [];
230
+ for (let u = i.r1; u <= i.r2; u++) {
231
+ const m = [];
232
+ for (let b = i.c1; b <= i.c2; b++) m.push(Kt(d(u, b)));
233
+ h.push(m.join(" "));
234
+ }
235
+ return h;
236
+ };
237
+ if (n.length > 1) {
238
+ const i = n[0];
239
+ if (n.every((m) => m.r1 === i.r1 && m.r2 === i.r2)) {
240
+ const m = [...n].sort((p, R) => p.c1 - R.c1), b = [];
241
+ for (let p = i.r1; p <= i.r2; p++) {
242
+ const R = [];
243
+ for (const Y of m)
244
+ for (let W = Y.c1; W <= Y.c2; W++) R.push(Kt(d(p, W)));
245
+ b.push(R.join(" "));
246
+ }
247
+ return b.join(`
248
+ `);
249
+ }
250
+ if (n.every((m) => m.c1 === i.c1 && m.c2 === i.c2))
251
+ return [...n].sort((b, p) => b.r1 - p.r1).flatMap(r).join(`
252
+ `);
253
+ }
254
+ return r(n[n.length - 1]).join(`
255
+ `);
256
+ }, Un = (n) => {
257
+ const d = [];
258
+ let r = [], i = "", h = !1, u = 0;
259
+ const m = () => {
260
+ r.push(i), i = "";
261
+ }, b = () => {
262
+ m(), d.push(r), r = [];
263
+ };
264
+ for (; u < n.length; ) {
265
+ const p = n[u];
266
+ if (h) {
267
+ if (p === '"') {
268
+ if (n[u + 1] === '"') {
269
+ i += '"', u += 2;
270
+ continue;
271
+ }
272
+ h = !1, u++;
273
+ continue;
274
+ }
275
+ i += p, u++;
276
+ continue;
277
+ }
278
+ if (p === '"') {
279
+ h = !0, u++;
280
+ continue;
281
+ }
282
+ if (p === " ") {
283
+ m(), u++;
284
+ continue;
285
+ }
286
+ if (p === `
287
+ ` || p === "\r") {
288
+ p === "\r" && n[u + 1] === `
289
+ ` && u++, b(), u++;
290
+ continue;
291
+ }
292
+ i += p, u++;
293
+ }
294
+ return (i !== "" || r.length > 0) && b(), d;
295
+ }, Ke = (n) => ({
296
+ width: n.size ?? 14,
297
+ height: n.size ?? 14,
298
+ viewBox: "0 0 16 16",
299
+ fill: "none",
300
+ stroke: "currentColor",
301
+ strokeWidth: 1.6,
302
+ strokeLinecap: "round",
303
+ strokeLinejoin: "round",
304
+ className: n.className,
305
+ "aria-hidden": !0
306
+ }), Wn = (n) => /* @__PURE__ */ v("svg", { ...Ke(n), children: /* @__PURE__ */ v("path", { d: "M8 12V4M8 4l-3 3M8 4l3 3" }) }), Bn = (n) => /* @__PURE__ */ v("svg", { ...Ke(n), children: /* @__PURE__ */ v("path", { d: "M8 4v8M8 12l-3-3M8 12l3-3" }) }), _n = (n) => /* @__PURE__ */ v("svg", { ...Ke(n), opacity: 0.45, children: /* @__PURE__ */ v("path", { d: "M5 6l3-3 3 3M5 10l3 3 3-3" }) }), In = (n) => /* @__PURE__ */ v("svg", { ...Ke(n), children: /* @__PURE__ */ v("path", { d: "M2.5 3.5h11l-4.2 5v4l-2.6 1.3v-5.3z" }) }), jn = (n) => /* @__PURE__ */ v("svg", { ...Ke(n), fill: "currentColor", stroke: "none", children: /* @__PURE__ */ v("path", { d: "M2.5 3.5h11l-4.2 5v4l-2.6 1.3v-5.3z" }) }), $t = {
307
+ sortAscending: Wn,
308
+ sortDescending: Bn,
309
+ sortUnsorted: _n,
310
+ filter: In,
311
+ filterActive: jn
312
+ }, Xn = (n) => n ? { ...$t, ...n } : $t, Ot = {
313
+ loading: "Loading…",
314
+ empty: "No rows",
315
+ contextCut: "Cut",
316
+ contextCopy: "Copy",
317
+ contextPaste: "Paste",
318
+ contextInsertRowAbove: "Insert row above",
319
+ contextInsertRowBelow: "Insert row below",
320
+ contextDeleteRows: "Delete rows",
321
+ contextUndo: "Undo",
322
+ contextRedo: "Redo",
323
+ confirmLargeCopyTitle: "Copy a large selection",
324
+ confirmLargeCopyMessage: "The selection is large and copying may take a while. Continue?",
325
+ confirmOk: "OK",
326
+ confirmCancel: "Cancel"
327
+ }, qn = (n) => n ? { ...Ot, ...n } : Ot, ft = () => typeof document < "u", Yn = async () => typeof navigator < "u" && navigator.clipboard ? navigator.clipboard.readText() : "", Jn = async (n) => {
328
+ typeof navigator < "u" && navigator.clipboard && await navigator.clipboard.writeText(n);
329
+ };
330
+ let Qn = 0;
331
+ const Gn = () => {
332
+ if (!ft()) return null;
333
+ let n = document.querySelector(".vox-toast-container");
334
+ return n || (n = document.createElement("div"), n.className = "vox-toast-container", document.body.appendChild(n)), n;
335
+ }, Zn = (n, d, r) => {
336
+ const i = Gn(), h = r?.id ?? `vox-toast-${++Qn}`;
337
+ if (!i) return h;
338
+ let u = document.getElementById(h);
339
+ u || (u = document.createElement("div"), u.id = h, i.appendChild(u)), u.className = `vox-toast vox-toast--${n}`, u.textContent = d;
340
+ const m = r?.durationMs ?? (n === "loading" ? 0 : 3e3);
341
+ return m > 0 && window.setTimeout(() => u?.remove(), m), h;
342
+ }, eo = (n) => ft() ? new Promise((d) => {
343
+ const r = document.createElement("div");
344
+ r.className = "vox-modal-backdrop";
345
+ const i = document.createElement("div");
346
+ i.className = "vox-modal", i.setAttribute("role", "dialog"), i.setAttribute("aria-modal", "true");
347
+ const h = (R) => {
348
+ r.remove(), d(R);
349
+ };
350
+ if (n.title) {
351
+ const R = document.createElement("div");
352
+ R.className = "vox-modal-title", R.textContent = n.title, i.appendChild(R);
353
+ }
354
+ const u = document.createElement("div");
355
+ u.className = "vox-modal-body", u.textContent = n.message, i.appendChild(u);
356
+ const m = document.createElement("div");
357
+ m.className = "vox-modal-footer";
358
+ const b = document.createElement("button");
359
+ b.className = "vox-btn", b.textContent = n.cancelLabel ?? "Cancel", b.onclick = () => h(!1);
360
+ const p = document.createElement("button");
361
+ p.className = "vox-btn vox-btn--primary", p.textContent = n.confirmLabel ?? "OK", p.onclick = () => h(!0), m.append(b, p), i.appendChild(m), r.appendChild(i), r.onclick = (R) => {
362
+ R.target === r && h(!1);
363
+ }, document.body.appendChild(r), p.focus();
364
+ }) : Promise.resolve(!1), to = async (n) => {
365
+ if (!ft()) return;
366
+ const d = typeof n.data == "string" ? new Blob([n.data], { type: n.mimeType ?? "text/plain" }) : n.data, r = URL.createObjectURL(d), i = document.createElement("a");
367
+ i.href = r, i.download = n.suggestedName, document.body.appendChild(i), i.click(), i.remove(), URL.revokeObjectURL(r);
368
+ }, no = (n) => ({
369
+ readText: n?.clipboard?.readText ?? Yn,
370
+ writeText: n?.clipboard?.writeText ?? Jn,
371
+ notify: n?.notify ?? Zn,
372
+ confirm: n?.confirm ?? eo,
373
+ saveFile: n?.saveFile ?? to
374
+ }), Pt = {
375
+ compact: { rowHeight: 22, fontSize: 12 },
376
+ normal: { rowHeight: 28, fontSize: 13 },
377
+ comfortable: { rowHeight: 34, fontSize: 15 }
378
+ }, Fe = 52, Ut = 8, oo = 40, ro = 600, dt = 1e5, lo = (n) => n === null ? "" : String(n), so = (n, d) => {
379
+ const {
380
+ columns: r,
381
+ totalRows: i,
382
+ fetchRows: h,
383
+ queryKey: u,
384
+ density: m = "normal",
385
+ defaultColumnWidth: b = 120,
386
+ frozenRows: p = 0,
387
+ theme: R = "system",
388
+ className: Y,
389
+ style: W,
390
+ readOnly: w = !1,
391
+ sort: A = [],
392
+ filters: G = [],
393
+ search: ye,
394
+ searchHighlights: re,
395
+ currentSearchHit: P,
396
+ renderLoading: le,
397
+ renderEmpty: de,
398
+ labels: g,
399
+ icons: y,
400
+ platform: C,
401
+ onSortChange: j,
402
+ onFilterButtonClick: T,
403
+ onColumnResize: fe,
404
+ onColumnRename: F,
405
+ onAddColumn: se,
406
+ onCellChange: ke,
407
+ onDirtyChange: Ne,
408
+ onAppendRow: he,
409
+ onInsertRow: Te,
410
+ onDeleteRows: k,
411
+ onAutoFill: me,
412
+ onSelectionChange: $e,
413
+ onSelectionStats: B,
414
+ onCellKeyDown: Le,
415
+ onError: pe
416
+ } = n, $ = Se(() => qn(g), [g]), Ae = Se(() => Xn(y), [y]), ge = Se(() => no(C), [C]), D = n.rowHeight ?? Pt[m].rowHeight, Xe = Pt[m].fontSize, ht = E(null), X = E(null), qe = E(null), mt = E(null), [pt, Wt] = V(0), [Oe, Bt] = V(600), [_t, It] = V(0), [gt, vt] = V([]), wt = E(/* @__PURE__ */ new Map()), yt = E(null);
417
+ I(() => {
418
+ const e = wt.current, t = yt.current;
419
+ t && t.length === r.length && t.forEach((o, s) => {
420
+ const c = r[s]?.name;
421
+ c && c !== o && e.has(o) && (e.set(c, e.get(o)), e.delete(o));
422
+ }), yt.current = r.map((o) => o.name), vt(r.map((o) => e.get(o.name) ?? o.width ?? b));
423
+ }, [r, b]);
424
+ const Z = a(
425
+ (e) => gt[e] ?? r[e]?.width ?? b,
426
+ [gt, r, b]
427
+ ), Ye = a(
428
+ (e) => {
429
+ let t = Fe;
430
+ for (let o = 0; o < e; o++) t += Z(o);
431
+ return t;
432
+ },
433
+ [Z]
434
+ ), Pe = a(
435
+ (e, t) => {
436
+ const o = Math.max(oo, Math.round(t));
437
+ vt((c) => {
438
+ const l = [...c];
439
+ return l[e] = o, l;
440
+ });
441
+ const s = r[e]?.name;
442
+ s && wt.current.set(s, o), fe?.(e, o);
443
+ },
444
+ [r, fe]
445
+ );
446
+ I(() => {
447
+ const e = X.current;
448
+ if (!e) return;
449
+ const t = () => {
450
+ Bt(e.clientHeight), It(e.offsetWidth - e.clientWidth);
451
+ };
452
+ t();
453
+ const o = new ResizeObserver(() => t());
454
+ return o.observe(e), () => o.disconnect();
455
+ }, []);
456
+ const ee = 0, bt = Math.max(0, Math.floor(pt / D) - Ut), xt = Math.ceil((pt + Oe) / D) + Ut, { rows: be, total: L, status: Ct, invalidate: Rt } = Tn({
457
+ fetchRows: h,
458
+ totalRows: i,
459
+ columns: r,
460
+ sort: A,
461
+ filters: G,
462
+ search: ye,
463
+ queryKey: u,
464
+ frozenRows: p,
465
+ startRow: bt,
466
+ endRow: xt,
467
+ onError: pe
468
+ }), jt = Math.min(bt, Math.max(0, L - 1)), Xt = Math.min(L, xt), H = An({ onCellChange: ke, onDirtyChange: Ne }), Ue = a(
469
+ (e, t) => be.get(e)?.values[t] ?? null,
470
+ [be]
471
+ ), z = a(
472
+ (e, t) => {
473
+ const o = H.getEditedValue(e, t);
474
+ return o !== void 0 ? o : Ue(e, t);
475
+ },
476
+ [H, Ue]
477
+ ), He = a(
478
+ (e, t) => {
479
+ const o = r[t];
480
+ return o ? Vn(z(e, t), o, e) : "";
481
+ },
482
+ [r, z]
483
+ ), ce = a(
484
+ (e) => H.applyEdits(e, Ue),
485
+ [H, Ue]
486
+ ), [ne, We] = V([]), [x, te] = V(null), S = Se(() => Kn(ne), [ne]), J = S.length > 0 ? S[S.length - 1] : null, _ = ne.length > 0 ? ne[ne.length - 1] : null, K = a((e) => {
487
+ We(e ? [e] : []);
488
+ }, []), U = a((e) => {
489
+ We((t) => t.length > 0 ? [...t.slice(0, -1), e] : [e]);
490
+ }, []), xe = a((e) => {
491
+ We((t) => [...t, e]);
492
+ }, []), Je = E(!1), Be = E(!1), Qe = E(!1), ie = E(null), Ce = E(null), [M, _e] = V(null), [Ge, Mt] = V(""), Ie = E(null), Ze = E(!1), [Q, et] = V(null), [tt, Et] = V(""), je = E(null), [Re, Dt] = V(!1), [ve, St] = V(null), [nt, kt] = V(null), Nt = E(0), Tt = E(0), [ot, Me] = V(null), ae = a(
493
+ (e, t) => {
494
+ if (w) return !1;
495
+ const o = r[e]?.editable;
496
+ return o === void 0 ? !0 : typeof o == "function" ? o({ row: t }) : o;
497
+ },
498
+ [r, w]
499
+ ), qt = Se(() => {
500
+ const e = /* @__PURE__ */ new Set();
501
+ return re?.forEach((t) => e.add(`${t.row}:${t.col}`)), e;
502
+ }, [re]);
503
+ I(() => {
504
+ const e = X.current;
505
+ if (!P || !e) return;
506
+ const t = Math.max(0, (P.row - ee) * D), o = e.clientHeight, s = e.scrollTop;
507
+ (t < s || t > s + o - D) && (e.scrollTop = Math.max(0, t - o / 3));
508
+ }, [P, D, ee]), I(() => {
509
+ $e?.(ne);
510
+ }, [ne, $e]), I(() => {
511
+ if (!B) return;
512
+ if (S.length === 0) {
513
+ B(null);
514
+ return;
515
+ }
516
+ const e = ut(S);
517
+ if (e > dt) {
518
+ B({ count: e, numericCount: 0, sum: null, average: null });
519
+ return;
520
+ }
521
+ let t = 0, o = 0;
522
+ for (const s of S)
523
+ for (let c = s.r1; c <= s.r2; c++)
524
+ for (let l = s.c1; l <= s.c2; l++) {
525
+ const f = zn(z(c, l));
526
+ f !== null && (o += f, t++);
527
+ }
528
+ B({
529
+ count: e,
530
+ numericCount: t,
531
+ sum: t > 0 ? o : null,
532
+ average: t > 0 ? o / t : null
533
+ });
534
+ }, [S, be, H.version, B, z]);
535
+ const Yt = a(() => {
536
+ const e = X.current;
537
+ e && (qe.current && (qe.current.scrollLeft = e.scrollLeft), mt.current && (mt.current.scrollLeft = e.scrollLeft), Wt(e.scrollTop));
538
+ }, []), we = a(
539
+ (e, t, o) => {
540
+ ae(t, e) && (Me(null), _e({ row: e, col: t }), Mt(o ?? lo(z(e, t))));
541
+ },
542
+ [ae, z]
543
+ ), Lt = a(() => _e(null), []), q = a(() => {
544
+ if (!M) return;
545
+ const { row: e, col: t } = M, o = r[t];
546
+ if (_e(null), !o) return;
547
+ const s = z(e, t), c = Ft(Ge, o.type);
548
+ if (o.validate) {
549
+ const l = o.validate(c, { row: e });
550
+ if (l === !1 || typeof l == "string") {
551
+ ge.notify("error", typeof l == "string" ? l : "Invalid value");
552
+ return;
553
+ }
554
+ }
555
+ c !== s && ce([{ row: e, col: t, oldValue: s, newValue: c }]);
556
+ }, [M, r, Ge, z, ce, ge]);
557
+ I(() => {
558
+ M && Ie.current && (Ie.current.focus(), Ie.current.select());
559
+ }, [M]);
560
+ const Jt = a(
561
+ (e, t, o) => {
562
+ M && M.row === e && M.col === t || (M && q(), Me(null), o.shiftKey && x ? U({ start: x, end: { row: e, col: t } }) : o.ctrlKey || o.metaKey ? (te({ row: e, col: t }), xe({ start: { row: e, col: t }, end: { row: e, col: t } })) : (te({ row: e, col: t }), K({ start: { row: e, col: t }, end: { row: e, col: t } })), Je.current = !0);
563
+ },
564
+ [x, M, q, K, U, xe]
565
+ ), Qt = a(
566
+ (e, t) => {
567
+ Je.current && x && U({ start: x, end: { row: e, col: t } }), Be.current && ie.current !== null && U({
568
+ start: { row: ie.current, col: 0 },
569
+ end: { row: e, col: r.length - 1 }
570
+ }), Re && St(e);
571
+ },
572
+ [x, Re, r.length, U]
573
+ ), At = a(() => {
574
+ if (!_ || ve === null) return;
575
+ const e = Math.min(_.start.row, _.end.row), t = Math.max(_.start.row, _.end.row), o = Math.min(_.start.col, _.end.col), s = Math.max(_.start.col, _.end.col), c = Math.max(t, ve);
576
+ if (c <= t) return;
577
+ const l = [];
578
+ for (let f = t + 1; f <= c; f++) {
579
+ const N = e + (f - e) % (t - e + 1);
580
+ for (let ue = o; ue <= s; ue++)
581
+ ae(ue, f) && l.push({
582
+ row: f,
583
+ col: ue,
584
+ oldValue: z(f, ue),
585
+ newValue: z(N, ue)
586
+ });
587
+ }
588
+ ce(l), K({ start: { row: e, col: o }, end: { row: c, col: s } }), me?.({
589
+ sourceRange: { start: { row: e, col: o }, end: { row: t, col: s } },
590
+ direction: "down",
591
+ toEnd: !1
592
+ });
593
+ }, [_, ve, ae, z, ce, K, me]);
594
+ I(() => {
595
+ const e = () => {
596
+ Je.current = !1, Be.current = !1, Qe.current = !1, Re && ve !== null && At(), Dt(!1), St(null);
597
+ };
598
+ return window.addEventListener("mouseup", e), () => window.removeEventListener("mouseup", e);
599
+ }, [Re, ve, At]);
600
+ const Gt = a((e) => {
601
+ e.preventDefault(), e.stopPropagation(), Dt(!0);
602
+ }, []), Ve = a(
603
+ (e, t) => ({
604
+ start: { row: e, col: 0 },
605
+ end: { row: t, col: r.length - 1 }
606
+ }),
607
+ [r.length]
608
+ ), Zt = a(
609
+ (e, t) => {
610
+ M && q(), Me(null), t.shiftKey && ie.current !== null ? U(Ve(ie.current, e)) : t.ctrlKey || t.metaKey ? (ie.current = e, te({ row: e, col: 0 }), xe(Ve(e, e))) : (ie.current = e, te({ row: e, col: 0 }), K(Ve(e, e))), Be.current = !0;
611
+ },
612
+ [M, q, Ve, K, U, xe]
613
+ ), Ee = a(
614
+ (e, t) => ({
615
+ start: { row: 0, col: e },
616
+ end: { row: L - 1, col: t }
617
+ }),
618
+ [L]
619
+ ), en = a(
620
+ (e, t) => {
621
+ Q === null && (M && q(), Me(null), t.shiftKey && Ce.current !== null ? U(Ee(Ce.current, e)) : t.ctrlKey || t.metaKey ? (Ce.current = e, te({ row: 0, col: e }), xe(Ee(e, e))) : (Ce.current = e, te({ row: 0, col: e }), K(Ee(e, e))), Qe.current = !0);
622
+ },
623
+ [
624
+ Q,
625
+ M,
626
+ q,
627
+ Ee,
628
+ K,
629
+ U,
630
+ xe
631
+ ]
632
+ ), tn = a(
633
+ (e) => {
634
+ Qe.current && Ce.current !== null && U(Ee(Ce.current, e));
635
+ },
636
+ [Ee, U]
637
+ ), rt = a(() => {
638
+ M && q(), te({ row: 0, col: 0 }), K({
639
+ start: { row: 0, col: 0 },
640
+ end: { row: L - 1, col: r.length - 1 }
641
+ });
642
+ }, [M, q, L, r.length, K]), nn = a(
643
+ (e) => {
644
+ F && (_e(null), K(null), te(null), et(e), Et(r[e]?.name ?? ""));
645
+ },
646
+ [F, r, K]
647
+ ), Ht = a(() => {
648
+ if (Q === null) return;
649
+ const e = tt.trim();
650
+ e && e !== r[Q]?.name && F?.(Q, e), et(null);
651
+ }, [Q, tt, r, F]);
652
+ I(() => {
653
+ Q !== null && je.current && (je.current.focus(), je.current.select());
654
+ }, [Q]);
655
+ const on = a(
656
+ (e) => {
657
+ const t = r[e]?.name;
658
+ if (!t || !j) return;
659
+ const o = A.find((c) => c.column === t);
660
+ let s;
661
+ o ? o.direction === "asc" ? s = A.map((c) => c.column === t ? { ...c, direction: "desc" } : c) : s = A.filter((c) => c.column !== t) : s = [...A, { column: t, direction: "asc" }], j(s);
662
+ },
663
+ [r, j, A]
664
+ ), rn = a(
665
+ (e, t) => {
666
+ if (t.stopPropagation(), !T) return;
667
+ const o = t.currentTarget.getBoundingClientRect();
668
+ T(e, o);
669
+ },
670
+ [T]
671
+ ), ln = a(
672
+ (e, t) => {
673
+ t.preventDefault(), t.stopPropagation(), kt(e), Nt.current = t.clientX, Tt.current = Z(e);
674
+ },
675
+ [Z]
676
+ );
677
+ I(() => {
678
+ if (nt === null) return;
679
+ const e = (o) => {
680
+ Pe(
681
+ nt,
682
+ Tt.current + (o.clientX - Nt.current)
683
+ );
684
+ }, t = () => kt(null);
685
+ return window.addEventListener("mousemove", e), window.addEventListener("mouseup", t), () => {
686
+ window.removeEventListener("mousemove", e), window.removeEventListener("mouseup", t);
687
+ };
688
+ }, [nt, Pe]);
689
+ const lt = E(null), sn = a(
690
+ (e) => {
691
+ lt.current || (lt.current = document.createElement("canvas"));
692
+ const t = lt.current.getContext("2d");
693
+ if (!t) return;
694
+ const o = X.current?.querySelector(".vox-cell");
695
+ if (o) {
696
+ const c = getComputedStyle(o);
697
+ t.font = `${c.fontWeight} ${c.fontSize} ${c.fontFamily}`;
698
+ } else
699
+ t.font = `${Xe}px sans-serif`;
700
+ let s = t.measureText(r[e]?.name ?? "").width + 48;
701
+ be.forEach((c, l) => {
702
+ const f = He(l, e);
703
+ f && (s = Math.max(s, t.measureText(f).width));
704
+ }), Pe(e, Math.min(ro, s + 16));
705
+ },
706
+ [r, be, He, Pe, Xe]
707
+ ), ze = a(async () => {
708
+ if (S.length !== 0) {
709
+ if (ut(S) > dt) {
710
+ ge.notify("error", "Selection is too large to copy");
711
+ return;
712
+ }
713
+ try {
714
+ await ge.writeText(Pn(S, He));
715
+ } catch (e) {
716
+ pe?.(e, { phase: "commit" });
717
+ }
718
+ }
719
+ }, [S, ge, He, pe]), st = a(async () => {
720
+ if (w || (await ze(), S.length === 0 || ut(S) > dt)) return;
721
+ const e = [], t = /* @__PURE__ */ new Set();
722
+ for (const o of S)
723
+ for (let s = o.r1; s <= o.r2; s++)
724
+ for (let c = o.c1; c <= o.c2; c++) {
725
+ const l = `${s}:${c}`;
726
+ t.has(l) || !ae(c, s) || (t.add(l), e.push({ row: s, col: c, oldValue: z(s, c), newValue: null }));
727
+ }
728
+ ce(e);
729
+ }, [w, ze, S, ae, z, ce]), ct = a(async () => {
730
+ if (!(w || !x))
731
+ try {
732
+ const e = await ge.readText(), t = Un(e), o = [];
733
+ for (let s = 0; s < t.length; s++) {
734
+ const c = t[s];
735
+ for (let l = 0; l < c.length; l++) {
736
+ const f = x.row + s, N = x.col + l;
737
+ f >= L || N >= r.length || !ae(N, f) || o.push({
738
+ row: f,
739
+ col: N,
740
+ oldValue: z(f, N),
741
+ newValue: Ft(c[l] ?? "", r[N]?.type)
742
+ });
743
+ }
744
+ }
745
+ ce(o);
746
+ } catch (e) {
747
+ pe?.(e, { phase: "commit" });
748
+ }
749
+ }, [
750
+ w,
751
+ x,
752
+ ge,
753
+ L,
754
+ r,
755
+ ae,
756
+ z,
757
+ ce,
758
+ pe
759
+ ]), O = a(
760
+ (e, t, o) => {
761
+ const s = Math.max(0, Math.min(L - 1, e)), c = Math.max(0, Math.min(r.length - 1, t));
762
+ te({ row: s, col: c }), o && _ ? U({ start: _.start, end: { row: s, col: c } }) : K({ start: { row: s, col: c }, end: { row: s, col: c } });
763
+ const l = X.current;
764
+ if (l) {
765
+ const f = (s - ee) * D;
766
+ f < l.scrollTop ? l.scrollTop = f : f + D > l.scrollTop + l.clientHeight && (l.scrollTop = f + D - l.clientHeight);
767
+ }
768
+ },
769
+ [
770
+ L,
771
+ r.length,
772
+ _,
773
+ U,
774
+ K,
775
+ ee,
776
+ D
777
+ ]
778
+ ), cn = a(
779
+ (e) => {
780
+ if (Q !== null) return;
781
+ if (x && Le) {
782
+ const l = r[x.col];
783
+ if (l && (Le(e, {
784
+ row: x.row,
785
+ col: x.col,
786
+ value: z(x.row, x.col),
787
+ column: l
788
+ }), e.defaultPrevented))
789
+ return;
790
+ }
791
+ const t = e.ctrlKey || e.metaKey;
792
+ if (t && !M) {
793
+ if (e.key === "a") {
794
+ e.preventDefault(), rt();
795
+ return;
796
+ }
797
+ if (e.key === "c") {
798
+ e.preventDefault(), ze();
799
+ return;
800
+ }
801
+ if (!w && e.key === "x") {
802
+ e.preventDefault(), st();
803
+ return;
804
+ }
805
+ if (!w && e.key === "v") {
806
+ e.preventDefault(), ct();
807
+ return;
808
+ }
809
+ if (!w && e.key === "z") {
810
+ e.preventDefault(), H.undo();
811
+ return;
812
+ }
813
+ if (!w && e.key === "y") {
814
+ e.preventDefault(), H.redo();
815
+ return;
816
+ }
817
+ }
818
+ if (M) {
819
+ e.key === "Enter" && !Ze.current ? (e.preventDefault(), q(), O(M.row + 1, M.col, !1)) : e.key === "Escape" ? (e.preventDefault(), Lt()) : e.key === "Tab" && (e.preventDefault(), q(), O(M.row, M.col + (e.shiftKey ? -1 : 1), !1));
820
+ return;
821
+ }
822
+ if (!x || w && !e.key.startsWith("Arrow") && e.key !== "Tab") return;
823
+ const { row: o, col: s } = x, c = e.shiftKey && e.key.startsWith("Arrow");
824
+ e.key === "ArrowDown" ? (e.preventDefault(), O(o + 1, s, c)) : e.key === "ArrowUp" ? (e.preventDefault(), O(o - 1, s, c)) : e.key === "ArrowRight" ? (e.preventDefault(), O(o, s + 1, c)) : e.key === "ArrowLeft" ? (e.preventDefault(), O(o, s - 1, c)) : e.key === "Tab" ? (e.preventDefault(), O(o, s + (e.shiftKey ? -1 : 1), !1)) : e.key === "Enter" ? (e.preventDefault(), o >= L - 1 ? he?.(L) : O(o + 1, s, !1)) : e.key === "Home" ? (e.preventDefault(), O(o, 0, c), t && O(0, 0, c)) : e.key === "End" ? (e.preventDefault(), O(t ? L - 1 : o, r.length - 1, c)) : e.key === "PageDown" ? (e.preventDefault(), O(o + Math.floor(Oe / D), s, c)) : e.key === "PageUp" ? (e.preventDefault(), O(o - Math.floor(Oe / D), s, c)) : !w && (e.key === "Delete" || e.key === "Backspace") ? (e.preventDefault(), we(o, s, "")) : !w && e.key === "F2" ? (e.preventDefault(), we(o, s)) : !w && e.key.length === 1 && !t && !e.altKey && we(o, s, e.key);
825
+ },
826
+ [
827
+ Q,
828
+ x,
829
+ Le,
830
+ r,
831
+ z,
832
+ M,
833
+ w,
834
+ rt,
835
+ ze,
836
+ st,
837
+ ct,
838
+ H,
839
+ q,
840
+ Lt,
841
+ O,
842
+ L,
843
+ he,
844
+ Oe,
845
+ D,
846
+ we
847
+ ]
848
+ ), an = a(
849
+ (e) => {
850
+ if (w) {
851
+ e.preventDefault();
852
+ return;
853
+ }
854
+ e.preventDefault(), Me({ x: e.clientX, y: e.clientY });
855
+ },
856
+ [w]
857
+ ), un = a(() => {
858
+ if (S.length === 0) return;
859
+ const e = /* @__PURE__ */ new Set();
860
+ for (const t of S) for (let o = t.r1; o <= t.r2; o++) e.add(o);
861
+ k?.(Array.from(e).sort((t, o) => t - o));
862
+ }, [S, k]);
863
+ kn(
864
+ d,
865
+ () => ({
866
+ scrollToRow: (e) => {
867
+ X.current && (X.current.scrollTop = Math.max(0, (e - ee) * D));
868
+ },
869
+ scrollToCell: (e, t) => {
870
+ X.current && (X.current.scrollTop = Math.max(0, (e - ee) * D));
871
+ let o = 0;
872
+ for (let s = 0; s < t; s++) o += Z(s);
873
+ X.current && (X.current.scrollLeft = o);
874
+ },
875
+ focusCell: (e, t) => {
876
+ te({ row: e, col: t }), K({ start: { row: e, col: t }, end: { row: e, col: t } }), ht.current?.focus();
877
+ },
878
+ getSelection: () => ne,
879
+ setSelection: (e) => We(e),
880
+ startEdit: (e, t) => we(e, t),
881
+ getLocalEdits: () => H.getLocalEdits(),
882
+ clearLocalEdits: () => H.clear(),
883
+ undo: () => H.undo(),
884
+ redo: () => H.redo(),
885
+ invalidate: () => Rt()
886
+ }),
887
+ [
888
+ ee,
889
+ D,
890
+ Z,
891
+ ne,
892
+ K,
893
+ we,
894
+ H,
895
+ Rt
896
+ ]
897
+ );
898
+ const dn = Fe + r.reduce((e, t, o) => e + Z(o), 0), fn = Math.max(0, L - ee) * D, hn = J ? J.r2 : null, mn = J ? J.c2 : null, pn = (e) => {
899
+ if (w || !j && !T) return null;
900
+ const t = r[e]?.name ?? "", o = A.findIndex((N) => N.column === t), s = o >= 0 ? A[o] : void 0, c = G.some((N) => N.column === t), l = s ? s.direction === "asc" ? Ae.sortAscending : Ae.sortDescending : Ae.sortUnsorted, f = c ? Ae.filterActive : Ae.filter;
901
+ return /* @__PURE__ */ oe("span", { className: "vox-header-actions", onMouseDown: (N) => N.stopPropagation(), children: [
902
+ T && /* @__PURE__ */ v(
903
+ "button",
904
+ {
905
+ type: "button",
906
+ className: "vox-header-btn",
907
+ title: "Filter",
908
+ "aria-label": `Filter ${t}`,
909
+ onClick: (N) => rn(e, N),
910
+ children: /* @__PURE__ */ v(f, { size: 13 })
911
+ }
912
+ ),
913
+ j && /* @__PURE__ */ oe(
914
+ "button",
915
+ {
916
+ type: "button",
917
+ className: "vox-header-btn",
918
+ title: "Sort",
919
+ "aria-label": `Sort ${t}`,
920
+ onClick: (N) => {
921
+ N.stopPropagation(), on(e);
922
+ },
923
+ children: [
924
+ /* @__PURE__ */ v(l, { size: 13 }),
925
+ s && A.length > 1 && /* @__PURE__ */ v("sup", { children: o + 1 })
926
+ ]
927
+ }
928
+ )
929
+ ] });
930
+ }, gn = (e, t) => {
931
+ const o = be.get(e), s = S.some(
932
+ (l) => e >= l.r1 && e <= l.r2 && l.c1 === 0 && l.c2 === r.length - 1
933
+ ), c = o ? Math.floor(o.ordinal) : e + 1;
934
+ return /* @__PURE__ */ oe(
935
+ "div",
936
+ {
937
+ className: "vox-row",
938
+ style: { top: t, height: D },
939
+ "aria-rowindex": e + 1,
940
+ children: [
941
+ /* @__PURE__ */ v(
942
+ "div",
943
+ {
944
+ className: `vox-row-header${s ? " vox-row-header--selected" : ""}`,
945
+ style: { width: Fe, height: D },
946
+ onMouseDown: (l) => Zt(e, l),
947
+ onMouseEnter: () => Be.current && ie.current !== null && U(Ve(ie.current, e)),
948
+ children: c.toLocaleString()
949
+ }
950
+ ),
951
+ r.map((l, f) => {
952
+ const N = On(S, e, f), ue = x?.row === e && x?.col === f, yn = M?.row === e && M?.col === f, bn = H.isDirty(e, f), xn = qt.has(`${e}:${f}`), Cn = P?.row === e && P?.col === f, Rn = !Re && e === hn && f === mn && J !== null && !w, Mn = Re && ve !== null && J !== null && e > J.r2 && e <= ve && f >= J.c1 && f <= J.c2, En = l.align ?? Hn(l.type), Dn = "vox-cell" + (N ? " vox-cell--selected" : "") + (ue ? " vox-cell--active" : "") + (bn ? " vox-cell--dirty" : "") + (Mn ? " vox-cell--selected" : "") + (xn ? " vox-cell--search-hit" : "") + (Cn ? " vox-cell--search-current" : "");
953
+ return /* @__PURE__ */ oe(
954
+ "div",
955
+ {
956
+ className: Dn,
957
+ role: "gridcell",
958
+ "aria-selected": N,
959
+ "aria-colindex": f + 1,
960
+ style: {
961
+ width: Z(f),
962
+ height: D,
963
+ justifyContent: co(En)
964
+ },
965
+ onMouseDown: (it) => Jt(e, f, it),
966
+ onMouseEnter: () => Qt(e, f),
967
+ onDoubleClick: () => we(e, f),
968
+ onContextMenu: an,
969
+ children: [
970
+ yn ? /* @__PURE__ */ v(
971
+ "input",
972
+ {
973
+ ref: Ie,
974
+ className: "vox-cell-input",
975
+ value: Ge,
976
+ onChange: (it) => Mt(it.target.value),
977
+ onBlur: q,
978
+ onCompositionStart: () => Ze.current = !0,
979
+ onCompositionEnd: () => Ze.current = !1
980
+ }
981
+ ) : He(e, f),
982
+ Rn && /* @__PURE__ */ v(
983
+ "div",
984
+ {
985
+ className: "vox-fill-handle",
986
+ onMouseDown: Gt
987
+ }
988
+ )
989
+ ]
990
+ },
991
+ f
992
+ );
993
+ })
994
+ ]
995
+ },
996
+ e
997
+ );
998
+ }, Vt = [];
999
+ for (let e = jt; e < Xt; e++)
1000
+ Vt.push(gn(e, (e - ee) * D));
1001
+ const vn = {
1002
+ "--vox-row-height": `${D}px`,
1003
+ "--vox-font-size": `${Xe}px`,
1004
+ "--vox-row-header-width": `${Fe}px`,
1005
+ ...W
1006
+ }, wn = L === 0 && Ct !== "loading";
1007
+ return /* @__PURE__ */ oe(
1008
+ "div",
1009
+ {
1010
+ ref: ht,
1011
+ className: `vox-sheet${Y ? ` ${Y}` : ""}`,
1012
+ "data-vox-theme": R === "system" ? void 0 : R,
1013
+ role: "grid",
1014
+ "aria-rowcount": L,
1015
+ "aria-colcount": r.length,
1016
+ "aria-readonly": w,
1017
+ tabIndex: 0,
1018
+ style: vn,
1019
+ onKeyDown: cn,
1020
+ onContextMenu: w ? (e) => e.preventDefault() : void 0,
1021
+ children: [
1022
+ /* @__PURE__ */ oe("div", { className: "vox-header-wrap", style: { paddingRight: _t }, children: [
1023
+ /* @__PURE__ */ v(
1024
+ "div",
1025
+ {
1026
+ className: "vox-corner",
1027
+ style: { width: Fe },
1028
+ onClick: rt
1029
+ }
1030
+ ),
1031
+ /* @__PURE__ */ oe("div", { className: "vox-header", ref: qe, role: "row", children: [
1032
+ r.map((e, t) => {
1033
+ const o = S.some(
1034
+ (l) => t >= l.c1 && t <= l.c2 && l.r1 === 0 && l.r2 === L - 1
1035
+ ), s = e.name, c = A.find((l) => l.column === s);
1036
+ return /* @__PURE__ */ oe(
1037
+ "div",
1038
+ {
1039
+ className: "vox-header-cell",
1040
+ role: "columnheader",
1041
+ "aria-colindex": t + 1,
1042
+ "aria-sort": c ? c.direction === "asc" ? "ascending" : "descending" : "none",
1043
+ style: {
1044
+ width: Z(t),
1045
+ background: o ? "var(--vox-color-selection-bg)" : void 0
1046
+ },
1047
+ onMouseDown: (l) => en(t, l),
1048
+ onMouseEnter: () => tn(t),
1049
+ children: [
1050
+ Q === t ? /* @__PURE__ */ v(
1051
+ "input",
1052
+ {
1053
+ ref: je,
1054
+ className: "vox-cell-input",
1055
+ value: tt,
1056
+ onChange: (l) => Et(l.target.value),
1057
+ onBlur: Ht,
1058
+ onMouseDown: (l) => l.stopPropagation(),
1059
+ onKeyDown: (l) => {
1060
+ l.key === "Enter" ? (l.preventDefault(), Ht()) : l.key === "Escape" && (l.preventDefault(), et(null));
1061
+ }
1062
+ }
1063
+ ) : /* @__PURE__ */ v(
1064
+ "span",
1065
+ {
1066
+ className: "vox-header-label",
1067
+ onDoubleClick: F ? (l) => {
1068
+ l.stopPropagation(), nn(t);
1069
+ } : void 0,
1070
+ children: e.name
1071
+ }
1072
+ ),
1073
+ pn(t),
1074
+ /* @__PURE__ */ v(
1075
+ "div",
1076
+ {
1077
+ className: "vox-resize-handle",
1078
+ onMouseDown: (l) => ln(t, l),
1079
+ onDoubleClick: (l) => {
1080
+ l.preventDefault(), l.stopPropagation(), sn(t);
1081
+ }
1082
+ }
1083
+ )
1084
+ ]
1085
+ },
1086
+ t
1087
+ );
1088
+ }),
1089
+ se && /* @__PURE__ */ v(
1090
+ "button",
1091
+ {
1092
+ type: "button",
1093
+ className: "vox-add-column",
1094
+ title: "Add column",
1095
+ onClick: () => se(r.length),
1096
+ children: "+"
1097
+ }
1098
+ )
1099
+ ] })
1100
+ ] }),
1101
+ /* @__PURE__ */ v("div", { className: "vox-body", ref: X, onScroll: Yt, children: /* @__PURE__ */ oe(
1102
+ "div",
1103
+ {
1104
+ className: "vox-scroll-spacer",
1105
+ style: { height: fn, width: dn },
1106
+ children: [
1107
+ Vt,
1108
+ S.map((e, t) => /* @__PURE__ */ v(
1109
+ "div",
1110
+ {
1111
+ className: "vox-selection-outline",
1112
+ style: {
1113
+ left: Ye(e.c1),
1114
+ top: (e.r1 - ee) * D,
1115
+ width: Ye(e.c2) + Z(e.c2) - Ye(e.c1),
1116
+ height: (e.r2 - e.r1 + 1) * D
1117
+ }
1118
+ },
1119
+ `sel-${t}`
1120
+ ))
1121
+ ]
1122
+ }
1123
+ ) }),
1124
+ Ct === "loading" && L === 0 && /* @__PURE__ */ v("div", { className: "vox-overlay", children: le ? le() : $.loading }),
1125
+ wn && /* @__PURE__ */ v("div", { className: "vox-overlay", children: de ? de() : $.empty }),
1126
+ ot && /* @__PURE__ */ v(
1127
+ io,
1128
+ {
1129
+ x: ot.x,
1130
+ y: ot.y,
1131
+ onClose: () => Me(null),
1132
+ items: [
1133
+ {
1134
+ label: $.contextCut,
1135
+ action: () => {
1136
+ st();
1137
+ },
1138
+ disabled: !J
1139
+ },
1140
+ {
1141
+ label: $.contextCopy,
1142
+ action: () => {
1143
+ ze();
1144
+ },
1145
+ disabled: !J
1146
+ },
1147
+ {
1148
+ label: $.contextPaste,
1149
+ action: () => {
1150
+ ct();
1151
+ },
1152
+ disabled: !x
1153
+ },
1154
+ ...Te ? [
1155
+ "sep",
1156
+ {
1157
+ label: $.contextInsertRowAbove,
1158
+ action: () => x && Te(x.row, "above"),
1159
+ disabled: !x
1160
+ },
1161
+ {
1162
+ label: $.contextInsertRowBelow,
1163
+ action: () => x && Te(x.row, "below"),
1164
+ disabled: !x
1165
+ }
1166
+ ] : [],
1167
+ ...k ? [
1168
+ "sep",
1169
+ {
1170
+ label: $.contextDeleteRows,
1171
+ action: un,
1172
+ disabled: S.length === 0
1173
+ }
1174
+ ] : [],
1175
+ "sep",
1176
+ {
1177
+ label: $.contextUndo,
1178
+ action: () => H.undo(),
1179
+ disabled: !H.canUndo()
1180
+ },
1181
+ {
1182
+ label: $.contextRedo,
1183
+ action: () => H.redo(),
1184
+ disabled: !H.canRedo()
1185
+ }
1186
+ ]
1187
+ }
1188
+ )
1189
+ ]
1190
+ }
1191
+ );
1192
+ }, co = (n) => n === "right" ? "flex-end" : n === "center" ? "center" : "flex-start", io = ({
1193
+ x: n,
1194
+ y: d,
1195
+ items: r,
1196
+ onClose: i
1197
+ }) => {
1198
+ const h = E(null);
1199
+ return I(() => {
1200
+ const u = (m) => {
1201
+ h.current && !h.current.contains(m.target) && i();
1202
+ };
1203
+ return document.addEventListener("mousedown", u), () => document.removeEventListener("mousedown", u);
1204
+ }, [i]), /* @__PURE__ */ v("div", { ref: h, className: "vox-context-menu", style: { left: n, top: d }, role: "menu", children: r.map(
1205
+ (u, m) => u === "sep" ? /* @__PURE__ */ v("div", { className: "vox-context-separator" }, m) : /* @__PURE__ */ v(
1206
+ "button",
1207
+ {
1208
+ type: "button",
1209
+ className: "vox-context-item",
1210
+ role: "menuitem",
1211
+ disabled: u.disabled,
1212
+ onClick: () => {
1213
+ u.action(), i();
1214
+ },
1215
+ children: u.label
1216
+ },
1217
+ m
1218
+ )
1219
+ ) });
1220
+ }, fo = Sn(so);
1221
+ export {
1222
+ $t as DEFAULT_ICONS,
1223
+ Ot as DEFAULT_LABELS,
1224
+ fo as VoxSheet
1225
+ };
1226
+ //# sourceMappingURL=index.js.map