@floegence/floe-webapp-core 0.11.4 → 0.11.5

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.
@@ -160,9 +160,15 @@ export interface FileBrowserContextValue {
160
160
  currentFiles: Accessor<FileItem[]>;
161
161
  filterQuery: Accessor<string>;
162
162
  setFilterQuery: (query: string) => void;
163
+ /** Query that is actually applied to the list (may lag behind filterQuery for UI-first rendering) */
164
+ filterQueryApplied: Accessor<string>;
163
165
  isFilterActive: Accessor<boolean>;
164
166
  setFilterActive: (active: boolean) => void;
165
167
  getFilterMatch: (name: string) => FilterMatchInfo | null;
168
+ /** Fast path: match info by file id (no repeated fuzzy matching) */
169
+ getFilterMatchForId: (id: string) => FilterMatchInfo | null;
170
+ /** Selected items in the current view, ordered by currentFiles order */
171
+ getSelectedItemsList: () => FileItem[];
166
172
  sidebarCollapsed: Accessor<boolean>;
167
173
  toggleSidebar: () => void;
168
174
  sidebarWidth: Accessor<number>;
@@ -0,0 +1,29 @@
1
+ import type { Accessor } from 'solid-js';
2
+ export interface VirtualRange {
3
+ start: number;
4
+ end: number;
5
+ }
6
+ export interface UseVirtualWindowOptions {
7
+ count: Accessor<number>;
8
+ /** Fixed item size in pixels */
9
+ itemSize: Accessor<number>;
10
+ /** Extra items to render before/after the visible window */
11
+ overscan?: number;
12
+ }
13
+ export interface UseVirtualWindowReturn {
14
+ /** Attach to the scroll container element */
15
+ scrollRef: (el: HTMLElement | null) => void;
16
+ /** Call this from the scroll container's onScroll handler */
17
+ onScroll: () => void;
18
+ range: Accessor<VirtualRange>;
19
+ paddingTop: Accessor<number>;
20
+ paddingBottom: Accessor<number>;
21
+ totalSize: Accessor<number>;
22
+ }
23
+ /**
24
+ * Lightweight fixed-size virtual window.
25
+ *
26
+ * Unlike the chat virtual list (variable-height), this keeps O(1) math per scroll update and
27
+ * is intended for very large collections (e.g. 10k items in FileBrowser).
28
+ */
29
+ export declare function useVirtualWindow(options: UseVirtualWindowOptions): UseVirtualWindowReturn;
package/dist/index105.js CHANGED
@@ -1,64 +1,77 @@
1
- import { createEffect as Y, onCleanup as A } from "solid-js";
2
- import { useDeck as G } from "./index97.js";
3
- import { applyDragDelta as M } from "./index112.js";
4
- import { getGridConfigFromElement as x } from "./index11.js";
5
- import { lockBodyStyle as z } from "./index109.js";
6
- function O() {
7
- const l = G();
8
- let n = null, u = 0, s = 0, y = 0, D = 0, r = null, c = null, E = null, p = null, a = null, P = 0, I = 0, f = null;
9
- const F = (t) => {
1
+ import { createEffect as B, onCleanup as G } from "solid-js";
2
+ import { useDeck as z } from "./index97.js";
3
+ import { applyDragDelta as R } from "./index112.js";
4
+ import { getGridConfigFromElement as N } from "./index11.js";
5
+ import { lockBodyStyle as O } from "./index109.js";
6
+ function V() {
7
+ const p = z();
8
+ let c = null, m = 0, f = 0, L = 0, g = 0, l = 0, P = 0, A = 0, F = 0, a = null, v = null, T = null, y = null, n = null, I = 0, k = 0, w = null;
9
+ const M = (t) => {
10
10
  if (!t) {
11
- p?.(), p = null;
11
+ y?.(), y = null;
12
12
  return;
13
13
  }
14
- p?.(), p = z({ cursor: "grabbing", "user-select": "none" });
15
- }, b = () => {
16
- n !== null && (r !== null && typeof cancelAnimationFrame < "u" && (cancelAnimationFrame(r), r = null), n = null, c = null, E = null, a = null, f = null, F(!1), l.endDrag(!0));
17
- }, k = (t) => {
18
- const o = t.target;
19
- if (o.closest('button, input, select, textarea, [role="button"], a') || o.closest("[data-widget-resize-handle]")) return;
20
- const e = o.closest("[data-widget-drag-handle]");
21
- if (!e || t.pointerType === "mouse" && t.button !== 0) return;
22
- const i = e.dataset.widgetDragHandle;
23
- if (!i) return;
24
- const d = e.closest(".deck-grid");
25
- if (!d) return;
26
- t.preventDefault(), t.stopPropagation(), n = t.pointerId, u = t.clientX, s = t.clientY, y = u, D = s, c = i, E = e, a = d, F(!0);
27
- const h = l.activeLayout()?.widgets.find((L) => L.id === i);
28
- f = h ? { ...h.position } : null;
29
- const w = window.getComputedStyle(d);
30
- P = parseFloat(w.paddingLeft) || 0, I = parseFloat(w.paddingRight) || 0, l.startDrag(i, u, s), e.setPointerCapture(t.pointerId);
31
- }, C = (t) => {
32
- if (!(n !== t.pointerId || !c) && (y = t.clientX, D = t.clientY, r === null)) {
33
- if (typeof requestAnimationFrame > "u") {
34
- H();
14
+ y?.(), y = O({ cursor: "grabbing", "user-select": "none" });
15
+ }, C = () => {
16
+ c !== null && (a !== null && typeof cancelAnimationFrame < "u" && (cancelAnimationFrame(a), a = null), c = null, v = null, T = null, n = null, w = null, M(!1), p.endDrag(!0));
17
+ }, X = () => {
18
+ if (!n) return;
19
+ const t = n.getBoundingClientRect(), e = 48, d = 24, s = l - t.top, o = t.bottom - l;
20
+ let r = 0;
21
+ if (s < e ? r = -Math.ceil((e - s) / e * d) : o < e && (r = Math.ceil((e - o) / e * d)), r === 0) return;
22
+ const i = n.scrollTop, h = Math.max(0, Math.min(i + r, n.scrollHeight - n.clientHeight));
23
+ h !== i && (n.scrollTop = h);
24
+ }, Y = () => {
25
+ if (a !== null || typeof requestAnimationFrame > "u") return;
26
+ const t = () => {
27
+ if (c === null) {
28
+ a = null;
35
29
  return;
36
30
  }
37
- r = requestAnimationFrame(() => {
38
- r = null, n !== null && H();
39
- });
40
- }
41
- }, H = () => {
42
- if (!c || !a || !f) return;
43
- const t = y - u, o = D - s, { cols: g, rowHeight: W, gap: e } = x(a), i = a.clientWidth - P - I, d = e * (g - 1), v = (i - d) / g;
44
- if (!Number.isFinite(v) || v <= 0) return;
45
- const h = W + e, w = Math.round(t / v), L = Math.round(o / h), X = M(f, w, L, g);
46
- l.updateDrag(X, { x: t, y: o });
47
- }, m = (t) => {
48
- if (n === t.pointerId) {
31
+ x(), a = requestAnimationFrame(t);
32
+ };
33
+ a = requestAnimationFrame(t);
34
+ }, H = (t) => {
35
+ const e = t.target;
36
+ if (e.closest('button, input, select, textarea, [role="button"], a') || e.closest("[data-widget-resize-handle]")) return;
37
+ const o = e.closest("[data-widget-drag-handle]");
38
+ if (!o || t.pointerType === "mouse" && t.button !== 0) return;
39
+ const r = o.dataset.widgetDragHandle;
40
+ if (!r) return;
41
+ const i = o.closest(".deck-grid");
42
+ if (!i) return;
43
+ t.preventDefault(), t.stopPropagation(), c = t.pointerId, m = t.clientX, f = t.clientY, g = m, l = f, P = m, A = f, v = r, T = o, n = i, L = i.scrollTop, F = L, M(!0);
44
+ const u = p.activeLayout()?.widgets.find((b) => b.id === r);
45
+ w = u ? { ...u.position } : null;
46
+ const E = window.getComputedStyle(i);
47
+ I = parseFloat(E.paddingLeft) || 0, k = parseFloat(E.paddingRight) || 0, p.startDrag(r, m, f), o.setPointerCapture(t.pointerId), Y();
48
+ }, S = (t) => {
49
+ c !== t.pointerId || !v || (g = t.clientX, l = t.clientY, typeof requestAnimationFrame > "u" && x());
50
+ }, x = () => {
51
+ if (!v || !n || !w) return;
52
+ X();
53
+ const t = n.scrollTop;
54
+ if (g === P && l === A && t === F) return;
55
+ P = g, A = l, F = t;
56
+ const e = g - m, d = l - f + (t - L), { cols: s, rowHeight: o, gap: r } = N(n), i = n.clientWidth - I - k, h = r * (s - 1), u = (i - h) / s;
57
+ if (!Number.isFinite(u) || u <= 0) return;
58
+ const E = o + r, b = Math.round(e / u), W = Math.round(d / E), q = R(w, b, W, s);
59
+ p.updateDrag(q, { x: e, y: d });
60
+ }, D = (t) => {
61
+ if (c === t.pointerId) {
49
62
  try {
50
- E?.releasePointerCapture(t.pointerId);
63
+ T?.releasePointerCapture(t.pointerId);
51
64
  } catch {
52
65
  }
53
- b();
66
+ C();
54
67
  }
55
68
  };
56
- Y(() => {
57
- l.editMode() && (typeof document > "u" || (document.addEventListener("pointerdown", k, !0), document.addEventListener("pointermove", C, !0), document.addEventListener("pointerup", m, !0), document.addEventListener("pointercancel", m, !0), A(() => {
58
- b(), document.removeEventListener("pointerdown", k, !0), document.removeEventListener("pointermove", C, !0), document.removeEventListener("pointerup", m, !0), document.removeEventListener("pointercancel", m, !0);
69
+ B(() => {
70
+ p.editMode() && (typeof document > "u" || (document.addEventListener("pointerdown", H, !0), document.addEventListener("pointermove", S, !0), document.addEventListener("pointerup", D, !0), document.addEventListener("pointercancel", D, !0), G(() => {
71
+ C(), document.removeEventListener("pointerdown", H, !0), document.removeEventListener("pointermove", S, !0), document.removeEventListener("pointerup", D, !0), document.removeEventListener("pointercancel", D, !0);
59
72
  })));
60
73
  });
61
74
  }
62
75
  export {
63
- O as useDeckDrag
76
+ V as useDeckDrag
64
77
  };
package/dist/index11.js CHANGED
@@ -1,67 +1,108 @@
1
- import { insert as h, createComponent as f, effect as O, setStyleProperty as I, className as P, setAttribute as $, template as z, use as F } from "solid-js/web";
2
- import { createSignal as A, createEffect as L, createMemo as s, onMount as T, Show as _, For as E, onCleanup as N } from "solid-js";
3
- import { cn as W } from "./index106.js";
4
- import { useDeck as V } from "./index97.js";
5
- import { useLayout as Z } from "./index92.js";
6
- import { hasCollision as K } from "./index111.js";
7
- import { DeckCell as U } from "./index12.js";
8
- import { DropZonePreview as j } from "./index19.js";
9
- var q = /* @__PURE__ */ z('<div class="absolute inset-0 pointer-events-none z-0 rounded"style="padding:inherit;background-origin:content-box;background-clip:content-box;background-image:linear-gradient(to right, color-mix(in srgb, var(--border) 15%, transparent) 1px, transparent 1px), linear-gradient(to bottom, color-mix(in srgb, var(--border) 15%, transparent) 1px, transparent 1px) ;background-position:0 0">'), B = /* @__PURE__ */ z('<div data-grid-cols=24 data-gap=4 data-default-rows=24 style="scrollbar-gutter:stable;grid-template-columns:repeat(24, 1fr);gap:4px"><div class=pointer-events-none aria-hidden=true style=grid-column:1>');
10
- const b = 24, c = 24, d = 4, w = 20, J = 4, Q = (b - 1) * d, X = {
1
+ import { insert as w, createComponent as m, effect as z, setStyleProperty as v, className as L, setAttribute as _, template as C, use as A } from "solid-js/web";
2
+ import { createSignal as N, createEffect as T, createMemo as s, onMount as j, Show as D, For as V, onCleanup as W } from "solid-js";
3
+ import { cn as Z } from "./index106.js";
4
+ import { useDeck as $ } from "./index97.js";
5
+ import { useLayout as K } from "./index92.js";
6
+ import { hasCollision as U } from "./index111.js";
7
+ import { DeckCell as q } from "./index12.js";
8
+ import { DropZonePreview as B } from "./index19.js";
9
+ var J = /* @__PURE__ */ C('<div class="pointer-events-none z-0"style="grid-column:1 / -1;--deck-grid-unit-x:calc((100% - 92px) / 24 + 4px);background-position:0 0, 0 0, 0 0, 0 0, 0 0, 0 0">'), Q = /* @__PURE__ */ C('<div data-grid-cols=24 data-gap=4 data-default-rows=24 style="scrollbar-gutter:stable;grid-template-columns:repeat(24, 1fr);gap:4px"><div class=pointer-events-none aria-hidden=true style="grid-column:1 / -1">');
10
+ const O = 24, a = 24, x = 4, b = 20, P = 4, X = {
11
11
  x: 0,
12
12
  y: 0
13
13
  };
14
- function at(a) {
15
- const o = V(), C = Z();
16
- let l;
17
- const [k, S] = A(0), R = () => o.activeLayout()?.widgets ?? [], u = () => o.dragState(), D = () => o.resizeState();
18
- L(() => {
19
- C.isMobile() && o.editMode() && o.setEditMode(!1);
14
+ function st(d) {
15
+ const c = $(), M = K();
16
+ let p;
17
+ const [y, I] = N(0), H = () => c.activeLayout()?.widgets ?? [], f = () => c.dragState(), k = () => c.resizeState();
18
+ T(() => {
19
+ M.isMobile() && c.editMode() && c.setEditMode(!1);
20
20
  });
21
21
  const G = s(() => {
22
- const e = u();
23
- if (!e) return !0;
24
- const r = o.activeLayout();
25
- return r ? !K(e.currentPosition, r.widgets, e.widgetId) : !0;
26
- }), H = s(() => {
27
- const e = R();
28
- if (e.length === 0) return c;
29
- let r = c;
30
- for (const n of e) {
31
- const t = n.position.row + n.position.rowSpan;
22
+ const r = f();
23
+ if (!r) return !0;
24
+ const e = c.activeLayout();
25
+ return e ? !U(r.currentPosition, e.widgets, r.widgetId) : !0;
26
+ }), F = s(() => {
27
+ const r = H();
28
+ if (r.length === 0) return a;
29
+ let e = a;
30
+ for (const i of r) {
31
+ const t = i.position.row + i.position.rowSpan;
32
+ t > e && (e = t);
33
+ }
34
+ return e;
35
+ }), S = s(() => {
36
+ let r = F();
37
+ const e = f();
38
+ if (e) {
39
+ const t = e.currentPosition.row + e.currentPosition.rowSpan;
40
+ t > r && (r = t);
41
+ }
42
+ const i = k();
43
+ if (i) {
44
+ const t = i.currentPosition.row + i.currentPosition.rowSpan;
32
45
  t > r && (r = t);
33
46
  }
34
- return r;
35
- }), x = s(() => {
36
- const e = k();
37
- if (e <= 0) return w;
38
- const n = (e - J * 2 - (c - 1) * d) / c;
39
- return Math.max(w, n);
47
+ return Math.max(a, r);
48
+ }), h = s(() => {
49
+ const r = y();
50
+ if (r <= 0) return b;
51
+ const i = (r - P * 2 - (a - 1) * x) / a;
52
+ return Math.max(b, i);
40
53
  });
41
- T(() => {
42
- if (!l || typeof ResizeObserver > "u") return;
43
- const e = new ResizeObserver((r) => {
44
- for (const n of r)
45
- S(n.contentRect.height);
54
+ j(() => {
55
+ if (!p || typeof ResizeObserver > "u") return;
56
+ const r = new ResizeObserver((e) => {
57
+ for (const i of e)
58
+ I(i.contentRect.height);
46
59
  });
47
- e.observe(l), S(l.clientHeight), N(() => e.disconnect());
60
+ r.observe(p), I(p.clientHeight), W(() => r.disconnect());
48
61
  });
49
- const M = s(() => H() > c);
62
+ const E = s(() => S() > a ? !0 : y() <= 0 ? !1 : a * h() + (a - 1) * x + P * 2 > y() + 1);
50
63
  return (() => {
51
- var e = B(), r = e.firstChild, n = l;
52
- return typeof n == "function" ? F(n, e) : l = e, h(e, f(_, {
64
+ var r = Q(), e = r.firstChild, i = p;
65
+ return typeof i == "function" ? A(i, r) : p = r, w(r, m(D, {
53
66
  get when() {
54
- return o.editMode();
67
+ return c.editMode();
55
68
  },
56
69
  get children() {
57
- var t = q();
58
- return O((g) => I(t, "background-size", `calc((100% - ${Q}px) / ${b} + ${d}px) ${x() + d}px`)), t;
70
+ var t = J();
71
+ return z((n) => {
72
+ var l = `1 / ${S() + 1}`, g = `${h() + x}px`, u = [
73
+ // Fine
74
+ "linear-gradient(to right, color-mix(in srgb, var(--border) 35%, transparent) 1px, transparent 1px)",
75
+ "linear-gradient(to bottom, color-mix(in srgb, var(--border) 35%, transparent) 1px, transparent 1px)",
76
+ // Major (6)
77
+ "linear-gradient(to right, color-mix(in srgb, var(--border) 55%, transparent) 1px, transparent 1px)",
78
+ "linear-gradient(to bottom, color-mix(in srgb, var(--border) 55%, transparent) 1px, transparent 1px)",
79
+ // Major (12)
80
+ "linear-gradient(to right, color-mix(in srgb, var(--border) 75%, transparent) 2px, transparent 2px)",
81
+ "linear-gradient(to bottom, color-mix(in srgb, var(--border) 75%, transparent) 2px, transparent 2px)"
82
+ ].join(", "), o = [
83
+ // Fine
84
+ "var(--deck-grid-unit-x) var(--deck-grid-unit-y)",
85
+ "var(--deck-grid-unit-x) var(--deck-grid-unit-y)",
86
+ // Major (6)
87
+ "calc(var(--deck-grid-unit-x) * 6) calc(var(--deck-grid-unit-y) * 6)",
88
+ "calc(var(--deck-grid-unit-x) * 6) calc(var(--deck-grid-unit-y) * 6)",
89
+ // Major (12)
90
+ "calc(var(--deck-grid-unit-x) * 12) calc(var(--deck-grid-unit-y) * 12)",
91
+ "calc(var(--deck-grid-unit-x) * 12) calc(var(--deck-grid-unit-y) * 12)"
92
+ ].join(", ");
93
+ return l !== n.e && v(t, "grid-row", n.e = l), g !== n.t && v(t, "--deck-grid-unit-y", n.t = g), u !== n.a && v(t, "background-image", n.a = u), o !== n.o && v(t, "background-size", n.o = o), n;
94
+ }, {
95
+ e: void 0,
96
+ t: void 0,
97
+ a: void 0,
98
+ o: void 0
99
+ }), t;
59
100
  }
60
- }), null), h(e, f(_, {
101
+ }), null), w(r, m(D, {
61
102
  get when() {
62
- return u();
103
+ return f();
63
104
  },
64
- children: (t) => f(j, {
105
+ children: (t) => m(B, {
65
106
  get position() {
66
107
  return t().currentPosition;
67
108
  },
@@ -69,72 +110,72 @@ function at(a) {
69
110
  return G();
70
111
  }
71
112
  })
72
- }), null), h(e, f(E, {
113
+ }), null), w(r, m(V, {
73
114
  get each() {
74
- return R();
115
+ return H();
75
116
  },
76
117
  children: (t) => {
77
- const g = s(() => {
78
- const i = u();
79
- if (i && i.widgetId === t.id)
118
+ const n = s(() => {
119
+ const o = f();
120
+ if (o && o.widgetId === t.id)
80
121
  return t.position;
81
- const y = D();
82
- return y && y.widgetId === t.id ? y.currentPosition : t.position;
83
- }), p = s(() => u()?.widgetId === t.id), m = s(() => D()?.widgetId === t.id), v = s(() => {
84
- const i = u();
85
- return i && i.widgetId === t.id ? i.pixelOffset : X;
122
+ const R = k();
123
+ return R && R.widgetId === t.id ? R.currentPosition : t.position;
124
+ }), l = s(() => f()?.widgetId === t.id), g = s(() => k()?.widgetId === t.id), u = s(() => {
125
+ const o = f();
126
+ return o && o.widgetId === t.id ? o.pixelOffset : X;
86
127
  });
87
- return f(U, {
128
+ return m(q, {
88
129
  widget: t,
89
130
  get position() {
90
- return g();
131
+ return n();
91
132
  },
92
133
  get isDragging() {
93
- return p();
134
+ return l();
94
135
  },
95
136
  get isResizing() {
96
- return m();
137
+ return g();
97
138
  },
98
139
  get pixelOffset() {
99
- return v();
140
+ return u();
100
141
  }
101
142
  });
102
143
  }
103
- }), null), h(e, () => a.children, null), O((t) => {
104
- var g = W(
144
+ }), null), w(r, () => d.children, null), z((t) => {
145
+ var n = Z(
105
146
  "deck-grid relative w-full h-full overflow-x-hidden",
106
147
  // Only enable vertical scroll when content exceeds 24 rows
107
- M() ? "overflow-y-scroll" : "overflow-y-hidden",
148
+ E() ? "overflow-y-scroll" : "overflow-y-hidden",
108
149
  "grid p-1",
109
- o.editMode() && "bg-muted/20",
110
- a.class
111
- ), p = `${x()}px`, m = x(), v = `1 / ${H() + 1}`;
112
- return g !== t.e && P(e, t.e = g), p !== t.t && I(e, "grid-auto-rows", t.t = p), m !== t.a && $(e, "data-row-height", t.a = m), v !== t.o && I(r, "grid-row", t.o = v), t;
150
+ c.editMode() && "bg-muted/20",
151
+ d.class
152
+ ), l = `${h()}px`, g = h(), u = `1 / ${S() + 1}`;
153
+ return n !== t.e && L(r, t.e = n), l !== t.t && v(r, "grid-auto-rows", t.t = l), g !== t.a && _(r, "data-row-height", t.a = g), u !== t.o && v(e, "grid-row", t.o = u), t;
113
154
  }, {
114
155
  e: void 0,
115
156
  t: void 0,
116
157
  a: void 0,
117
158
  o: void 0
118
- }), e;
159
+ }), r;
119
160
  })();
120
161
  }
121
162
  const ct = {
122
- cols: b,
123
- defaultRows: c,
124
- gap: d,
163
+ cols: O,
164
+ defaultRows: a,
165
+ gap: x,
125
166
  // Deprecated: use getGridConfig() or read from data-row-height attribute instead
126
- rowHeight: w
167
+ rowHeight: b
127
168
  };
128
- function dt(a) {
169
+ function dt(d) {
129
170
  return {
130
- cols: parseInt(a.dataset.gridCols || String(b), 10),
131
- rowHeight: parseFloat(a.dataset.rowHeight || String(w)),
132
- gap: parseInt(a.dataset.gap || String(d), 10),
133
- defaultRows: parseInt(a.dataset.defaultRows || String(c), 10)
171
+ cols: parseInt(d.dataset.gridCols || String(O), 10),
172
+ rowHeight: parseFloat(d.dataset.rowHeight || String(b)),
173
+ gap: parseInt(d.dataset.gap || String(x), 10),
174
+ defaultRows: parseInt(d.dataset.defaultRows || String(a), 10)
134
175
  };
135
176
  }
136
177
  export {
137
178
  ct as DECK_GRID_CONFIG,
138
- at as DeckGrid,
179
+ st as DeckGrid,
139
180
  dt as getGridConfigFromElement
140
181
  };