UNPKG

hightable

Version:

A dynamic windowed scrolling table component for react

968 lines (967 loc) 30.4 kB
import { jsx as m, jsxs as A } from "react/jsx-runtime"; import { useState as O, useCallback as x, createContext as Je, useContext as Xe, useMemo as H, useEffect as T, useRef as K } from "react"; import { flushSync as Ue } from "react-dom"; function Ge(e) { const n = e.then((t) => (n.resolved = t, t)).catch((t) => { throw n.rejected = t, t; }); return n; } function we(e) { const n = Promise.resolve(e); return n.resolved = e, n; } function ge() { let e, n; const t = Ge(new Promise((r, o) => { e = r, n = o; })); return t.resolve = e, t.reject = n, t; } function Qe(e) { return { index: ge(), cells: Object.fromEntries(e.map((n) => [n, ge()])) }; } function Ye(e, n, t) { const r = new Array(n).fill(null).map(() => Qe(t)); return e.then((o) => { o.length !== n && console.warn(`Expected ${n} rows, got ${o.length}`), o.forEach( (i, a) => { const u = r[a]; if (u === void 0) throw new Error(`Expected row ${a} to exist`); for (const s of t) { const l = u.cells[s]; if (l === void 0) throw new Error(`Expected cell ${s} to exist in row ${a}`); i.cells[s] instanceof Promise ? i.cells[s].then((c) => { l.resolve(c); }).catch((c) => { l.reject(c); }) : l.resolve(i.cells[s]); } i.index instanceof Promise ? i.index.then((s) => { u.index.resolve(s); }).catch((s) => { u.index.reject(s); }) : u.index.resolve(i.index); } ); }).catch((o) => { r.forEach((i) => { for (const a of Object.values(i.cells)) a.reject(o); i.index.reject(o); }); }), r; } async function Ze(e) { const n = e.index, t = Object.values(e.cells), r = Object.keys(e.cells), [o, ...i] = await Promise.all([n, ...t]); return { index: o, cells: Object.fromEntries(r.map((a, u) => [a, i[u]])) }; } function Mn(e) { return Promise.all(e.map(Ze)); } function en(e) { return e.getColumn ? e.getColumn : function({ column: t, start: r = 0, end: o = e.numRows }) { if (!e.header.includes(t)) throw new Error(`Invalid column: ${t}`); return Promise.all(e.rows({ start: r, end: o }).map((i) => i.cells[t])); }; } async function Ee({ data: e, column: n }) { if (!e.header.includes(n)) throw new Error(`Invalid column: ${n}`); const r = (await en(e)({ column: n })).map((u, s) => ({ value: u, index: s })), o = Array.from(r).sort(({ value: u }, { value: s }) => u < s ? -1 : u > s ? 1 : 0), i = o.length; return o.reduce(({ lastValue: u, lastRank: s, ranks: l }, { value: c, index: h }, w) => c === u ? (l[h] = s, { ranks: l, lastValue: u, lastRank: s }) : (l[h] = w, { ranks: l, lastValue: c, lastRank: w }), { ranks: Array(i).fill(-1), lastValue: void 0, lastRank: 0 }).ranks; } function Ie(e) { if (!(0 in e)) throw new Error("orderBy should have at least one element"); const n = e[0].ranks.length; return Array.from({ length: n }, (o, i) => i).sort((o, i) => { for (const { direction: a, ranks: u } of e) { const s = u[o], l = u[i]; if (s === void 0 || l === void 0) throw new Error("Invalid ranks"); const c = a === "ascending" ? 1 : -1; if (s < l) return -c; if (s > l) return c; } return 0; }); } function Se({ data: e }) { const { numRows: n } = e, t = Array.from({ length: n }, (r, o) => o); return Promise.resolve(t); } function Nn(e) { if (e.sortable) return e; const n = /* @__PURE__ */ new Map(); return { ...e, rows({ start: t, end: r, orderBy: o }) { if (o && o.length > 0) { if (o.some(({ column: c }) => !e.header.includes(c))) throw new Error(`Invalid orderBy field: ${o.map(({ column: c }) => c).join(", ")}`); const a = [...o, { column: "", direction: "ascending" }].map(async ({ column: c, direction: h }) => { const w = n.get(c) ?? (c === "" ? Se({ data: e }) : Ee({ data: e, column: c })); n.has(c) || n.set(c, w); const R = await w; return { column: c, direction: h, ranks: R }; }), l = Promise.all(a).then(Ie).then((c) => c.slice(t, r)).then((c) => Promise.all( // TODO(SL): optimize to fetch groups of rows instead of individual rows? // if so: maybe the 'reverse' above should be done after fetching the rows c.map((h) => { const w = e.rows({ start: h, end: h + 1 }); if (!(0 in w)) throw new Error("data.rows should have return one async row"); return w[0]; }) )); return Ye(l, r - t, e.header); } else return e.rows({ start: t, end: r }); }, sortable: !0 }; } function Ln(e) { if (!(0 in e)) return { header: [], numRows: 0, rows: () => [], getColumn: () => Promise.resolve([]) }; const n = Object.keys(e[0]); return { header: n, numRows: e.length, rows({ start: t, end: r }) { return e.slice(t, r).map((o, i) => ({ index: we(t + i), cells: Object.fromEntries(Object.entries(o).map(([a, u]) => [a, we(u)])) })); }, getColumn({ column: t, start: r = 0, end: o = e.length }) { if (!n.includes(t)) throw new Error(`Invalid column: ${t}`); return Promise.resolve(e.slice(r, o).map((i) => i[t])); } }; } function N(e) { return Number.isInteger(e) && e >= 0; } function Q(e) { return N(e.start) && N(e.end) && e.end > e.start; } function z(e) { if (e.length === 0) return !0; if (e.some((n) => !Q(n))) return !1; for (let n = 0; n < e.length - 1; n++) { const t = e[n], r = e[n + 1]; if (!t || !r || t.end >= r.start) return !1; } return !0; } function re({ ranges: e, index: n }) { if (!N(n)) throw new Error("Invalid index"); if (!z(e)) throw new Error("Invalid ranges"); return e.some((t) => t.start <= n && n < t.end); } function ne({ ranges: e, length: n }) { if (!z(e)) throw new Error("Invalid ranges"); if (n && !N(n)) throw new Error("Invalid length"); return e.length === 1 && 0 in e && e[0].start === 0 && e[0].end === n; } function nn({ ranges: e, length: n }) { if (!z(e)) throw new Error("Invalid ranges"); if (n && !N(n)) throw new Error("Invalid length"); return ne({ ranges: e, length: n }) ? [] : [{ start: 0, end: n }]; } function oe({ ranges: e, range: n }) { if (!z(e)) throw new Error("Invalid ranges"); if (!Q(n)) throw new Error("Invalid range"); const t = [], { start: r, end: o } = n; let i = 0; for (; i < e.length; ) { const a = e[i]; if (!a) throw new Error("Invalid range"); if (a.end >= r) break; t.push({ ...a }), i++; } for (; i < e.length; ) { const a = e[i]; if (!a) throw new Error("Invalid range"); if (a.start > o) break; n.start = Math.min(n.start, a.start), n.end = Math.max(n.end, a.end), i++; } for (t.push(n); i < e.length; ) { const a = e[i]; if (!a) throw new Error("Invalid range"); t.push({ ...a }), i++; } return t; } function tn({ ranges: e, index: n }) { return oe({ ranges: e, range: { start: n, end: n + 1 } }); } function Ce({ ranges: e, range: n }) { if (!z(e)) throw new Error("Invalid ranges"); if (!Q(n)) throw new Error("Invalid range"); const t = [], { start: r, end: o } = n; let i = 0; for (; i < e.length; ) { const a = e[i]; if (!a) throw new Error("Invalid range"); if (a.end >= r) break; t.push({ ...a }), i++; } for (; i < e.length; ) { const a = e[i]; if (!a) throw new Error("Invalid range"); if (a.start >= o) break; a.start < r && t.push({ start: a.start, end: r }), a.end > o && t.push({ start: o, end: a.end }), i++; } for (; i < e.length; ) { const a = e[i]; if (!a) throw new Error("Invalid range"); t.push({ ...a }), i++; } return t; } function ke({ ranges: e, anchor: n, index: t }) { if (!z(e)) throw new Error("Invalid ranges"); if (n === void 0) return e; if (!N(n)) throw new Error("Invalid anchor"); if (!N(t)) throw new Error("Invalid index"); if (n === t) return e; const r = n < t ? { start: n, end: t + 1 } : { start: t, end: n + 1 }; if (!Q(r)) throw new Error("Invalid range"); return re({ ranges: e, index: n }) ? oe({ ranges: e, range: r }) : Ce({ ranges: e, range: r }); } function rn({ ranges: e, index: n }) { if (!N(n)) throw new Error("Invalid index"); const t = { start: n, end: n + 1 }; return re({ ranges: e, index: n }) ? Ce({ ranges: e, range: t }) : oe({ ranges: e, range: t }); } function on({ selection: e, index: n }) { return { ranges: rn({ ranges: e.ranges, index: n }), anchor: n }; } function sn({ selection: e, index: n }) { return { ranges: ke({ ranges: e.ranges, anchor: e.anchor, index: n }), anchor: e.anchor }; } function ln(e) { const n = e.length, t = Array(n).fill(-1); return e.forEach((r, o) => { if (r < 0 || r >= n) throw new Error("Invalid index: out of bounds"); if (!Number.isInteger(r)) throw new Error("Invalid index: not an integer"); if (t[r] !== -1) throw new Error("Duplicate index"); t[r] = o; }), t; } function ve({ index: e, array: n }) { const t = n[e]; if (t === void 0) throw new Error("Data index not found in the data frame"); return t; } function me({ selection: e, permutationIndexes: n }) { const t = n.length, { ranges: r, anchor: o } = e; if (!z(e.ranges)) throw new Error("Invalid ranges"); if (o !== void 0 && !N(o)) throw new Error("Invalid anchor"); let i = []; if (r.length === 0) i = []; else if (r.length === 1 && 0 in r && r[0].start === 0 && r[0].end === t) i = [{ start: 0, end: t }]; else for (const u of r) { const { start: s, end: l } = u; for (let c = s; c < l; c++) i = tn({ ranges: i, index: ve({ index: c, array: n }) }); } const a = o !== void 0 ? ve({ index: o, array: n }) : void 0; return { ranges: i, anchor: a }; } async function cn({ tableIndex: e, selection: n, orderBy: t, data: r, ranksMap: o, setRanksMap: i }) { if (!r.sortable) throw new Error("Data frame is not sortable"); const u = [...t, { column: "", direction: "ascending" }].map(({ column: f, direction: S }) => ({ column: f, direction: S, ranks: o.get(f) ?? (f === "" ? Se({ data: r }) : Ee({ data: r, column: f })) })); u.some(({ column: f }) => !o.has(f)) && i((f) => { const S = new Map(f); return u.forEach(({ column: E, ranks: P }) => S.set(E, P)), S; }); const s = await Promise.all(u.map(async ({ column: f, direction: S, ranks: E }) => ({ column: f, direction: S, ranks: await E }))), l = Ie(s), c = ln(l), h = me({ selection: n, permutationIndexes: c }), { ranges: w, anchor: R } = h, L = { ranges: ke({ ranges: w, anchor: R, index: e }), anchor: R }; return me({ selection: L, permutationIndexes: l }); } function an(e, n) { return e.length !== n.length ? !1 : e.every((t, r) => { const o = n[r]; return o ? t.column === o.column && t.direction === o.direction : !1; }); } function un(e, n) { const t = []; let r; const o = []; for (const i of e) r ? o.push(i) : i.column === n ? r = i : t.push(i); return { prefix: t, item: r, suffix: o }; } function fn(e, n) { const { prefix: t, item: r, suffix: o } = un(n, e); return r && t.length === 0 ? r.direction === "ascending" ? [{ column: e, direction: "descending" }, ...o] : [...o] : [{ column: e, direction: "ascending" }, ...t, ...o]; } function dn(e) { const n = e ? `${e}px` : void 0; return { minWidth: n, maxWidth: n }; } function hn(e) { return { minWidth: e ? `${e}px` : void 0 }; } function pe(e) { const n = window.getComputedStyle(e), t = parseInt(n.paddingLeft) + parseInt(n.paddingRight); return e.offsetWidth - t; } function Re(e) { const n = localStorage.getItem(e); return n ? JSON.parse(n) : void 0; } function be({ key: e, value: n }) { e !== void 0 && (n === void 0 ? localStorage.removeItem(e) : localStorage.setItem(e, JSON.stringify(n))); } function wn({ key: e } = {}) { const [n, t] = O(void 0), [r, o] = O(void 0); e !== r && (e !== void 0 && t(Re(e)), o(e)); const i = x((a) => { if (typeof a == "function") { const u = a; if (e === void 0) t(u); else { const s = Re(e), l = u(s); t(l), be({ key: e, value: l }); } } else { const u = a; t(u), be({ key: e, value: u }); } }, [e]); return [n, i]; } const $e = Je({}); function gn({ children: e, localStorageKey: n }) { const [t, r] = wn({ key: n }), o = x((s) => { const l = t == null ? void 0 : t[s]; if (l != null) { if (isNaN(l) || l < 0) { console.warn(`Invalid column width for column index ${s}: ${l}. Ignoring it.`); return; } return l; } }, [t]), i = x((s) => dn(o(s)), [o]), a = x(({ columnIndex: s, width: l }) => { r((c) => { if (l !== void 0 && (isNaN(l) || l < 0)) throw new Error(`Invalid column width: ${l}`); if ((c == null ? void 0 : c[s]) === l) return c; const h = [...c ?? []]; return l === void 0 ? h[s] = void 0 : h[s] = l, h; }); }, [r]), u = H(() => ({ getColumnWidth: o, getColumnStyle: i, setColumnWidth: a }), [o, i, a]); return /* @__PURE__ */ m($e.Provider, { value: u, children: e }); } function Oe() { return Xe($e); } function ye(e) { const { value: n, onChange: t, defaultValue: r, disabled: o } = e, [i] = O(n), [a] = O(o ?? !1), [u, s] = O(r), l = i !== void 0; let c = !0, h; a ? (h = void 0, c = !1) : l ? (n === void 0 ? (console.warn("The value is controlled (it has no local state) because the property was initially defined. It cannot be set to undefined now (it is set back to the initial value)."), h = i) : h = n, c = t !== void 0) : (n !== void 0 && console.warn("The value is uncontrolled (it only has a local state) because the property was initially undefined. It cannot be set to a value now and is ignored."), h = u, c = !0); const w = x((R) => { c && (t == null || t(R), l || s(R)); }, [t, l, c]); return { value: h, onChange: w, enableInteractions: c, isControlled: l }; } function te(e) { return typeof e == "string" ? e : typeof e == "number" || typeof e == "bigint" ? e.toLocaleString("en-US") : typeof e == "boolean" ? e.toString() : Array.isArray(e) ? `[ ${e.map((n) => vn(te(n), 2)).join(`, `)} ]` : e == null ? JSON.stringify(e) : e instanceof Date ? e.toISOString() : typeof e == "object" ? `{${Object.entries(e).filter((n) => n[1] !== void 0).map(([n, t]) => `${n}: ${te(t)}`).join(", ")}}` : JSON.stringify(e); } function vn(e, n) { return e == null ? void 0 : e.split(` `).map((t) => " ".repeat(n) + t).join(` `); } function mn(e, n) { let t = !1, r = !1; function o() { e(), r = !1, t = !0, setTimeout(() => { t = !1, r && o(); }, n); } return () => { t ? r = !0 : o(); }; } function pn({ onDoubleClick: e, onMouseDown: n, stringify: t, columnIndex: r, value: o, hasResolved: i, className: a }) { const { getColumnStyle: u } = Oe(), s = u == null ? void 0 : u(r), l = H(() => t(o), [t, o]), c = H(() => { if (l !== void 0) { if (l.length > 400) return `${l.slice(0, 397)}…`; if (l.length > 100) return l; } }, [l]); return /* @__PURE__ */ m( "td", { role: "cell", "aria-busy": !i, onDoubleClick: e, onMouseDown: n, style: s, className: a, title: c, children: l } ); } function U({ children: e, selected: n, ariaRowIndex: t, title: r }) { return /* @__PURE__ */ m( "tr", { role: "row", "aria-rowindex": t, title: r, "aria-selected": n, children: e } ); } function ee({ children: e, checked: n, onClick: t, showCheckBox: r, style: o }) { return /* @__PURE__ */ A("th", { scope: "row", role: "rowheader", style: o, onClick: t, children: [ /* @__PURE__ */ m("span", { children: e }), r && /* @__PURE__ */ m("input", { type: "checkbox", disabled: !t, checked: n, readOnly: !0 }) ] }); } function Rn({ children: e, checked: n, onClick: t, showCheckBox: r, style: o }) { return /* @__PURE__ */ A("td", { "aria-disabled": !r, style: o, onClick: t, children: [ /* @__PURE__ */ m("span", { children: e }), r && /* @__PURE__ */ m("input", { type: "checkbox", checked: n, readOnly: !0 }) ] }); } function bn({ onDoubleClick: e, setWidth: n, width: t }) { const [r, o] = O(void 0), i = x((u) => { u.stopPropagation(); }, []), a = x((u) => { u.stopPropagation(); const s = t ?? 0; o(u.clientX - s), n == null || n(s); }, [n, t]); return T(() => { if (r !== void 0) { const s = function(l) { return function(c) { n == null || n(Math.max(1, c.clientX - l)); }; }(r); return window.addEventListener("mousemove", s), () => { window.removeEventListener("mousemove", s); }; } }, [r, n]), T(() => { if (r !== void 0) { const s = function(l) { return function(c) { n == null || n(Math.max(1, c.clientX - l)), o(void 0); }; }(r); return window.addEventListener("mouseup", s), () => { window.removeEventListener("mouseup", s); }; } }, [r, n]), /* @__PURE__ */ m( "span", { role: "separator", "aria-orientation": "vertical", onDoubleClick: e, onMouseDown: a, onClick: i } ); } function yn({ columnIndex: e, dataReady: n, direction: t, onClick: r, title: o, sortable: i, ariaPosInSet: a, ariaSetSize: u, className: s, children: l }) { const c = K(null), { getColumnStyle: h, setColumnWidth: w, getColumnWidth: R } = Oe(), L = h == null ? void 0 : h(e), j = R == null ? void 0 : R(e), f = x((E) => { w == null || w({ columnIndex: e, width: E }); }, [w, e]); T(() => { const E = c.current; if (n && E) { const P = pe(E); isNaN(P) || f(P); } }, [n, f]); const S = x(() => { const E = c.current; if (E) { Ue(() => { f(void 0); }); const P = pe(E); isNaN(P) || f(P); } }, [f]); return /* @__PURE__ */ A( "th", { ref: c, scope: "col", role: "columnheader", "aria-sort": t ?? "none", "aria-disabled": !i, "aria-posinset": u !== void 0 ? a : void 0, "aria-setsize": u, onClick: r, style: L, title: o, className: s, children: [ l, /* @__PURE__ */ m( bn, { setWidth: f, onDoubleClick: S, width: j } ) ] } ); } function xn({ header: e, orderBy: n, onOrderByChange: t, dataReady: r, sortable: o = !0, columnClassNames: i = [] }) { const a = x( (s) => { if (!(!t || !n)) return () => { t(fn(s, n)); }; }, [n, t] ), u = H(() => new Map((n ?? []).map(({ column: s, direction: l }, c) => [s, { direction: l, index: c }])), [n]); return e.map((s, l) => { var c, h; return ( // The ColumnHeader component width is controlled by the parent /* @__PURE__ */ m( yn, { dataReady: r, direction: (c = u.get(s)) == null ? void 0 : c.direction, ariaPosInSet: (h = u.get(s)) == null ? void 0 : h.index, ariaSetSize: n == null ? void 0 : n.length, onClick: a(s), sortable: o, title: s, columnIndex: l, className: i[l], children: s }, l ) ); }); } function je(e) { return e === void 0 ? "" : (e + 1).toLocaleString("en-US"); } function En(e, n) { const t = Object.keys(e.cells).length; if (t > 0 && t !== n) return `Row ${je(e.index)} length ${t} does not match header length ${n}`; } const In = "_hightable_o6cvp_1", Sn = "_table-scroll_o6cvp_15", Cn = "_mock-row-label_o6cvp_143", kn = "_styled_o6cvp_155", G = { hightable: In, tableScroll: Sn, mockRowLabel: Cn, styled: kn }, xe = 33; function Vn({ data: e, cacheKey: n, overscan: t = 20, padding: r = 20, focus: o = !0, orderBy: i, onOrderByChange: a, selection: u, onSelectionChange: s, onDoubleClickCell: l, onMouseDownCell: c, onError: h = console.error, stringify: w = te, className: R = "", columnClassNames: L = [], styled: j = !0 }) { const [f, S] = O(void 0), [E, P] = O({ start: 0, end: 0 }), [Y, ie] = O(!1), [se, le] = O(() => /* @__PURE__ */ new Map()), { value: D, onChange: Pe, enableInteractions: Me } = ye({ value: i, onChange: a, defaultValue: [], disabled: !e.sortable }), Ne = u === void 0 && s === void 0, { value: p, onChange: _, enableInteractions: Le, isControlled: Ve } = ye({ value: u, onChange: s, defaultValue: { ranges: [], anchor: void 0 }, disabled: Ne }), Z = p !== void 0, ce = Z && Le, Ae = ce || Z && ne({ ranges: p.ranges, length: e.numRows }), De = x(() => { if (!p) return; const { ranges: d } = p; return () => { _({ ranges: nn({ ranges: d, length: e.numRows }), anchor: void 0 }); }; }, [_, e.numRows, p]), ae = K(0), _e = x(({ tableIndex: d, dataIndex: g }) => { if (!p) return; async function v(b) { if (!p) return; if (!(b.shiftKey && p.anchor !== void 0)) { _(on({ selection: p, index: g })); return; } if (!D || D.length === 0) { _(sn({ selection: p, index: g })); return; } const $ = ++ae.current, C = await cn({ selection: p, tableIndex: d, orderBy: D, data: e, ranksMap: se, setRanksMap: le }); $ === ae.current && _(C); } return (b) => { v(b); }; }, [e, _, D, se, p]), ze = H(() => { if (!p) return !1; const { ranges: d } = p; return ne({ ranges: d, length: e.numRows }); }, [p, e.numRows]), Te = x((d) => { if (!p || d === void 0) return; const { ranges: g } = p; return re({ ranges: g, index: d }); }, [p]), W = (e.numRows + 1) * xe, He = f ? Math.max(0, f.offset - r) * xe : 0, F = K(null), ue = K(null), fe = K(0); f && e !== f.data && (S(void 0), ie(!1), le(/* @__PURE__ */ new Map()), Ve || _({ ranges: [], anchor: void 0 })), T(() => { function d() { var M, V; const v = (M = F.current) == null ? void 0 : M.clientHeight, b = v === void 0 || v === 0 ? 100 : v, k = ((V = F.current) == null ? void 0 : V.scrollTop) ?? 0, $ = Math.floor(e.numRows * k / W), C = Math.ceil(e.numRows * (k + b) / W), y = Math.max(0, $ - t), I = Math.min(e.numRows, C + t); if (isNaN(y)) throw new Error(`invalid start row ${y}`); if (isNaN(I)) throw new Error(`invalid end row ${I}`); if (I - y > 1e3) throw new Error(`attempted to render too many rows ${I - y} table must be contained in a scrollable div`); P({ start: y, end: I }); } d(); const g = F.current; return g == null || g.addEventListener("scroll", d), window.addEventListener("resize", d), () => { g == null || g.removeEventListener("scroll", d), window.removeEventListener("resize", d); }; }, [e.numRows, t, r, W]), T(() => { async function d() { const { start: g, end: v } = E, b = D ?? []; if (!(f && f.data === e && g === f.offset && v === f.offset + f.rows.length && an(f.orderedBy, b))) { if (g === v) { S({ offset: g, rows: [], orderedBy: b, data: e }); return; } try { const k = ++fe.current, $ = e.rows({ start: g, end: v, orderBy: b }), C = mn(() => { const y = []; for (const M of $) { const V = { cells: {} }; for (const [J, X] of Object.entries(M.cells)) "resolved" in X && (V.cells[J] = X.resolved); "resolved" in M.index && (V.index = M.index.resolved), y.push(V); } const I = { offset: g, rows: y, orderedBy: b, data: e }; if (S(I), !Y) { const M = new Set(I.data.header); I.rows.some((V) => { const J = Object.keys(V.cells); return J.length === M.size && J.every((X) => M.has(X)); }) && ie(!0); } }, 10); C(); for (const y of $) for (const I of [y.index, ...Object.values(y.cells)]) I.then(() => { fe.current === k && C(); }); await Promise.all($.flatMap((y) => [y.index, ...Object.values(y.cells)])); } catch (k) { h(k); } } } d(); }, [e, h, D, f, E, Y]); const Be = x((d, g) => { if (!(!l || g === void 0)) return (v) => { l(v, d, g); }; }, [l]), Ke = x((d, g) => { if (!(!c || g === void 0)) return (v) => { c(v, d, g); }; }, [c]); T(() => { var d; o && ((d = ue.current) == null || d.focus()); }, [o]); const q = (f == null ? void 0 : f.offset) ?? 0, de = (f == null ? void 0 : f.rows.length) ?? 0, he = Array.from({ length: Math.min(r, q) }, () => []), We = Array.from({ length: Math.min(r, e.numRows - q - de) }, () => []), B = H(() => { const d = Math.ceil(Math.log10(e.numRows + 1)) * 4 + 22; return hn(d); }, [e.numRows]); if (!e.header.length) return; const Fe = e.header.length + 1, qe = e.numRows + 1; return /* @__PURE__ */ m(gn, { localStorageKey: `${n}:column-widths`, children: /* @__PURE__ */ A("div", { className: `${G.hightable} ${j ? G.styled : ""} ${R}`, children: [ /* @__PURE__ */ m("div", { className: G.tableScroll, ref: F, children: /* @__PURE__ */ m("div", { style: { height: `${W}px` }, children: /* @__PURE__ */ A( "table", { "aria-readonly": !0, "aria-colcount": Fe, "aria-rowcount": qe, "aria-multiselectable": ce, ref: ue, role: "grid", style: { top: `${He}px` }, tabIndex: 0, children: [ /* @__PURE__ */ m("thead", { role: "rowgroup", children: /* @__PURE__ */ A(U, { ariaRowIndex: 1, children: [ /* @__PURE__ */ m( Rn, { onClick: De(), checked: ze, showCheckBox: Ae, style: B, children: " " } ), /* @__PURE__ */ m( xn, { dataReady: Y, header: e.header, orderBy: D, onOrderByChange: Pe, sortable: Me, columnClassNames: L } ) ] }) }), /* @__PURE__ */ A("tbody", { role: "rowgroup", children: [ he.map((d, g) => { const v = q - he.length + g; return /* @__PURE__ */ m(U, { ariaRowIndex: v + 2, children: /* @__PURE__ */ m(ee, { style: B }) }, v); }), f == null ? void 0 : f.rows.map((d, g) => { const v = f.offset + g, b = d.index, k = Te(d.index) ?? !1; return /* @__PURE__ */ A( U, { selected: k, ariaRowIndex: v + 2, title: En(d, e.header.length), children: [ /* @__PURE__ */ m( ee, { style: B, onClick: b === void 0 ? void 0 : _e({ tableIndex: v, dataIndex: b }), checked: k, showCheckBox: Z, children: je(b) } ), e.header.map(($, C) => { const y = $ in d.cells, I = d.cells[$]; return /* @__PURE__ */ m( pn, { onDoubleClick: Be(C, b), onMouseDown: Ke(C, b), stringify: w, value: I, columnIndex: C, hasResolved: y, className: L[C] }, C ); }) ] }, v ); }), We.map((d, g) => { const v = q + de + g; return /* @__PURE__ */ m(U, { ariaRowIndex: v + 2, children: /* @__PURE__ */ m(ee, { style: B }) }, v); }) ] }) ] } ) }) }), /* @__PURE__ */ m("div", { className: G.mockRowLabel, style: B, children: " " }) ] }) }); } function An(e) { const n = {}; let t = 0, r = 0; return { ...e, rows({ start: o, end: i, orderBy: a }) { const u = $n(a), s = n[u] ?? new Array(e.numRows); u in n || (n[u] = s); const l = t + r; l && !(l % 10) && console.log(`Cache hits: ${t} / ${t + r} (${(100 * t / (t + r)).toFixed(1)}%)`); let c, h = !1; for (let w = o; w <= i; w++) if (w < i && !s[w]) c ?? (c = w); else if (c !== void 0) { const R = w, L = e.rows({ start: c, end: R, orderBy: a }); for (let j = 0; j < R - c; j++) s[c + j] = L[j]; c = void 0, h = !0; } return h ? r++ : t++, s.slice(o, i).map((w) => { if (!w) throw new Error("Row not cached"); return w; }); } }; } function $n(e) { if (!e || e.length === 0) return ""; if (!(0 in e)) throw new Error("orderBy should have at least one element"); return JSON.stringify(e); } export { Vn as HighTable, Ln as arrayDataFrame, Ye as asyncRows, Ze as awaitRow, Mn as awaitRows, Vn as default, ge as resolvablePromise, Qe as resolvableRow, An as rowCache, Nn as sortableDataFrame, te as stringify, Ge as wrapPromise, we as wrapResolved }; //# sourceMappingURL=HighTable.js.map