@floegence/floe-webapp-core 0.35.4 → 0.35.6
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/components/file-browser/FileBrowser.d.ts +2 -0
- package/dist/components/file-browser/FileBrowser.js +33 -27
- package/dist/components/file-browser/FileBrowserToolbar.d.ts +2 -0
- package/dist/components/file-browser/FileBrowserToolbar.js +55 -47
- package/dist/components/file-browser/FileContextMenu.d.ts +2 -0
- package/dist/components/file-browser/FileContextMenu.js +175 -157
- package/dist/components/file-browser/types.d.ts +2 -1
- package/package.json +1 -1
|
@@ -32,6 +32,8 @@ export interface FileBrowserProps {
|
|
|
32
32
|
header?: JSX.Element;
|
|
33
33
|
/** Actions rendered on the right side of the Explorer sidebar header */
|
|
34
34
|
sidebarHeaderActions?: JSX.Element;
|
|
35
|
+
/** Actions rendered at the end of the main file browser toolbar */
|
|
36
|
+
toolbarEndActions?: JSX.Element;
|
|
35
37
|
/** Sidebar width in pixels */
|
|
36
38
|
sidebarWidth?: number;
|
|
37
39
|
/** Persisted sidebar width storage key (defaults to a shared user preference key) */
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { createComponent as n, insert as i, use as
|
|
2
|
-
import { onMount as
|
|
3
|
-
import { cn as
|
|
4
|
-
import { useLayout as
|
|
5
|
-
import { useFileBrowserDrag as
|
|
1
|
+
import { createComponent as n, insert as i, use as F, memo as P, effect as _, className as k, template as w, delegateEvents as z } from "solid-js/web";
|
|
2
|
+
import { onMount as W, onCleanup as E, createEffect as K, Show as u } from "solid-js";
|
|
3
|
+
import { cn as L } from "../../utils/cn.js";
|
|
4
|
+
import { useLayout as B } from "../../context/LayoutContext.js";
|
|
5
|
+
import { useFileBrowserDrag as O } from "../../context/FileBrowserDragContext.js";
|
|
6
6
|
import { deferAfterPaint as V } from "../../utils/defer.js";
|
|
7
7
|
import { FileBrowserProvider as H, useFileBrowser as N } from "./FileBrowserContext.js";
|
|
8
8
|
import { SidebarPane as T } from "../layout/SidebarPane.js";
|
|
@@ -13,7 +13,7 @@ import { FileBrowserToolbar as q } from "./FileBrowserToolbar.js";
|
|
|
13
13
|
import { FileContextMenu as J } from "./FileContextMenu.js";
|
|
14
14
|
import { DragPreview as U } from "./DragPreview.js";
|
|
15
15
|
var X = /* @__PURE__ */ w('<div class="border-b border-border">'), Y = /* @__PURE__ */ w('<div><div class="flex flex-1 min-h-0 relative"><div class="flex-1 min-w-0 flex flex-col"><div class="flex-1 min-h-0"></div><div class="flex items-center justify-between px-3 py-1 border-t border-border text-[10px] text-muted-foreground"><span> items</span><span class="truncate max-w-[200px]">');
|
|
16
|
-
function
|
|
16
|
+
function be(e) {
|
|
17
17
|
return n(H, {
|
|
18
18
|
get files() {
|
|
19
19
|
return e.files;
|
|
@@ -65,6 +65,9 @@ function me(e) {
|
|
|
65
65
|
get sidebarHeaderActions() {
|
|
66
66
|
return e.sidebarHeaderActions;
|
|
67
67
|
},
|
|
68
|
+
get toolbarEndActions() {
|
|
69
|
+
return e.toolbarEndActions;
|
|
70
|
+
},
|
|
68
71
|
get sidebarResizable() {
|
|
69
72
|
return e.sidebarResizable;
|
|
70
73
|
},
|
|
@@ -97,12 +100,12 @@ function me(e) {
|
|
|
97
100
|
});
|
|
98
101
|
}
|
|
99
102
|
function Z(e) {
|
|
100
|
-
const t = N(), I =
|
|
103
|
+
const t = N(), I = B(), o = O(), f = () => I.isMobile(), M = () => t.sidebarWidth(), S = () => e.sidebarResizable ?? !0, a = () => (e.enableDragDrop ?? !0) && !!o, d = () => e.instanceId ?? `filebrowser-${Math.random().toString(36).slice(2, 9)}`;
|
|
101
104
|
let h, C = null, x = null;
|
|
102
|
-
|
|
105
|
+
W(() => {
|
|
103
106
|
if (!o || !a()) return;
|
|
104
107
|
const r = {
|
|
105
|
-
instanceId:
|
|
108
|
+
instanceId: d(),
|
|
106
109
|
currentPath: t.currentPath,
|
|
107
110
|
files: t.files,
|
|
108
111
|
onDragMove: e.onDragMove,
|
|
@@ -112,11 +115,11 @@ function Z(e) {
|
|
|
112
115
|
optimisticInsert: t.optimisticInsert
|
|
113
116
|
};
|
|
114
117
|
o.registerInstance(r);
|
|
115
|
-
}),
|
|
116
|
-
o && a() && o.unregisterInstance(
|
|
118
|
+
}), E(() => {
|
|
119
|
+
o && a() && o.unregisterInstance(d());
|
|
117
120
|
});
|
|
118
121
|
let v = !1, g = !1;
|
|
119
|
-
|
|
122
|
+
K(() => {
|
|
120
123
|
const r = f();
|
|
121
124
|
if (!v) {
|
|
122
125
|
v = !0, g = r, r && e.hideSidebarOnMobile !== !1 && !t.sidebarCollapsed() && t.toggleSidebar();
|
|
@@ -128,7 +131,7 @@ function Z(e) {
|
|
|
128
131
|
(r.metaKey || r.ctrlKey) && r.key.toLowerCase() === "f" && (r.preventDefault(), t.setFilterActive(!0), V(() => h?.focus()));
|
|
129
132
|
}, y = () => !t.sidebarCollapsed() || !f();
|
|
130
133
|
return (() => {
|
|
131
|
-
var r = Y(),
|
|
134
|
+
var r = Y(), b = r.firstChild, m = b.firstChild, c = m.firstChild, R = c.nextSibling, s = R.firstChild, $ = s.firstChild, A = s.nextSibling;
|
|
132
135
|
return r.$$keydown = D, i(r, n(u, {
|
|
133
136
|
get when() {
|
|
134
137
|
return e.header;
|
|
@@ -137,7 +140,7 @@ function Z(e) {
|
|
|
137
140
|
var l = X();
|
|
138
141
|
return i(l, () => e.header), l;
|
|
139
142
|
}
|
|
140
|
-
}),
|
|
143
|
+
}), b), i(b, n(T, {
|
|
141
144
|
title: "Explorer",
|
|
142
145
|
get width() {
|
|
143
146
|
return M();
|
|
@@ -164,16 +167,19 @@ function Z(e) {
|
|
|
164
167
|
get children() {
|
|
165
168
|
return n(j, {
|
|
166
169
|
get instanceId() {
|
|
167
|
-
return
|
|
170
|
+
return d();
|
|
168
171
|
},
|
|
169
172
|
get enableDragDrop() {
|
|
170
173
|
return a();
|
|
171
174
|
}
|
|
172
175
|
});
|
|
173
176
|
}
|
|
174
|
-
}),
|
|
175
|
-
filterInputRef: (l) => h = l
|
|
176
|
-
|
|
177
|
+
}), m), i(m, n(q, {
|
|
178
|
+
filterInputRef: (l) => h = l,
|
|
179
|
+
get endActions() {
|
|
180
|
+
return e.toolbarEndActions;
|
|
181
|
+
}
|
|
182
|
+
}), c), F((l) => {
|
|
177
183
|
C = l;
|
|
178
184
|
}, c), i(c, n(u, {
|
|
179
185
|
get when() {
|
|
@@ -182,7 +188,7 @@ function Z(e) {
|
|
|
182
188
|
get fallback() {
|
|
183
189
|
return n(Q, {
|
|
184
190
|
get instanceId() {
|
|
185
|
-
return
|
|
191
|
+
return d();
|
|
186
192
|
},
|
|
187
193
|
get enableDragDrop() {
|
|
188
194
|
return a();
|
|
@@ -192,28 +198,28 @@ function Z(e) {
|
|
|
192
198
|
get children() {
|
|
193
199
|
return n(G, {
|
|
194
200
|
get instanceId() {
|
|
195
|
-
return
|
|
201
|
+
return d();
|
|
196
202
|
},
|
|
197
203
|
get enableDragDrop() {
|
|
198
204
|
return a();
|
|
199
205
|
}
|
|
200
206
|
});
|
|
201
207
|
}
|
|
202
|
-
})), i(
|
|
208
|
+
})), i(s, () => t.currentFiles().length, $), i(s, n(u, {
|
|
203
209
|
get when() {
|
|
204
210
|
return t.filterQueryApplied().trim();
|
|
205
211
|
},
|
|
206
212
|
get children() {
|
|
207
213
|
return [" ", "(filtered)"];
|
|
208
214
|
}
|
|
209
|
-
}), null), i(
|
|
215
|
+
}), null), i(s, n(u, {
|
|
210
216
|
get when() {
|
|
211
217
|
return t.selectedItems().size > 0;
|
|
212
218
|
},
|
|
213
219
|
get children() {
|
|
214
|
-
return [" · ",
|
|
220
|
+
return [" · ", P(() => t.selectedItems().size), " selected"];
|
|
215
221
|
}
|
|
216
|
-
}), null), i(
|
|
222
|
+
}), null), i(A, () => t.currentPath()), i(r, n(J, {
|
|
217
223
|
get callbacks() {
|
|
218
224
|
return e.contextMenuCallbacks;
|
|
219
225
|
},
|
|
@@ -233,10 +239,10 @@ function Z(e) {
|
|
|
233
239
|
get children() {
|
|
234
240
|
return n(U, {});
|
|
235
241
|
}
|
|
236
|
-
}), null),
|
|
242
|
+
}), null), _(() => k(r, L("flex flex-col h-full min-h-0 bg-background", "border border-border rounded-lg overflow-hidden", "shadow-sm", e.class))), r;
|
|
237
243
|
})();
|
|
238
244
|
}
|
|
239
|
-
|
|
245
|
+
z(["keydown"]);
|
|
240
246
|
export {
|
|
241
|
-
|
|
247
|
+
be as FileBrowser
|
|
242
248
|
};
|
|
@@ -3,6 +3,8 @@ export interface FileBrowserToolbarProps {
|
|
|
3
3
|
class?: string;
|
|
4
4
|
/** Reference to focus the filter input */
|
|
5
5
|
filterInputRef?: (el: HTMLInputElement) => void;
|
|
6
|
+
/** Actions rendered at the end of the toolbar */
|
|
7
|
+
endActions?: JSX.Element;
|
|
6
8
|
}
|
|
7
9
|
/**
|
|
8
10
|
* Toolbar with navigation, breadcrumb, filter, and view mode toggle
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
import { addEventListener as
|
|
2
|
-
import { onMount as R, Show as
|
|
3
|
-
import { cn as
|
|
1
|
+
import { addEventListener as M, insert as n, createComponent as l, use as S, effect as s, className as f, template as a, setAttribute as g, delegateEvents as Q } from "solid-js/web";
|
|
2
|
+
import { onMount as R, Show as k } from "solid-js";
|
|
3
|
+
import { cn as v } from "../../utils/cn.js";
|
|
4
4
|
import { deferAfterPaint as E } from "../../utils/defer.js";
|
|
5
5
|
import { useFileBrowser as L } from "./FileBrowserContext.js";
|
|
6
6
|
import { Breadcrumb as T } from "./Breadcrumb.js";
|
|
7
7
|
import { Grid as V } from "../icons/index.js";
|
|
8
|
-
var N = /* @__PURE__ */
|
|
9
|
-
const
|
|
8
|
+
var N = /* @__PURE__ */ a('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><line x1=8 y1=6 x2=21 y2=6></line><line x1=8 y1=12 x2=21 y2=12></line><line x1=8 y1=18 x2=21 y2=18></line><line x1=3 y1=6 x2=3.01 y2=6></line><line x1=3 y1=12 x2=3.01 y2=12></line><line x1=3 y1=18 x2=3.01 y2=18>'), U = /* @__PURE__ */ a('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"></path><path d="M12 10v6"></path><path d="m9 13 3-3 3 3">'), G = /* @__PURE__ */ a('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><rect width=18 height=18 x=3 y=3 rx=2 ry=2></rect><line x1=9 y1=3 x2=9 y2=21>'), P = /* @__PURE__ */ a('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><circle cx=11 cy=11 r=8></circle><path d="m21 21-4.3-4.3">'), D = /* @__PURE__ */ a('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><path d="M18 6 6 18"></path><path d="m6 6 12 12">'), H = /* @__PURE__ */ a('<button type=button aria-label="Clear filter">'), K = /* @__PURE__ */ a('<div class="flex items-center flex-1 gap-1 px-2 py-1 bg-muted/50 rounded-md border border-border/50 focus-within:border-ring focus-within:ring-1 focus-within:ring-ring"><input type=text placeholder=Filter... aria-label="Filter files by name">'), X = /* @__PURE__ */ a('<div class="ml-0.5 flex shrink-0 items-center gap-1">'), Z = /* @__PURE__ */ a('<div><button type=button aria-label="Toggle sidebar"></button><button type=button aria-label="Navigate to parent folder"></button><div></div><div></div><div class="flex items-center gap-0.5 p-0.5 bg-muted/50 rounded-md">'), q = /* @__PURE__ */ a('<button type=button aria-label="Filter files">'), z = /* @__PURE__ */ a("<button type=button>");
|
|
9
|
+
const J = (r) => (() => {
|
|
10
10
|
var e = N();
|
|
11
11
|
return s(() => g(e, "class", r.class)), e;
|
|
12
|
-
})(),
|
|
12
|
+
})(), O = (r) => (() => {
|
|
13
13
|
var e = U();
|
|
14
14
|
return s(() => g(e, "class", r.class)), e;
|
|
15
|
-
})(),
|
|
15
|
+
})(), W = (r) => (() => {
|
|
16
16
|
var e = G();
|
|
17
17
|
return s(() => g(e, "class", r.class)), e;
|
|
18
18
|
})(), j = (r) => (() => {
|
|
19
19
|
var e = P();
|
|
20
20
|
return s(() => g(e, "class", r.class)), e;
|
|
21
|
-
})(),
|
|
21
|
+
})(), Y = (r) => (() => {
|
|
22
22
|
var e = D();
|
|
23
23
|
return s(() => g(e, "class", r.class)), e;
|
|
24
24
|
})();
|
|
25
|
-
function
|
|
25
|
+
function se(r) {
|
|
26
26
|
const e = L();
|
|
27
|
-
let
|
|
27
|
+
let i;
|
|
28
28
|
const c = () => {
|
|
29
|
-
const
|
|
30
|
-
return
|
|
31
|
-
},
|
|
32
|
-
e.isFilterActive() ? (e.setFilterQuery(""), e.setFilterActive(!1)) : (e.setFilterActive(!0), E(() =>
|
|
33
|
-
},
|
|
34
|
-
e.setFilterQuery(""),
|
|
35
|
-
},
|
|
36
|
-
|
|
29
|
+
const d = e.currentPath();
|
|
30
|
+
return d !== "/" && d !== "";
|
|
31
|
+
}, b = () => {
|
|
32
|
+
e.isFilterActive() ? (e.setFilterQuery(""), e.setFilterActive(!1)) : (e.setFilterActive(!0), E(() => i?.focus()));
|
|
33
|
+
}, h = () => {
|
|
34
|
+
e.setFilterQuery(""), i?.focus();
|
|
35
|
+
}, w = (d) => {
|
|
36
|
+
d.key === "Escape" && (e.setFilterQuery(""), e.setFilterActive(!1));
|
|
37
37
|
}, I = () => {
|
|
38
38
|
e.filterQuery().trim() || e.setFilterActive(!1);
|
|
39
39
|
};
|
|
40
40
|
return R(() => {
|
|
41
|
-
r.filterInputRef &&
|
|
41
|
+
r.filterInputRef && i && r.filterInputRef(i);
|
|
42
42
|
}), (() => {
|
|
43
|
-
var
|
|
44
|
-
return
|
|
43
|
+
var d = Z(), x = d.firstChild, m = x.nextSibling, p = m.nextSibling, y = p.nextSibling, $ = y.nextSibling;
|
|
44
|
+
return M(x, "click", e.toggleSidebar, !0), n(x, l(W, {
|
|
45
45
|
class: "w-4 h-4"
|
|
46
|
-
})),
|
|
46
|
+
})), M(m, "click", e.navigateUp, !0), n(m, l(O, {
|
|
47
47
|
class: "w-4 h-4"
|
|
48
|
-
})),
|
|
48
|
+
})), n(p, l(T, {})), n(y, l(k, {
|
|
49
49
|
get when() {
|
|
50
50
|
return e.isFilterActive();
|
|
51
51
|
},
|
|
52
52
|
get fallback() {
|
|
53
53
|
return (() => {
|
|
54
|
-
var t =
|
|
55
|
-
return t.$$click =
|
|
54
|
+
var t = q();
|
|
55
|
+
return t.$$click = b, n(t, l(j, {
|
|
56
56
|
class: "w-4 h-4"
|
|
57
|
-
})), s(() =>
|
|
57
|
+
})), s(() => f(t, v("flex items-center justify-center w-7 h-7 rounded cursor-pointer", "transition-colors duration-100", "hover:bg-muted/70", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"))), t;
|
|
58
58
|
})();
|
|
59
59
|
},
|
|
60
60
|
get children() {
|
|
61
|
-
var t = K(),
|
|
62
|
-
return
|
|
61
|
+
var t = K(), u = t.firstChild;
|
|
62
|
+
return n(t, l(j, {
|
|
63
63
|
class: "w-3.5 h-3.5 text-muted-foreground flex-shrink-0"
|
|
64
|
-
}),
|
|
65
|
-
|
|
66
|
-
},
|
|
64
|
+
}), u), u.addEventListener("blur", I), u.$$keydown = w, u.$$input = (o) => e.setFilterQuery(o.currentTarget.value), S((o) => {
|
|
65
|
+
i = o, r.filterInputRef && r.filterInputRef(o);
|
|
66
|
+
}, u), n(t, l(k, {
|
|
67
67
|
get when() {
|
|
68
68
|
return e.filterQuery();
|
|
69
69
|
},
|
|
70
70
|
get children() {
|
|
71
|
-
var
|
|
72
|
-
return
|
|
71
|
+
var o = H();
|
|
72
|
+
return o.$$click = h, n(o, l(Y, {
|
|
73
73
|
class: "w-3 h-3"
|
|
74
|
-
})), s(() =>
|
|
74
|
+
})), s(() => f(o, v("flex items-center justify-center w-4 h-4 rounded-sm cursor-pointer", "text-muted-foreground hover:text-foreground", "transition-colors duration-100"))), o;
|
|
75
75
|
}
|
|
76
|
-
}), null), s(() =>
|
|
76
|
+
}), null), s(() => f(u, v("flex-1 min-w-0 bg-transparent text-xs", "outline-none border-0 ring-0 shadow-none appearance-none", "focus:outline-none focus:border-0 focus:ring-0", "placeholder:text-muted-foreground/60"))), s(() => u.value = e.filterQuery()), t;
|
|
77
77
|
}
|
|
78
|
-
})),
|
|
78
|
+
})), n($, l(B, {
|
|
79
79
|
mode: "list",
|
|
80
80
|
get currentMode() {
|
|
81
81
|
return e.viewMode();
|
|
82
82
|
},
|
|
83
83
|
onClick: () => e.setViewMode("list"),
|
|
84
|
-
icon:
|
|
84
|
+
icon: J,
|
|
85
85
|
label: "List view"
|
|
86
|
-
}), null),
|
|
86
|
+
}), null), n($, l(B, {
|
|
87
87
|
mode: "grid",
|
|
88
88
|
get currentMode() {
|
|
89
89
|
return e.viewMode();
|
|
@@ -91,9 +91,17 @@ function le(r) {
|
|
|
91
91
|
onClick: () => e.setViewMode("grid"),
|
|
92
92
|
icon: V,
|
|
93
93
|
label: "Grid view"
|
|
94
|
+
}), null), n(d, l(k, {
|
|
95
|
+
get when() {
|
|
96
|
+
return r.endActions;
|
|
97
|
+
},
|
|
98
|
+
get children() {
|
|
99
|
+
var t = X();
|
|
100
|
+
return n(t, () => r.endActions), t;
|
|
101
|
+
}
|
|
94
102
|
}), null), s((t) => {
|
|
95
|
-
var
|
|
96
|
-
return
|
|
103
|
+
var u = v("flex items-center gap-2 px-2 py-1.5 border-b border-border", "bg-background/50 backdrop-blur-sm", r.class), o = v("md:hidden flex items-center justify-center w-7 h-7 rounded cursor-pointer", "transition-colors duration-100", "hover:bg-muted/70", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring", !e.sidebarCollapsed() && "bg-muted/50"), F = !c(), _ = v("flex items-center justify-center w-7 h-7 rounded cursor-pointer", "transition-colors duration-100", "hover:bg-muted/70", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring", "disabled:opacity-40 disabled:cursor-not-allowed disabled:hover:bg-transparent"), A = v("flex-1 min-w-0 overflow-hidden transition-all duration-200", e.isFilterActive() && "hidden sm:block sm:flex-1"), C = v("flex items-center gap-1 transition-all duration-200 ease-out", e.isFilterActive() ? "flex-1 sm:flex-none sm:w-48" : "w-7");
|
|
104
|
+
return u !== t.e && f(d, t.e = u), o !== t.t && f(x, t.t = o), F !== t.a && (m.disabled = t.a = F), _ !== t.o && f(m, t.o = _), A !== t.i && f(p, t.i = A), C !== t.n && f(y, t.n = C), t;
|
|
97
105
|
}, {
|
|
98
106
|
e: void 0,
|
|
99
107
|
t: void 0,
|
|
@@ -101,26 +109,26 @@ function le(r) {
|
|
|
101
109
|
o: void 0,
|
|
102
110
|
i: void 0,
|
|
103
111
|
n: void 0
|
|
104
|
-
}),
|
|
112
|
+
}), d;
|
|
105
113
|
})();
|
|
106
114
|
}
|
|
107
115
|
function B(r) {
|
|
108
116
|
const e = () => r.currentMode === r.mode;
|
|
109
117
|
return (() => {
|
|
110
|
-
var
|
|
111
|
-
return
|
|
118
|
+
var i = z();
|
|
119
|
+
return i.$$click = () => r.onClick(), n(i, l(r.icon, {
|
|
112
120
|
class: "w-3.5 h-3.5"
|
|
113
121
|
})), s((c) => {
|
|
114
|
-
var
|
|
115
|
-
return
|
|
122
|
+
var b = v("flex items-center justify-center w-6 h-6 rounded cursor-pointer", "transition-all duration-150", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring", e() ? "bg-background shadow-sm text-foreground" : "text-muted-foreground hover:text-foreground"), h = r.label, w = e();
|
|
123
|
+
return b !== c.e && f(i, c.e = b), h !== c.t && g(i, "aria-label", c.t = h), w !== c.a && g(i, "aria-pressed", c.a = w), c;
|
|
116
124
|
}, {
|
|
117
125
|
e: void 0,
|
|
118
126
|
t: void 0,
|
|
119
127
|
a: void 0
|
|
120
|
-
}),
|
|
128
|
+
}), i;
|
|
121
129
|
})();
|
|
122
130
|
}
|
|
123
131
|
Q(["click", "input", "keydown"]);
|
|
124
132
|
export {
|
|
125
|
-
|
|
133
|
+
se as FileBrowserToolbar
|
|
126
134
|
};
|
|
@@ -28,6 +28,8 @@ export interface FileContextMenuProps {
|
|
|
28
28
|
*/
|
|
29
29
|
hideItems?: HideItemsValue;
|
|
30
30
|
}
|
|
31
|
+
export declare function createDefaultContextMenuItems(callbacks?: ContextMenuCallbacks): ContextMenuItem[];
|
|
32
|
+
export declare function dispatchContextMenuAction(item: ContextMenuItem, items: FileItem[], callbacks?: ContextMenuCallbacks): void;
|
|
31
33
|
/**
|
|
32
34
|
* Context menu for file browser items
|
|
33
35
|
*/
|
|
@@ -1,145 +1,161 @@
|
|
|
1
|
-
import { createComponent as
|
|
2
|
-
import { createSignal as H, createEffect as $, onCleanup as
|
|
1
|
+
import { createComponent as u, Portal as D, insert as v, Dynamic as E, effect as h, className as C, setStyleProperty as M, template as c, setAttribute as p, use as L, delegateEvents as P } from "solid-js/web";
|
|
2
|
+
import { createSignal as H, createEffect as $, onCleanup as F, Show as m, For as N } from "solid-js";
|
|
3
3
|
import { cn as I } from "../../utils/cn.js";
|
|
4
|
-
import { deferAfterPaint as
|
|
4
|
+
import { deferAfterPaint as S } from "../../utils/defer.js";
|
|
5
5
|
import { useFileBrowser as V } from "./FileBrowserContext.js";
|
|
6
|
-
var
|
|
7
|
-
const U = (
|
|
8
|
-
var
|
|
9
|
-
return
|
|
10
|
-
})(), X = (
|
|
11
|
-
var
|
|
12
|
-
return
|
|
13
|
-
})(), Y = (
|
|
14
|
-
var
|
|
15
|
-
return
|
|
16
|
-
})(), ee = (
|
|
17
|
-
var
|
|
18
|
-
return
|
|
19
|
-
})(), te = (
|
|
20
|
-
var
|
|
21
|
-
return
|
|
22
|
-
})(), ne = (
|
|
23
|
-
var
|
|
24
|
-
return
|
|
6
|
+
var R = /* @__PURE__ */ c('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><rect width=14 height=14 x=8 y=8 rx=2 ry=2></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2">'), T = /* @__PURE__ */ c('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><rect width=14 height=16 x=5 y=4 rx=2></rect><path d="M9 4.5h6a1 1 0 0 0 1-1V3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v.5a1 1 0 0 0 1 1Z">'), Z = /* @__PURE__ */ c('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><path d="m12 3-1.9 5.8a2 2 0 0 1-1.3 1.3L3 12l5.8 1.9a2 2 0 0 1 1.3 1.3L12 21l1.9-5.8a2 2 0 0 1 1.3-1.3L21 12l-5.8-1.9a2 2 0 0 1-1.3-1.3Z">'), z = /* @__PURE__ */ c('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><path d="M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13c0 1.1.9 2 2 2Z"></path><path d="M8 10v4"></path><path d="M12 10v2"></path><path d="M16 10v6">'), W = /* @__PURE__ */ c('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><path d="M12 3v18"></path><path d="m8 7-4 4 4 4"></path><path d="m16 7 4 4-4 4">'), q = /* @__PURE__ */ c('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><path d="M3 6h18"></path><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"></path><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2">'), K = /* @__PURE__ */ c('<svg xmlns=http://www.w3.org/2000/svg viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round><path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"></path><path d="m15 5 4 4">'), O = /* @__PURE__ */ c("<div role=menu aria-orientation=vertical>"), G = /* @__PURE__ */ c('<span class="text-[10px] text-muted-foreground opacity-60">'), J = /* @__PURE__ */ c('<button type=button role=menuitem><span class="flex-1 text-left">'), Q = /* @__PURE__ */ c('<div class="my-1 h-px bg-border">');
|
|
7
|
+
const U = (n) => (() => {
|
|
8
|
+
var e = R();
|
|
9
|
+
return h(() => p(e, "class", n.class)), e;
|
|
10
|
+
})(), X = (n) => (() => {
|
|
11
|
+
var e = T();
|
|
12
|
+
return h(() => p(e, "class", n.class)), e;
|
|
13
|
+
})(), Y = (n) => (() => {
|
|
14
|
+
var e = Z();
|
|
15
|
+
return h(() => p(e, "class", n.class)), e;
|
|
16
|
+
})(), ee = (n) => (() => {
|
|
17
|
+
var e = z();
|
|
18
|
+
return h(() => p(e, "class", n.class)), e;
|
|
19
|
+
})(), te = (n) => (() => {
|
|
20
|
+
var e = W();
|
|
21
|
+
return h(() => p(e, "class", n.class)), e;
|
|
22
|
+
})(), ne = (n) => (() => {
|
|
23
|
+
var e = q();
|
|
24
|
+
return h(() => p(e, "class", n.class)), e;
|
|
25
|
+
})(), oe = (n) => (() => {
|
|
26
|
+
var e = K();
|
|
27
|
+
return h(() => p(e, "class", n.class)), e;
|
|
25
28
|
})();
|
|
26
|
-
function
|
|
27
|
-
const n =
|
|
28
|
-
|
|
29
|
+
function re(n) {
|
|
30
|
+
const e = !!n?.onAskAgent, a = !!n?.onCopyName;
|
|
31
|
+
return [{
|
|
32
|
+
id: "duplicate",
|
|
33
|
+
label: "Duplicate",
|
|
34
|
+
type: "duplicate",
|
|
35
|
+
icon: U,
|
|
36
|
+
shortcut: "Cmd+D",
|
|
37
|
+
separator: !a && !e
|
|
38
|
+
}, ...a ? [{
|
|
39
|
+
id: "copy-name",
|
|
40
|
+
label: "Copy Name",
|
|
41
|
+
type: "copy-name",
|
|
42
|
+
icon: X,
|
|
43
|
+
separator: !e
|
|
44
|
+
}] : [], ...e ? [{
|
|
45
|
+
id: "ask-agent",
|
|
46
|
+
label: "Ask Agent",
|
|
47
|
+
type: "ask-agent",
|
|
48
|
+
icon: Y,
|
|
49
|
+
separator: !0
|
|
50
|
+
}] : [], {
|
|
51
|
+
id: "copy-to",
|
|
52
|
+
label: "Copy to...",
|
|
53
|
+
type: "copy-to",
|
|
54
|
+
icon: ee
|
|
55
|
+
}, {
|
|
56
|
+
id: "move-to",
|
|
57
|
+
label: "Move to...",
|
|
58
|
+
type: "move-to",
|
|
59
|
+
icon: te,
|
|
60
|
+
separator: !0
|
|
61
|
+
}, {
|
|
62
|
+
id: "rename",
|
|
63
|
+
label: "Rename",
|
|
64
|
+
type: "rename",
|
|
65
|
+
icon: oe,
|
|
66
|
+
shortcut: "Enter"
|
|
67
|
+
}, {
|
|
68
|
+
id: "delete",
|
|
69
|
+
label: "Delete",
|
|
70
|
+
type: "delete",
|
|
71
|
+
icon: ne,
|
|
72
|
+
shortcut: "Del"
|
|
73
|
+
}];
|
|
74
|
+
}
|
|
75
|
+
function ae(n, e, a) {
|
|
76
|
+
switch (n.type) {
|
|
77
|
+
case "duplicate":
|
|
78
|
+
a?.onDuplicate?.(e);
|
|
79
|
+
break;
|
|
80
|
+
case "copy-name":
|
|
81
|
+
a?.onCopyName?.(e);
|
|
82
|
+
break;
|
|
83
|
+
case "ask-agent":
|
|
84
|
+
a?.onAskAgent?.(e);
|
|
85
|
+
break;
|
|
86
|
+
case "copy-to":
|
|
87
|
+
a?.onCopyTo?.(e);
|
|
88
|
+
break;
|
|
89
|
+
case "move-to":
|
|
90
|
+
a?.onMoveTo?.(e);
|
|
91
|
+
break;
|
|
92
|
+
case "delete":
|
|
93
|
+
a?.onDelete?.(e);
|
|
94
|
+
break;
|
|
95
|
+
case "rename":
|
|
96
|
+
e.length === 1 && a?.onRename?.(e[0]);
|
|
97
|
+
break;
|
|
98
|
+
case "custom":
|
|
99
|
+
n.onAction?.(e);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function ue(n) {
|
|
104
|
+
const e = V();
|
|
105
|
+
let a;
|
|
29
106
|
const _ = typeof window > "u" || typeof document > "u", [g, w] = H({
|
|
30
107
|
x: -9999,
|
|
31
108
|
y: -9999
|
|
32
109
|
}), A = () => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}, ...t ? [{
|
|
42
|
-
id: "ask-agent",
|
|
43
|
-
label: "Ask Agent",
|
|
44
|
-
type: "ask-agent",
|
|
45
|
-
icon: X,
|
|
46
|
-
separator: !0
|
|
47
|
-
}] : [], {
|
|
48
|
-
id: "copy-to",
|
|
49
|
-
label: "Copy to...",
|
|
50
|
-
type: "copy-to",
|
|
51
|
-
icon: Y
|
|
52
|
-
}, {
|
|
53
|
-
id: "move-to",
|
|
54
|
-
label: "Move to...",
|
|
55
|
-
type: "move-to",
|
|
56
|
-
icon: ee,
|
|
57
|
-
separator: !0
|
|
58
|
-
}, {
|
|
59
|
-
id: "rename",
|
|
60
|
-
label: "Rename",
|
|
61
|
-
type: "rename",
|
|
62
|
-
icon: ne,
|
|
63
|
-
shortcut: "Enter"
|
|
64
|
-
}, {
|
|
65
|
-
id: "delete",
|
|
66
|
-
label: "Delete",
|
|
67
|
-
type: "delete",
|
|
68
|
-
icon: te,
|
|
69
|
-
shortcut: "Del"
|
|
70
|
-
}];
|
|
71
|
-
}, j = () => {
|
|
72
|
-
if (s.overrideItems)
|
|
73
|
-
return s.overrideItems;
|
|
74
|
-
const t = () => {
|
|
75
|
-
const e = s.hideItems;
|
|
76
|
-
if (!e) return [];
|
|
77
|
-
if (typeof e == "function") {
|
|
78
|
-
const r = n.contextMenu()?.items ?? [];
|
|
79
|
-
return e(r);
|
|
110
|
+
if (n.overrideItems)
|
|
111
|
+
return n.overrideItems;
|
|
112
|
+
const r = () => {
|
|
113
|
+
const t = n.hideItems;
|
|
114
|
+
if (!t) return [];
|
|
115
|
+
if (typeof t == "function") {
|
|
116
|
+
const s = e.contextMenu()?.items ?? [];
|
|
117
|
+
return t(s);
|
|
80
118
|
}
|
|
81
|
-
return
|
|
119
|
+
return t;
|
|
82
120
|
};
|
|
83
|
-
let o =
|
|
84
|
-
const
|
|
85
|
-
return
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
case "duplicate":
|
|
92
|
-
r?.onDuplicate?.(e);
|
|
93
|
-
break;
|
|
94
|
-
case "ask-agent":
|
|
95
|
-
r?.onAskAgent?.(e);
|
|
96
|
-
break;
|
|
97
|
-
case "copy-to":
|
|
98
|
-
r?.onCopyTo?.(e);
|
|
99
|
-
break;
|
|
100
|
-
case "move-to":
|
|
101
|
-
r?.onMoveTo?.(e);
|
|
102
|
-
break;
|
|
103
|
-
case "delete":
|
|
104
|
-
r?.onDelete?.(e);
|
|
105
|
-
break;
|
|
106
|
-
case "rename":
|
|
107
|
-
e.length === 1 && r?.onRename?.(e[0]);
|
|
108
|
-
break;
|
|
109
|
-
case "custom":
|
|
110
|
-
i?.(e);
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
121
|
+
let o = re(n.callbacks);
|
|
122
|
+
const l = r();
|
|
123
|
+
return l.length > 0 && (o = o.filter((t) => !l.includes(t.type))), n.customItems?.length && (o = [...o, ...n.customItems]), o;
|
|
124
|
+
}, j = (r, o) => {
|
|
125
|
+
e.hideContextMenu();
|
|
126
|
+
const l = [...o], t = n.callbacks;
|
|
127
|
+
S(() => {
|
|
128
|
+
ae(r, l, t);
|
|
113
129
|
});
|
|
114
|
-
}, f = (
|
|
115
|
-
|
|
116
|
-
}, x = (
|
|
117
|
-
|
|
130
|
+
}, f = (r) => {
|
|
131
|
+
a && !a.contains(r.target) && e.hideContextMenu();
|
|
132
|
+
}, x = (r) => {
|
|
133
|
+
r.key === "Escape" && e.hideContextMenu();
|
|
118
134
|
};
|
|
119
135
|
$(() => {
|
|
120
|
-
|
|
136
|
+
e.contextMenu() && (document.addEventListener("click", f), document.addEventListener("keydown", x), F(() => {
|
|
121
137
|
document.removeEventListener("click", f), document.removeEventListener("keydown", x);
|
|
122
138
|
}));
|
|
123
139
|
});
|
|
124
|
-
const
|
|
125
|
-
const
|
|
126
|
-
if (!
|
|
127
|
-
x:
|
|
128
|
-
y:
|
|
140
|
+
const B = () => {
|
|
141
|
+
const r = e.contextMenu();
|
|
142
|
+
if (!r || !a) return {
|
|
143
|
+
x: r?.x ?? 0,
|
|
144
|
+
y: r?.y ?? 0
|
|
129
145
|
};
|
|
130
|
-
const o =
|
|
131
|
-
let
|
|
146
|
+
const o = a.getBoundingClientRect(), l = window.innerWidth, t = window.innerHeight;
|
|
147
|
+
let s = r.x, d = r.y;
|
|
132
148
|
return o.width === 0 || o.height === 0 ? {
|
|
133
|
-
x:
|
|
134
|
-
y:
|
|
135
|
-
} : (
|
|
136
|
-
x: Math.max(8,
|
|
137
|
-
y: Math.max(8,
|
|
149
|
+
x: s,
|
|
150
|
+
y: d
|
|
151
|
+
} : (s + o.width > l && (s = l - o.width - 8), d + o.height > t && (d = t - o.height - 8), {
|
|
152
|
+
x: Math.max(8, s),
|
|
153
|
+
y: Math.max(8, d)
|
|
138
154
|
});
|
|
139
155
|
};
|
|
140
156
|
$(() => {
|
|
141
|
-
const
|
|
142
|
-
if (!
|
|
157
|
+
const r = e.contextMenu();
|
|
158
|
+
if (!r) {
|
|
143
159
|
w({
|
|
144
160
|
x: -9999,
|
|
145
161
|
y: -9999
|
|
@@ -147,79 +163,81 @@ function ce(s) {
|
|
|
147
163
|
return;
|
|
148
164
|
}
|
|
149
165
|
w({
|
|
150
|
-
x:
|
|
151
|
-
y:
|
|
166
|
+
x: r.x,
|
|
167
|
+
y: r.y
|
|
152
168
|
}), requestAnimationFrame(() => {
|
|
153
|
-
const o =
|
|
169
|
+
const o = B();
|
|
154
170
|
w(o);
|
|
155
171
|
});
|
|
156
172
|
});
|
|
157
|
-
const
|
|
158
|
-
var o = O(),
|
|
159
|
-
return typeof
|
|
173
|
+
const y = (r) => (() => {
|
|
174
|
+
var o = O(), l = a;
|
|
175
|
+
return typeof l == "function" ? L(l, o) : a = o, v(o, u(N, {
|
|
160
176
|
get each() {
|
|
161
|
-
return
|
|
177
|
+
return A();
|
|
162
178
|
},
|
|
163
|
-
children: (
|
|
164
|
-
var
|
|
165
|
-
return
|
|
179
|
+
children: (t) => [(() => {
|
|
180
|
+
var s = J(), d = s.firstChild;
|
|
181
|
+
return s.$$click = () => j(t, r.menu().items), v(s, u(m, {
|
|
166
182
|
get when() {
|
|
167
|
-
return
|
|
183
|
+
return t.icon;
|
|
168
184
|
},
|
|
169
|
-
children: (
|
|
185
|
+
children: (i) => u(E, {
|
|
170
186
|
get component() {
|
|
171
|
-
return
|
|
187
|
+
return i();
|
|
172
188
|
},
|
|
173
189
|
class: "w-3.5 h-3.5 opacity-60"
|
|
174
190
|
})
|
|
175
|
-
}),
|
|
191
|
+
}), d), v(d, () => t.label), v(s, u(m, {
|
|
176
192
|
get when() {
|
|
177
|
-
return
|
|
193
|
+
return t.shortcut;
|
|
178
194
|
},
|
|
179
195
|
get children() {
|
|
180
|
-
var
|
|
181
|
-
return
|
|
196
|
+
var i = G();
|
|
197
|
+
return v(i, () => t.shortcut), i;
|
|
182
198
|
}
|
|
183
|
-
}), null),
|
|
184
|
-
var
|
|
185
|
-
return
|
|
199
|
+
}), null), h((i) => {
|
|
200
|
+
var k = t.disabled || t.type === "rename" && r.menu().items.length > 1, b = I("w-full flex items-center gap-2 px-3 py-1.5 text-xs cursor-pointer", "transition-colors duration-75", "hover:bg-accent hover:text-accent-foreground", "focus:outline-none focus-visible:bg-accent focus-visible:text-accent-foreground", "disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent", t.type === "delete" && "text-error hover:bg-error/10 hover:text-error");
|
|
201
|
+
return k !== i.e && (s.disabled = i.e = k), b !== i.t && C(s, i.t = b), i;
|
|
186
202
|
}, {
|
|
187
203
|
e: void 0,
|
|
188
204
|
t: void 0
|
|
189
|
-
}),
|
|
190
|
-
})(),
|
|
205
|
+
}), s;
|
|
206
|
+
})(), u(m, {
|
|
191
207
|
get when() {
|
|
192
|
-
return
|
|
208
|
+
return t.separator;
|
|
193
209
|
},
|
|
194
210
|
get children() {
|
|
195
211
|
return Q();
|
|
196
212
|
}
|
|
197
213
|
})]
|
|
198
|
-
})),
|
|
199
|
-
var
|
|
200
|
-
return
|
|
214
|
+
})), h((t) => {
|
|
215
|
+
var s = I("fixed z-50 min-w-[180px] py-1", "bg-popover border border-border rounded-lg shadow-lg", "animate-in fade-in zoom-in-95 duration-100"), d = `${g().x}px`, i = `${g().y}px`;
|
|
216
|
+
return s !== t.e && C(o, t.e = s), d !== t.t && M(o, "left", t.t = d), i !== t.a && M(o, "top", t.a = i), t;
|
|
201
217
|
}, {
|
|
202
218
|
e: void 0,
|
|
203
219
|
t: void 0,
|
|
204
220
|
a: void 0
|
|
205
221
|
}), o;
|
|
206
222
|
})();
|
|
207
|
-
return
|
|
223
|
+
return u(m, {
|
|
208
224
|
get when() {
|
|
209
|
-
return
|
|
225
|
+
return e.contextMenu();
|
|
210
226
|
},
|
|
211
|
-
children: (
|
|
212
|
-
menu:
|
|
213
|
-
}) :
|
|
227
|
+
children: (r) => _ ? u(y, {
|
|
228
|
+
menu: r
|
|
229
|
+
}) : u(D, {
|
|
214
230
|
get children() {
|
|
215
|
-
return
|
|
216
|
-
menu:
|
|
231
|
+
return u(y, {
|
|
232
|
+
menu: r
|
|
217
233
|
});
|
|
218
234
|
}
|
|
219
235
|
})
|
|
220
236
|
});
|
|
221
237
|
}
|
|
222
|
-
|
|
238
|
+
P(["click"]);
|
|
223
239
|
export {
|
|
224
|
-
|
|
240
|
+
ue as FileContextMenu,
|
|
241
|
+
re as createDefaultContextMenuItems,
|
|
242
|
+
ae as dispatchContextMenuAction
|
|
225
243
|
};
|
|
@@ -38,7 +38,7 @@ export interface FileListColumnRatios {
|
|
|
38
38
|
/**
|
|
39
39
|
* Built-in context menu action types
|
|
40
40
|
*/
|
|
41
|
-
export type ContextMenuActionType = 'duplicate' | 'ask-agent' | 'copy-to' | 'move-to' | 'delete' | 'rename' | 'custom';
|
|
41
|
+
export type ContextMenuActionType = 'duplicate' | 'copy-name' | 'ask-agent' | 'copy-to' | 'move-to' | 'delete' | 'rename' | 'custom';
|
|
42
42
|
/**
|
|
43
43
|
* Context menu item definition
|
|
44
44
|
*/
|
|
@@ -78,6 +78,7 @@ export interface ContextMenuEvent {
|
|
|
78
78
|
*/
|
|
79
79
|
export interface ContextMenuCallbacks {
|
|
80
80
|
onDuplicate?: (items: FileItem[]) => void;
|
|
81
|
+
onCopyName?: (items: FileItem[]) => void;
|
|
81
82
|
onAskAgent?: (items: FileItem[]) => void;
|
|
82
83
|
onCopyTo?: (items: FileItem[]) => void;
|
|
83
84
|
onMoveTo?: (items: FileItem[]) => void;
|