@floegence/floe-webapp-core 0.35.31 → 0.35.33

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.
@@ -9,10 +9,11 @@ import { useFileBrowserDrag as wt } from "../../context/FileBrowserDragContext.j
9
9
  import { FileItemIcon as Ct } from "./FileIcons.js";
10
10
  import { ChevronDown as bt } from "../icons/index.js";
11
11
  import { createLongPressContextMenuHandlers as Dt } from "./longPressContextMenu.js";
12
- import { ResizeHandle as nt } from "../layout/ResizeHandle.js";
12
+ import { ResizeHandle as it } from "../layout/ResizeHandle.js";
13
13
  import { fileBrowserTouchTargetAttrs as St } from "./touchInteractionGuard.js";
14
- var $t = /* @__PURE__ */ _("<span class=truncate>"), Mt = /* @__PURE__ */ _('<mark class="bg-warning/40 text-inherit rounded-sm">'), zt = /* @__PURE__ */ _("<span>"), _t = /* @__PURE__ */ _('<div><button type=button class="group w-full flex items-center justify-start text-left px-3 py-2 cursor-pointer hover:bg-muted/50 transition-colors">Modified'), yt = /* @__PURE__ */ _('<div class=shrink-0><button type=button class="group w-full flex items-center justify-start text-left px-3 py-2 cursor-pointer hover:bg-muted/50 transition-colors">Size'), It = /* @__PURE__ */ _("<div>"), Pt = /* @__PURE__ */ _('<div><div class="flex items-center border-b border-border text-[11px] text-muted-foreground font-medium"><div><button type=button class="group w-full flex items-center min-w-0 px-3 py-2 cursor-pointer hover:bg-muted/50 transition-colors"><span class="flex items-center gap-2 min-w-0"><span class="flex-shrink-0 w-4 h-4"aria-hidden=true></span><span class="flex items-center min-w-0"><span class=truncate>Name</span></span></span></button></div></div><div class="flex-1 min-h-0 overflow-auto">'), kt = /* @__PURE__ */ _('<span>No files matching "<!>"'), Tt = /* @__PURE__ */ _('<button type=button class="px-2 py-1 rounded bg-muted hover:bg-muted/80 transition-colors">Clear Filter'), Lt = /* @__PURE__ */ _('<div class="flex flex-col items-center justify-center h-32 gap-2 text-xs text-muted-foreground">'), pt = /* @__PURE__ */ _("<span>This folder is empty"), it = /* @__PURE__ */ _('<div class="shrink-0 px-3 py-1.5 text-left text-muted-foreground truncate">'), Rt = /* @__PURE__ */ _('<button type=button><div class="flex items-center gap-2 flex-1 min-w-0 px-3 py-1.5"><span class="flex-shrink-0 w-4 h-4">');
15
- function Wt(t) {
14
+ import { createItemContextMenuEvent as $t } from "./contextMenuEvent.js";
15
+ var Mt = /* @__PURE__ */ _("<span class=truncate>"), zt = /* @__PURE__ */ _('<mark class="bg-warning/40 text-inherit rounded-sm">'), _t = /* @__PURE__ */ _("<span>"), yt = /* @__PURE__ */ _('<div><button type=button class="group w-full flex items-center justify-start text-left px-3 py-2 cursor-pointer hover:bg-muted/50 transition-colors">Modified'), It = /* @__PURE__ */ _('<div class=shrink-0><button type=button class="group w-full flex items-center justify-start text-left px-3 py-2 cursor-pointer hover:bg-muted/50 transition-colors">Size'), Pt = /* @__PURE__ */ _("<div>"), kt = /* @__PURE__ */ _('<div><div class="flex items-center border-b border-border text-[11px] text-muted-foreground font-medium"><div><button type=button class="group w-full flex items-center min-w-0 px-3 py-2 cursor-pointer hover:bg-muted/50 transition-colors"><span class="flex items-center gap-2 min-w-0"><span class="flex-shrink-0 w-4 h-4"aria-hidden=true></span><span class="flex items-center min-w-0"><span class=truncate>Name</span></span></span></button></div></div><div class="flex-1 min-h-0 overflow-auto">'), Tt = /* @__PURE__ */ _('<span>No files matching "<!>"'), Lt = /* @__PURE__ */ _('<button type=button class="px-2 py-1 rounded bg-muted hover:bg-muted/80 transition-colors">Clear Filter'), Rt = /* @__PURE__ */ _('<div class="flex flex-col items-center justify-center h-32 gap-2 text-xs text-muted-foreground">'), pt = /* @__PURE__ */ _("<span>This folder is empty"), nt = /* @__PURE__ */ _('<div class="shrink-0 px-3 py-1.5 text-left text-muted-foreground truncate">'), Wt = /* @__PURE__ */ _('<button type=button><div class="flex items-center gap-2 flex-1 min-w-0 px-3 py-1.5"><span class="flex-shrink-0 w-4 h-4">');
16
+ function Et(t) {
16
17
  const a = Z(() => {
17
18
  if (!t.match || t.match.matchedIndices.length === 0)
18
19
  return [{
@@ -34,7 +35,7 @@ function Wt(t) {
34
35
  }), C;
35
36
  });
36
37
  return (() => {
37
- var C = $t();
38
+ var C = Mt();
38
39
  return u(C, m(at, {
39
40
  get each() {
40
41
  return a();
@@ -47,14 +48,14 @@ function Wt(t) {
47
48
  return rt(() => L.text);
48
49
  },
49
50
  get children() {
50
- var D = Mt();
51
+ var D = zt();
51
52
  return u(D, () => L.text), D;
52
53
  }
53
54
  })
54
55
  })), C;
55
56
  })();
56
57
  }
57
- function Kt(t) {
58
+ function Jt(t) {
58
59
  const a = st(), C = wt(), L = () => (t.enableDragDrop ?? !0) && !!C, D = () => t.instanceId ?? "default", S = 32, f = vt({
59
60
  count: () => a.currentFiles().length,
60
61
  itemSize: () => S,
@@ -62,35 +63,35 @@ function Kt(t) {
62
63
  }), y = Z(() => {
63
64
  const {
64
65
  start: r,
65
- end: n
66
+ end: i
66
67
  } = f.range();
67
- return a.currentFiles().slice(r, n);
68
+ return a.currentFiles().slice(r, i);
68
69
  }), E = (r) => {
69
- const n = a.sortConfig();
70
+ const i = a.sortConfig();
70
71
  a.setSortConfig({
71
72
  field: r,
72
- direction: n.field === r && n.direction === "asc" ? "desc" : "asc"
73
+ direction: i.field === r && i.direction === "asc" ? "desc" : "asc"
73
74
  });
74
75
  }, O = (r) => r === void 0 ? "-" : r < 1024 ? `${r} B` : r < 1024 * 1024 ? `${(r / 1024).toFixed(1)} KB` : `${(r / (1024 * 1024)).toFixed(1)} MB`, $ = (r) => r ? r.toLocaleDateString("en-US", {
75
76
  month: "short",
76
77
  day: "numeric",
77
78
  year: "numeric"
78
79
  }) : "-", X = (r) => {
79
- const n = () => a.sortConfig(), l = () => n().field === r.field;
80
+ const i = () => a.sortConfig(), l = () => i().field === r.field;
80
81
  return (() => {
81
- var d = zt();
82
+ var d = _t();
82
83
  return u(d, m(bt, {
83
84
  get class() {
84
- return H("w-3 h-3 transition-transform duration-150", l() && n().direction === "asc" && "rotate-180");
85
+ return H("w-3 h-3 transition-transform duration-150", l() && i().direction === "asc" && "rotate-180");
85
86
  }
86
87
  })), F(() => V(d, H("ml-1 transition-all duration-150", l() ? "opacity-100" : "opacity-0 group-hover:opacity-40"))), d;
87
88
  })();
88
- }, j = et("(min-width: 640px)"), A = et("(min-width: 768px)"), [K, Y] = ot(null), p = xt(K), N = (r, n, l) => Math.max(n, Math.min(l, r)), h = Z(() => {
89
- const r = p()?.width ?? 0, n = j(), l = A(), d = a.listColumnRatios(), x = 160, g = 120, w = 80, M = 128, o = 96;
90
- if (!n || r <= 0)
89
+ }, j = et("(min-width: 640px)"), A = et("(min-width: 768px)"), [K, Y] = ot(null), R = xt(K), N = (r, i, l) => Math.max(i, Math.min(l, r)), h = Z(() => {
90
+ const r = R()?.width ?? 0, i = j(), l = A(), d = a.listColumnRatios(), x = 160, g = 120, w = 80, M = 128, o = 96;
91
+ if (!i || r <= 0)
91
92
  return {
92
93
  width: r,
93
- showModified: n,
94
+ showModified: i,
94
95
  showSize: l,
95
96
  minName: x,
96
97
  minModified: g,
@@ -103,7 +104,7 @@ function Kt(t) {
103
104
  let P = (k > 0 ? d.modifiedAt / k : d.modifiedAt) * r;
104
105
  return P = N(P, g, Math.max(g, r - x)), {
105
106
  width: r,
106
- showModified: n,
107
+ showModified: i,
107
108
  showSize: l,
108
109
  minName: x,
109
110
  minModified: g,
@@ -112,31 +113,31 @@ function Kt(t) {
112
113
  sizeWidth: 0
113
114
  };
114
115
  }
115
- let i = Math.max(g, d.modifiedAt * r), s = Math.max(w, d.size * r);
116
+ let n = Math.max(g, d.modifiedAt * r), s = Math.max(w, d.size * r);
116
117
  const b = Math.max(0, r - x);
117
- if (i + s > b) {
118
- const I = i + s - b, k = Math.max(0, i - g), P = Math.max(0, s - w), T = k + P;
119
- T > 0 && (i -= I * (k / T), s -= I * (P / T));
118
+ if (n + s > b) {
119
+ const I = n + s - b, k = Math.max(0, n - g), P = Math.max(0, s - w), T = k + P;
120
+ T > 0 && (n -= I * (k / T), s -= I * (P / T));
120
121
  }
121
- return i = Math.max(g, i), s = Math.max(w, s), {
122
+ return n = Math.max(g, n), s = Math.max(w, s), {
122
123
  width: r,
123
- showModified: n,
124
+ showModified: i,
124
125
  showSize: l,
125
126
  minName: x,
126
127
  minModified: g,
127
128
  minSize: w,
128
- modifiedWidth: i,
129
+ modifiedWidth: n,
129
130
  sizeWidth: s
130
131
  };
131
132
  }), G = () => h().modifiedWidth, U = () => h().sizeWidth, Q = (r) => {
132
- const n = h();
133
- if (!n.showModified || n.width <= 0) return;
134
- if (!n.showSize) {
133
+ const i = h();
134
+ if (!i.showModified || i.width <= 0) return;
135
+ if (!i.showSize) {
135
136
  const I = a.listColumnRatios().size, k = Math.max(0, 1 - I);
136
137
  if (k <= 0) return;
137
- const P = n.width, T = n.modifiedWidth, e = Math.max(0, P - T), c = n.minName - e, z = T - n.minModified, v = N(r, c, z);
138
+ const P = i.width, T = i.modifiedWidth, e = Math.max(0, P - T), c = i.minName - e, z = T - i.minModified, v = N(r, c, z);
138
139
  if (v === 0) return;
139
- const R = e + v, J = T - v, lt = R / P * k, dt = J / P * k;
140
+ const p = e + v, J = T - v, lt = p / P * k, dt = J / P * k;
140
141
  a.setListColumnRatios({
141
142
  name: lt,
142
143
  modifiedAt: dt,
@@ -144,56 +145,56 @@ function Kt(t) {
144
145
  });
145
146
  return;
146
147
  }
147
- const l = n.width, d = n.modifiedWidth, x = n.sizeWidth, g = Math.max(0, l - d - x), w = n.minName - g, M = d - n.minModified, o = N(r, w, M);
148
+ const l = i.width, d = i.modifiedWidth, x = i.sizeWidth, g = Math.max(0, l - d - x), w = i.minName - g, M = d - i.minModified, o = N(r, w, M);
148
149
  if (o === 0) return;
149
- const i = g + o, s = d - o;
150
+ const n = g + o, s = d - o;
150
151
  a.setListColumnRatios({
151
- name: i / l,
152
+ name: n / l,
152
153
  modifiedAt: s / l,
153
154
  size: x / l
154
155
  });
155
156
  }, q = (r) => {
156
- const n = h();
157
- if (!n.showSize || n.width <= 0) return;
158
- const l = n.width, d = n.modifiedWidth, x = n.sizeWidth, g = n.minModified - d, w = x - n.minSize, M = N(r, g, w);
157
+ const i = h();
158
+ if (!i.showSize || i.width <= 0) return;
159
+ const l = i.width, d = i.modifiedWidth, x = i.sizeWidth, g = i.minModified - d, w = x - i.minSize, M = N(r, g, w);
159
160
  if (M === 0) return;
160
- const o = d + M, i = x - M, s = Math.max(0, l - o - i);
161
+ const o = d + M, n = x - M, s = Math.max(0, l - o - n);
161
162
  a.setListColumnRatios({
162
163
  name: s / l,
163
164
  modifiedAt: o / l,
164
- size: i / l
165
+ size: n / l
165
166
  });
166
167
  };
167
168
  return (() => {
168
- var r = Pt(), n = r.firstChild, l = n.firstChild, d = l.firstChild, x = d.firstChild, g = x.firstChild, w = g.nextSibling;
169
+ var r = kt(), i = r.firstChild, l = i.firstChild, d = l.firstChild, x = d.firstChild, g = x.firstChild, w = g.nextSibling;
169
170
  w.firstChild;
170
- var M = n.nextSibling;
171
- return tt(Y, n), d.$$click = () => E("name"), u(w, m(X, {
171
+ var M = i.nextSibling;
172
+ return tt(Y, i), d.$$click = () => E("name"), u(w, m(X, {
172
173
  field: "name"
173
174
  }), null), u(l, m(W, {
174
175
  get when() {
175
176
  return h().showModified;
176
177
  },
177
178
  get children() {
178
- return m(nt, {
179
+ return m(it, {
179
180
  direction: "horizontal",
180
181
  onResize: Q
181
182
  });
182
183
  }
183
- }), null), u(n, m(W, {
184
+ }), null), u(i, m(W, {
184
185
  get when() {
185
186
  return h().showModified;
186
187
  },
187
188
  get children() {
188
- var o = _t(), i = o.firstChild;
189
- return i.firstChild, i.$$click = () => E("modifiedAt"), u(i, m(X, {
189
+ var o = yt(), n = o.firstChild;
190
+ return n.firstChild, n.$$click = () => E("modifiedAt"), u(n, m(X, {
190
191
  field: "modifiedAt"
191
192
  }), null), u(o, m(W, {
192
193
  get when() {
193
194
  return h().showSize;
194
195
  },
195
196
  get children() {
196
- return m(nt, {
197
+ return m(it, {
197
198
  direction: "horizontal",
198
199
  onResize: q
199
200
  });
@@ -206,13 +207,13 @@ function Kt(t) {
206
207
  t: void 0
207
208
  }), o;
208
209
  }
209
- }), null), u(n, m(W, {
210
+ }), null), u(i, m(W, {
210
211
  get when() {
211
212
  return h().showSize;
212
213
  },
213
214
  get children() {
214
- var o = yt(), i = o.firstChild;
215
- return i.firstChild, i.$$click = () => E("size"), u(i, m(X, {
215
+ var o = It(), n = o.firstChild;
216
+ return n.firstChild, n.$$click = () => E("size"), u(n, m(X, {
216
217
  field: "size"
217
218
  }), null), F((s) => B(o, "width", `${U()}px`)), o;
218
219
  }
@@ -224,7 +225,7 @@ function Kt(t) {
224
225
  },
225
226
  get fallback() {
226
227
  return (() => {
227
- var o = Lt();
228
+ var o = Rt();
228
229
  return u(o, m(W, {
229
230
  get when() {
230
231
  return a.filterQueryApplied().trim();
@@ -234,24 +235,24 @@ function Kt(t) {
234
235
  },
235
236
  get children() {
236
237
  return [(() => {
237
- var i = kt(), s = i.firstChild, b = s.nextSibling;
238
- return b.nextSibling, u(i, () => a.filterQueryApplied(), b), i;
238
+ var n = Tt(), s = n.firstChild, b = s.nextSibling;
239
+ return b.nextSibling, u(n, () => a.filterQueryApplied(), b), n;
239
240
  })(), (() => {
240
- var i = Tt();
241
- return i.$$click = () => a.setFilterQuery(""), i;
241
+ var n = Lt();
242
+ return n.$$click = () => a.setFilterQuery(""), n;
242
243
  })()];
243
244
  }
244
245
  })), o;
245
246
  })();
246
247
  },
247
248
  get children() {
248
- var o = It();
249
+ var o = Pt();
249
250
  return u(o, m(at, {
250
251
  get each() {
251
252
  return y();
252
253
  },
253
- children: (i) => m(Et, {
254
- item: i,
254
+ children: (n) => m(Ft, {
255
+ item: n,
255
256
  formatSize: O,
256
257
  formatDate: $,
257
258
  get showModified() {
@@ -274,29 +275,31 @@ function Kt(t) {
274
275
  },
275
276
  dragContext: C
276
277
  })
277
- })), F((i) => {
278
+ })), F((n) => {
278
279
  var s = `${f.paddingTop()}px`, b = `${f.paddingBottom()}px`;
279
- return s !== i.e && B(o, "padding-top", i.e = s), b !== i.t && B(o, "padding-bottom", i.t = b), i;
280
+ return s !== n.e && B(o, "padding-top", n.e = s), b !== n.t && B(o, "padding-bottom", n.t = b), n;
280
281
  }, {
281
282
  e: void 0,
282
283
  t: void 0
283
284
  }), o;
284
285
  }
285
286
  })), F((o) => {
286
- var i = H("flex flex-col h-full min-h-0", t.class), s = H("relative flex-1 min-w-0", h().showModified && "border-r border-border");
287
- return i !== o.e && V(r, o.e = i), s !== o.t && V(l, o.t = s), o;
287
+ var n = H("flex flex-col h-full min-h-0", t.class), s = H("relative flex-1 min-w-0", h().showModified && "border-r border-border");
288
+ return n !== o.e && V(r, o.e = n), s !== o.t && V(l, o.t = s), o;
288
289
  }, {
289
290
  e: void 0,
290
291
  t: void 0
291
292
  }), r;
292
293
  })();
293
294
  }
294
- function Et(t) {
295
- const a = st(), C = () => a.isSelected(t.item.id), L = () => a.getFilterMatchForId(t.item.id), D = gt(() => t.item), S = Dt(a, D);
295
+ function Ft(t) {
296
+ const a = st(), C = () => a.isSelected(t.item.id), L = () => a.getFilterMatchForId(t.item.id), D = gt(() => t.item), S = Dt(a, D, {
297
+ source: "list"
298
+ });
296
299
  let f, y = null, E = 0, O = 0, $ = !1;
297
300
  const X = 5, j = 500;
298
301
  let A = null;
299
- const [K, Y] = ot(!1), p = () => f === "touch" || f === "pen", N = () => t.item.type === "folder", h = () => N() && t.enableDragDrop && t.dragContext, G = () => {
302
+ const [K, Y] = ot(!1), R = () => f === "touch" || f === "pen", N = () => t.item.type === "folder", h = () => N() && t.enableDragDrop && t.dragContext, G = () => {
300
303
  if (!h() || !t.dragContext) return !1;
301
304
  const e = t.dragContext.dragState();
302
305
  return e.isDragging ? t.dragContext.canDropOn(e.draggedItems, t.item.path, t.item, t.instanceId) : !1;
@@ -310,40 +313,40 @@ function Et(t) {
310
313
  typeof document > "u" || (document.removeEventListener("pointermove", d, !0), document.removeEventListener("pointerup", x, !0), document.removeEventListener("pointercancel", g, !0));
311
314
  }, r = () => {
312
315
  typeof document > "u" || (document.addEventListener("pointermove", d, !0), document.addEventListener("pointerup", x, !0), document.addEventListener("pointercancel", g, !0));
313
- }, n = (e) => {
316
+ }, i = (e) => {
314
317
  Q(), q(), $ && t.dragContext && t.dragContext.endDrag(e), y = null, $ = !1;
315
318
  };
316
319
  ht(() => {
317
- n(!1);
320
+ i(!1);
318
321
  });
319
322
  const l = (e, c) => {
320
323
  if (!t.enableDragDrop || !t.dragContext || $) return;
321
324
  $ = !0, C() || a.selectItem(t.item.id, !1);
322
- const z = a.getSelectedItemsList(), R = (z.length > 0 && C() ? z : [t.item]).map((J) => ({
325
+ const z = a.getSelectedItemsList(), p = (z.length > 0 && C() ? z : [t.item]).map((J) => ({
323
326
  item: J,
324
327
  sourceInstanceId: t.instanceId,
325
328
  sourcePath: a.currentPath()
326
329
  }));
327
- if (p() && "vibrate" in navigator)
330
+ if (R() && "vibrate" in navigator)
328
331
  try {
329
332
  navigator.vibrate(50);
330
333
  } catch {
331
334
  }
332
- t.dragContext.startDrag(R, e, c);
335
+ t.dragContext.startDrag(p, e, c);
333
336
  }, d = (e) => {
334
337
  if (y !== e.pointerId) return;
335
338
  const c = e.clientX - E, z = e.clientY - O, v = Math.sqrt(c * c + z * z);
336
- if (p() && !$ && v > 10) {
337
- n(!1);
339
+ if (R() && !$ && v > 10) {
340
+ i(!1);
338
341
  return;
339
342
  }
340
- !p() && !$ && v > X && l(e.clientX, e.clientY), $ && t.dragContext && t.dragContext.updateDrag(e.clientX, e.clientY);
343
+ !R() && !$ && v > X && l(e.clientX, e.clientY), $ && t.dragContext && t.dragContext.updateDrag(e.clientX, e.clientY);
341
344
  }, x = (e) => {
342
- y === e.pointerId && (S.onPointerUp(), n(!0));
345
+ y === e.pointerId && (S.onPointerUp(), i(!0));
343
346
  }, g = (e) => {
344
- y === e.pointerId && (S.onPointerCancel(), n(!1));
347
+ y === e.pointerId && (S.onPointerCancel(), i(!1));
345
348
  }, w = (e) => {
346
- f = e.pointerType, S.onPointerDown(e), !(e.pointerType === "mouse" && e.button !== 0) && (!t.enableDragDrop || !t.dragContext || (y = e.pointerId, E = e.clientX, O = e.clientY, $ = !1, r(), p() && (Q(), A = setTimeout(() => {
349
+ f = e.pointerType, S.onPointerDown(e), !(e.pointerType === "mouse" && e.button !== 0) && (!t.enableDragDrop || !t.dragContext || (y = e.pointerId, E = e.clientX, O = e.clientY, $ = !1, r(), R() && (Q(), A = setTimeout(() => {
347
350
  y !== null && !$ && l(E, O);
348
351
  }, j))));
349
352
  }, M = (e) => {
@@ -353,13 +356,13 @@ function Et(t) {
353
356
  const c = t.dragContext.dragState();
354
357
  if (!c.isDragging) return;
355
358
  Y(!0);
356
- const z = t.dragContext.canDropOn(c.draggedItems, t.item.path, t.item, t.instanceId), R = e.currentTarget?.getBoundingClientRect() ?? null;
359
+ const z = t.dragContext.canDropOn(c.draggedItems, t.item.path, t.item, t.instanceId), p = e.currentTarget?.getBoundingClientRect() ?? null;
357
360
  t.dragContext.setDropTarget({
358
361
  instanceId: t.instanceId,
359
362
  targetPath: t.item.path,
360
363
  targetItem: t.item
361
- }, z, R);
362
- }, i = (e) => {
364
+ }, z, p);
365
+ }, n = (e) => {
363
366
  if (!t.dragContext) return;
364
367
  Y(!1);
365
368
  const c = t.dragContext.dragState();
@@ -370,26 +373,28 @@ function Et(t) {
370
373
  return;
371
374
  }
372
375
  if (!S.consumeClickSuppression(e)) {
373
- if (p()) {
376
+ if (R()) {
374
377
  a.openItem(t.item);
375
378
  return;
376
379
  }
377
380
  a.selectItem(t.item.id, e.metaKey || e.ctrlKey);
378
381
  }
379
382
  }, b = () => {
380
- p() || a.openItem(t.item);
383
+ R() || a.openItem(t.item);
381
384
  }, I = (e) => {
382
- if (e.preventDefault(), e.stopPropagation(), p()) return;
385
+ if (e.preventDefault(), e.stopPropagation(), R()) return;
383
386
  C() || a.selectItem(t.item.id, !1);
384
387
  const c = a.getSelectedItemsList(), z = c.length > 0 ? c : [t.item];
385
- a.showContextMenu({
388
+ a.showContextMenu($t({
386
389
  x: e.clientX,
387
390
  y: e.clientY,
388
- items: z
389
- });
391
+ triggerItem: t.item,
392
+ items: z,
393
+ source: "list"
394
+ }));
390
395
  }, k = () => t.dragContext?.dragState(), P = () => k()?.isDragging ?? !1, T = () => K() && P() && h();
391
396
  return (() => {
392
- var e = Rt(), c = e.firstChild, z = c.firstChild;
397
+ var e = Wt(), c = e.firstChild, z = c.firstChild;
393
398
  return mt(e, ut(St, {
394
399
  onClick: s,
395
400
  onDblClick: b,
@@ -397,7 +402,7 @@ function Et(t) {
397
402
  onPointerDown: w,
398
403
  onPointerMove: M,
399
404
  onPointerEnter: o,
400
- onPointerLeave: i,
405
+ onPointerLeave: n,
401
406
  get class() {
402
407
  return H(
403
408
  "group w-full h-8 flex items-center text-xs cursor-pointer",
@@ -417,7 +422,7 @@ function Et(t) {
417
422
  return t.item;
418
423
  },
419
424
  class: "w-4 h-4"
420
- })), u(c, m(Wt, {
425
+ })), u(c, m(Et, {
421
426
  get name() {
422
427
  return t.item.name;
423
428
  },
@@ -429,24 +434,24 @@ function Et(t) {
429
434
  return t.showModified;
430
435
  },
431
436
  get children() {
432
- var v = it();
433
- return u(v, () => t.formatDate(t.item.modifiedAt)), F((R) => B(v, "width", `${t.modifiedWidthPx}px`)), v;
437
+ var v = nt();
438
+ return u(v, () => t.formatDate(t.item.modifiedAt)), F((p) => B(v, "width", `${t.modifiedWidthPx}px`)), v;
434
439
  }
435
440
  }), null), u(e, m(W, {
436
441
  get when() {
437
442
  return t.showSize;
438
443
  },
439
444
  get children() {
440
- var v = it();
445
+ var v = nt();
441
446
  return u(v, (() => {
442
- var R = rt(() => t.item.type === "folder");
443
- return () => R() ? "-" : t.formatSize(t.item.size);
444
- })()), F((R) => B(v, "width", `${t.sizeWidthPx}px`)), v;
447
+ var p = rt(() => t.item.type === "folder");
448
+ return () => p() ? "-" : t.formatSize(t.item.size);
449
+ })()), F((p) => B(v, "width", `${t.sizeWidthPx}px`)), v;
445
450
  }
446
451
  }), null), e;
447
452
  })();
448
453
  }
449
454
  ft(["click"]);
450
455
  export {
451
- Kt as FileListView
456
+ Jt as FileListView
452
457
  };
@@ -0,0 +1,10 @@
1
+ import type { ContextMenuEvent, ContextMenuSource, FileItem } from './types';
2
+ type ItemContextMenuSource = Extract<ContextMenuSource, 'list' | 'grid' | 'tree'>;
3
+ export declare function createItemContextMenuEvent(params: {
4
+ x: number;
5
+ y: number;
6
+ triggerItem: FileItem;
7
+ items: FileItem[];
8
+ source: ItemContextMenuSource;
9
+ }): ContextMenuEvent;
10
+ export {};
@@ -0,0 +1,19 @@
1
+ function n(e, t) {
2
+ return t.length !== 1 || e.type !== "folder" || t[0]?.path !== e.path ? null : {
3
+ path: e.path,
4
+ item: e
5
+ };
6
+ }
7
+ function o(e) {
8
+ return {
9
+ x: e.x,
10
+ y: e.y,
11
+ items: e.items,
12
+ targetKind: "item",
13
+ source: e.source,
14
+ directory: n(e.triggerItem, e.items)
15
+ };
16
+ }
17
+ export {
18
+ o as createItemContextMenuEvent
19
+ };
@@ -8,4 +8,4 @@ export { Breadcrumb, type BreadcrumbProps } from './Breadcrumb';
8
8
  export { FileBrowserToolbar, type FileBrowserToolbarProps } from './FileBrowserToolbar';
9
9
  export { FileBrowserDragPreview } from './DragPreview';
10
10
  export { FolderIcon, FolderOpenIcon, FileIcon, CodeFileIcon, JavaScriptFileIcon, TypeScriptFileIcon, ShellScriptFileIcon, ImageFileIcon, DocumentFileIcon, ConfigFileIcon, StyleFileIcon, FileItemIcon, getFileIcon, resolveFileItemIcon, } from './FileIcons';
11
- export type { FileItem, FileItemIconOverride, ViewMode, SortField, SortDirection, SortConfig, FileListColumnRatios, FileBrowserContextValue, ContextMenuActionType, ContextMenuItem, ContextMenuEvent, ContextMenuCallbacks, OptimisticUpdateType, OptimisticRemove, OptimisticUpdate, OptimisticInsert, OptimisticOperation, ScrollPosition, } from './types';
11
+ export type { FileItem, FileItemIconOverride, ViewMode, SortField, SortDirection, SortConfig, FileListColumnRatios, FileBrowserContextValue, ContextMenuActionType, ContextMenuTargetKind, ContextMenuSource, ContextMenuDirectory, ContextMenuItem, ContextMenuEvent, ContextMenuCallbacks, OptimisticUpdateType, OptimisticRemove, OptimisticUpdate, OptimisticInsert, OptimisticOperation, ScrollPosition, } from './types';
@@ -3,6 +3,7 @@ export declare function createLongPressContextMenuHandlers(ctx: FileBrowserConte
3
3
  delayMs?: number;
4
4
  moveTolerancePx?: number;
5
5
  selectOnOpen?: boolean;
6
+ source?: 'list' | 'grid' | 'tree';
6
7
  }): {
7
8
  onPointerDown: (e: PointerEvent) => void;
8
9
  onPointerMove: (e: PointerEvent) => void;
@@ -1,42 +1,55 @@
1
- import { onCleanup as T } from "solid-js";
2
- function v(s, i, u) {
3
- const d = u?.delayMs ?? 500, p = u?.moveTolerancePx ?? 10, m = u?.selectOnOpen ?? !0;
4
- let n = null, l = null, c = !1;
5
- const r = () => {
6
- n !== null && typeof window < "u" && (window.clearTimeout(n), n = null), l = null;
1
+ import { onCleanup as v } from "solid-js";
2
+ import { createItemContextMenuEvent as p } from "./contextMenuEvent.js";
3
+ function S(s, r, i) {
4
+ const m = i?.delayMs ?? 500, w = i?.moveTolerancePx ?? 10, C = i?.selectOnOpen ?? !0, f = i?.source ?? "list";
5
+ let t = null, l = null, u = !1;
6
+ const c = () => {
7
+ t !== null && typeof window < "u" && (window.clearTimeout(t), t = null), l = null;
7
8
  }, a = () => {
8
- c = !0;
9
- }, w = (e, t) => {
10
- if (!m) {
11
- s.showContextMenu({ x: e, y: t, items: [i] }), a();
9
+ u = !0;
10
+ }, y = (e, n) => {
11
+ if (!C) {
12
+ s.showContextMenu(p({
13
+ x: e,
14
+ y: n,
15
+ triggerItem: r,
16
+ items: [r],
17
+ source: f
18
+ })), a();
12
19
  return;
13
20
  }
14
- const o = i.id;
21
+ const o = r.id;
15
22
  s.isSelected(o) || s.selectItem(o, !1);
16
- const f = s.getSelectedItemsList(), h = f.length > 0 ? f : [i];
17
- s.showContextMenu({ x: e, y: t, items: h }), a();
18
- }, y = (e) => {
19
- if (c = !1, e.pointerType === "mouse" || typeof window > "u") return;
20
- r(), l = { x: e.clientX, y: e.clientY };
21
- const t = e.clientX, o = e.clientY;
22
- n = window.setTimeout(() => {
23
- n = null, w(t, o);
24
- }, d);
25
- }, C = (e) => {
26
- if (n === null || !l) return;
27
- const t = e.clientX - l.x, o = e.clientY - l.y;
28
- Math.hypot(t, o) > p && (r(), a());
29
- }, M = () => r(), P = () => r(), x = (e) => c ? (c = !1, e.preventDefault(), e.stopPropagation(), !0) : !1;
30
- return T(() => {
31
- r();
23
+ const d = s.getSelectedItemsList(), h = d.length > 0 ? d : [r];
24
+ s.showContextMenu(p({
25
+ x: e,
26
+ y: n,
27
+ triggerItem: r,
28
+ items: h,
29
+ source: f
30
+ })), a();
31
+ }, M = (e) => {
32
+ if (u = !1, e.pointerType === "mouse" || typeof window > "u") return;
33
+ c(), l = { x: e.clientX, y: e.clientY };
34
+ const n = e.clientX, o = e.clientY;
35
+ t = window.setTimeout(() => {
36
+ t = null, y(n, o);
37
+ }, m);
38
+ }, g = (e) => {
39
+ if (t === null || !l) return;
40
+ const n = e.clientX - l.x, o = e.clientY - l.y;
41
+ Math.hypot(n, o) > w && (c(), a());
42
+ }, x = () => c(), P = () => c(), I = (e) => u ? (u = !1, e.preventDefault(), e.stopPropagation(), !0) : !1;
43
+ return v(() => {
44
+ c();
32
45
  }), {
33
- onPointerDown: y,
34
- onPointerMove: C,
35
- onPointerUp: M,
46
+ onPointerDown: M,
47
+ onPointerMove: g,
48
+ onPointerUp: x,
36
49
  onPointerCancel: P,
37
- consumeClickSuppression: x
50
+ consumeClickSuppression: I
38
51
  };
39
52
  }
40
53
  export {
41
- v as createLongPressContextMenuHandlers
54
+ S as createLongPressContextMenuHandlers
42
55
  };
@@ -42,6 +42,12 @@ export interface FileListColumnRatios {
42
42
  * Built-in context menu action types
43
43
  */
44
44
  export type ContextMenuActionType = 'duplicate' | 'copy-name' | 'ask-agent' | 'copy-to' | 'move-to' | 'delete' | 'rename' | 'custom';
45
+ export type ContextMenuTargetKind = 'item' | 'directory-background';
46
+ export type ContextMenuSource = 'list' | 'grid' | 'tree' | 'background' | 'custom';
47
+ export interface ContextMenuDirectory {
48
+ path: string;
49
+ item?: FileItem;
50
+ }
45
51
  /**
46
52
  * Context menu item definition
47
53
  */
@@ -63,7 +69,9 @@ export interface ContextMenuItem {
63
69
  /** Keyboard shortcut hint (display only) */
64
70
  shortcut?: string;
65
71
  /** Custom handler for 'custom' type actions */
66
- onAction?: (items: FileItem[]) => void;
72
+ onAction?: (items: FileItem[], event?: ContextMenuEvent) => void;
73
+ /** Cascade submenu items */
74
+ children?: ContextMenuItem[];
67
75
  }
68
76
  /**
69
77
  * Context menu event with position and target items
@@ -75,6 +83,12 @@ export interface ContextMenuEvent {
75
83
  y: number;
76
84
  /** Target file/folder items */
77
85
  items: FileItem[];
86
+ /** Semantic menu target category */
87
+ targetKind: ContextMenuTargetKind;
88
+ /** Source surface that opened the menu */
89
+ source: ContextMenuSource;
90
+ /** Resolved directory scope for directory-scoped actions */
91
+ directory: ContextMenuDirectory | null;
78
92
  }
79
93
  /**
80
94
  * Callbacks for context menu actions