@floegence/floe-webapp-core 0.86.50 → 0.86.52
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/ui/DirectoryPicker.js +25 -29
- package/dist/components/ui/FileOpenPicker.js +106 -98
- package/dist/components/ui/FileSavePicker.js +74 -66
- package/dist/components/ui/index.d.ts +2 -0
- package/dist/components/ui/picker/DirectoryFavorites.d.ts +29 -0
- package/dist/components/ui/picker/DirectoryFavorites.js +163 -0
- package/dist/components/ui/picker/PickerBase.d.ts +16 -5
- package/dist/components/ui/picker/PickerBase.js +370 -225
- package/dist/components/ui/picker/PickerNavigation.d.ts +7 -0
- package/dist/components/ui/picker/PickerNavigation.js +73 -66
- package/dist/full.js +465 -463
- package/dist/styles.css +1 -1
- package/dist/ui.js +128 -126
- package/package.json +1 -1
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { createComponent as
|
|
2
|
-
import { createMemo as
|
|
3
|
-
import { cn as
|
|
1
|
+
import { createComponent as n, mergeProps as s, insert as i, effect as g, setAttribute as u, template as m } from "solid-js/web";
|
|
2
|
+
import { createMemo as d } from "solid-js";
|
|
3
|
+
import { cn as f } from "../../utils/cn.js";
|
|
4
4
|
import { Button as o } from "./Button.js";
|
|
5
|
-
import { Dialog as
|
|
6
|
-
import { usePickerNavigation as
|
|
5
|
+
import { Dialog as h } from "./Dialog.js";
|
|
6
|
+
import { usePickerNavigation as P, PickerPanel as v, pickerCopy as b } from "./picker/PickerBase.js";
|
|
7
7
|
import { parsePickerPath as w } from "./picker/PickerNavigation.js";
|
|
8
|
-
var
|
|
9
|
-
function
|
|
10
|
-
const
|
|
11
|
-
if (e.disabled ||
|
|
12
|
-
const
|
|
13
|
-
e.onSelect(
|
|
8
|
+
var x = /* @__PURE__ */ m('<div class="flex w-full items-center gap-2"><span class="min-w-0 flex-1 truncate text-[11px] text-muted-foreground">');
|
|
9
|
+
function $(e) {
|
|
10
|
+
const a = d(() => [...new Set((e.suggestedPaths ?? []).map((r) => w(r)).filter(Boolean))]), t = P(e, () => e.open, void 0, void 0, () => a().length ? "suggestions" : "browse"), c = () => {
|
|
11
|
+
if (e.disabled || t.view() !== "browse" || !t.valid()) return;
|
|
12
|
+
const r = t.currentPath();
|
|
13
|
+
e.onSelect(r), e.onOpenChange(!1);
|
|
14
14
|
};
|
|
15
|
-
return
|
|
15
|
+
return n(h, {
|
|
16
16
|
get open() {
|
|
17
17
|
return e.open;
|
|
18
18
|
},
|
|
@@ -23,50 +23,46 @@ function T(e) {
|
|
|
23
23
|
return e.title ?? "Select Directory";
|
|
24
24
|
},
|
|
25
25
|
get class() {
|
|
26
|
-
return
|
|
26
|
+
return f("max-w-lg", e.class);
|
|
27
27
|
},
|
|
28
28
|
get footer() {
|
|
29
29
|
return (() => {
|
|
30
|
-
var
|
|
31
|
-
return
|
|
30
|
+
var r = x(), l = r.firstChild;
|
|
31
|
+
return i(l, () => t.currentPath()), i(r, n(o, {
|
|
32
32
|
variant: "ghost",
|
|
33
33
|
size: "sm",
|
|
34
34
|
onClick: () => e.onOpenChange(!1),
|
|
35
35
|
get children() {
|
|
36
|
-
return e.cancelText ??
|
|
36
|
+
return e.cancelText ?? b(e).cancel;
|
|
37
37
|
}
|
|
38
|
-
}), null),
|
|
38
|
+
}), null), i(r, n(o, {
|
|
39
39
|
variant: "primary",
|
|
40
40
|
size: "sm",
|
|
41
|
-
onClick:
|
|
41
|
+
onClick: c,
|
|
42
42
|
get disabled() {
|
|
43
|
-
return e.disabled ||
|
|
43
|
+
return e.disabled || t.view() !== "browse" || !t.valid();
|
|
44
44
|
},
|
|
45
45
|
get children() {
|
|
46
46
|
return e.confirmText ?? "Select";
|
|
47
47
|
}
|
|
48
|
-
}), null),
|
|
48
|
+
}), null), g(() => u(l, "title", t.currentPath())), r;
|
|
49
49
|
})();
|
|
50
50
|
},
|
|
51
51
|
get children() {
|
|
52
|
-
return
|
|
53
|
-
source:
|
|
52
|
+
return n(v, s(e, {
|
|
53
|
+
source: t,
|
|
54
54
|
suggestions: {
|
|
55
55
|
get paths() {
|
|
56
|
-
return
|
|
56
|
+
return a();
|
|
57
57
|
},
|
|
58
58
|
get label() {
|
|
59
59
|
return e.suggestedPathsLabel ?? "Suggested directories";
|
|
60
|
-
}
|
|
61
|
-
get visible() {
|
|
62
|
-
return i();
|
|
63
|
-
},
|
|
64
|
-
onVisibilityChange: s
|
|
60
|
+
}
|
|
65
61
|
}
|
|
66
62
|
}));
|
|
67
63
|
}
|
|
68
64
|
});
|
|
69
65
|
}
|
|
70
66
|
export {
|
|
71
|
-
|
|
67
|
+
$ as DirectoryPicker
|
|
72
68
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createComponent as
|
|
1
|
+
import { createComponent as a, insert as c, mergeProps as z, spread as K, use as L, effect as j, setAttribute as M, className as V, memo as H, template as x, delegateEvents as R } from "solid-js/web";
|
|
2
2
|
import { createSignal as U, mergeProps as Y, createMemo as q, Show as w, For as G } from "solid-js";
|
|
3
3
|
import { cn as N } from "../../utils/cn.js";
|
|
4
4
|
import { deferNonBlocking as J } from "../../utils/defer.js";
|
|
@@ -6,53 +6,53 @@ import { Check as Q } from "../icons/index.js";
|
|
|
6
6
|
import { FileItemIcon as W } from "../file-browser/FileIcons.js";
|
|
7
7
|
import { Button as D } from "./Button.js";
|
|
8
8
|
import { Dialog as X } from "./Dialog.js";
|
|
9
|
-
import { usePickerNavigation as Z, PickerPanel as ee, normalizePath as k, pickerCopy as
|
|
9
|
+
import { usePickerNavigation as Z, PickerPanel as ee, normalizePath as k, pickerCopy as b } from "./picker/PickerBase.js";
|
|
10
10
|
import { pickerParentPath as te } from "./picker/PickerNavigation.js";
|
|
11
|
-
var ne = /* @__PURE__ */
|
|
12
|
-
function
|
|
13
|
-
const
|
|
11
|
+
var ne = /* @__PURE__ */ x('<div class="flex min-h-[140px] overflow-hidden rounded border border-border"><div>'), ie = /* @__PURE__ */ x('<div class="flex flex-col gap-2 -mt-1">'), le = /* @__PURE__ */ x('<div class="flex items-center w-full gap-2"><span class="flex-1 text-[11px] text-muted-foreground truncate">'), re = /* @__PURE__ */ x('<div class="flex h-full items-center justify-center px-4 text-center text-xs text-muted-foreground">'), oe = /* @__PURE__ */ x('<span class="ml-auto flex h-5 min-w-5 items-center justify-center rounded-full bg-primary px-1 text-[10px] text-primary-foreground">'), ae = /* @__PURE__ */ x("<button type=button role=option><span class=truncate>");
|
|
12
|
+
function ce(e, s) {
|
|
13
|
+
const u = y(s), f = /* @__PURE__ */ new Set(), d = [];
|
|
14
14
|
for (const g of e ?? []) {
|
|
15
|
-
const
|
|
16
|
-
if (!(
|
|
15
|
+
const i = k(g);
|
|
16
|
+
if (!(i === "/" || f.has(i)) && (f.add(i), d.push(i), d.length >= u))
|
|
17
17
|
break;
|
|
18
18
|
}
|
|
19
|
-
return
|
|
19
|
+
return d;
|
|
20
20
|
}
|
|
21
|
-
function
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
24
|
-
if (
|
|
25
|
-
const g = e.indexOf(
|
|
26
|
-
return g >= 0 ? e.filter((
|
|
21
|
+
function se(e, s, u, f) {
|
|
22
|
+
const d = k(s);
|
|
23
|
+
if (d === "/") return [...e];
|
|
24
|
+
if (u === "single") return [d];
|
|
25
|
+
const g = e.indexOf(d);
|
|
26
|
+
return g >= 0 ? e.filter((i, h) => h !== g) : e.length >= y(f) ? [...e] : [...e, d];
|
|
27
27
|
}
|
|
28
28
|
function y(e) {
|
|
29
29
|
return e == null || !Number.isFinite(e) ? Number.POSITIVE_INFINITY : Math.max(1, Math.floor(e));
|
|
30
30
|
}
|
|
31
31
|
function ke(e) {
|
|
32
|
-
const
|
|
32
|
+
const s = () => e.selectionMode ?? "single", [u, f] = U([]), d = () => {
|
|
33
33
|
if (e.initialPath) return e.initialPath;
|
|
34
34
|
const t = e.initialSelectedPaths?.[0];
|
|
35
35
|
return t ? te(t) : void 0;
|
|
36
36
|
}, g = Y(e, {
|
|
37
37
|
get initialPath() {
|
|
38
|
-
return
|
|
38
|
+
return d();
|
|
39
39
|
},
|
|
40
40
|
get scopeKey() {
|
|
41
41
|
return e.scopeKey;
|
|
42
42
|
}
|
|
43
|
-
}),
|
|
44
|
-
f(
|
|
45
|
-
}), h = q(() =>
|
|
46
|
-
f((
|
|
47
|
-
}, P = (t =
|
|
48
|
-
if (t.length === 0 || !
|
|
49
|
-
const
|
|
50
|
-
e.onOpenChange(!1), J(() =>
|
|
51
|
-
}, E = (t,
|
|
52
|
-
let
|
|
53
|
-
t.key === "ArrowDown" && (
|
|
54
|
-
},
|
|
55
|
-
return
|
|
43
|
+
}), i = Z(g, () => e.open, void 0, () => {
|
|
44
|
+
f(ce(e.initialSelectedPaths, s() === "single" ? 1 : e.maxSelections));
|
|
45
|
+
}), h = q(() => i.entries().filter((t) => t.type === "file" && (!e.fileFilter || e.fileFilter(t)))), T = (t) => u().indexOf(k(t)), A = () => s() === "multiple" && u().length >= y(e.maxSelections), B = (t) => {
|
|
46
|
+
f((o) => se(o, t.path, s(), e.maxSelections));
|
|
47
|
+
}, P = (t = u()) => {
|
|
48
|
+
if (e.disabled || t.length === 0 || i.view() !== "browse" || !i.valid()) return;
|
|
49
|
+
const o = e.onSelect;
|
|
50
|
+
e.onOpenChange(!1), J(() => o([...t]));
|
|
51
|
+
}, E = (t, o) => {
|
|
52
|
+
let l;
|
|
53
|
+
t.key === "ArrowDown" && (l = Math.min(o + 1, h().length - 1)), t.key === "ArrowUp" && (l = Math.max(o - 1, 0)), t.key === "Home" && (l = 0), t.key === "End" && (l = h().length - 1), !(l == null || l < 0) && (t.preventDefault(), $[l]?.focus());
|
|
54
|
+
}, $ = [];
|
|
55
|
+
return a(X, {
|
|
56
56
|
get open() {
|
|
57
57
|
return e.open;
|
|
58
58
|
},
|
|
@@ -67,23 +67,23 @@ function ke(e) {
|
|
|
67
67
|
},
|
|
68
68
|
get footer() {
|
|
69
69
|
return (() => {
|
|
70
|
-
var t =
|
|
71
|
-
return
|
|
72
|
-
var
|
|
73
|
-
return () =>
|
|
74
|
-
})()),
|
|
70
|
+
var t = le(), o = t.firstChild;
|
|
71
|
+
return c(o, (() => {
|
|
72
|
+
var l = H(() => u().length === 0);
|
|
73
|
+
return () => l() ? b(e).noFilesSelected : b(e).selectedCount(u().length);
|
|
74
|
+
})()), c(t, a(D, {
|
|
75
75
|
variant: "ghost",
|
|
76
76
|
size: "sm",
|
|
77
77
|
onClick: () => e.onOpenChange(!1),
|
|
78
78
|
get children() {
|
|
79
|
-
return e.cancelText ??
|
|
79
|
+
return e.cancelText ?? b(e).cancel;
|
|
80
80
|
}
|
|
81
|
-
}), null),
|
|
81
|
+
}), null), c(t, a(D, {
|
|
82
82
|
variant: "primary",
|
|
83
83
|
size: "sm",
|
|
84
84
|
onClick: () => P(),
|
|
85
85
|
get disabled() {
|
|
86
|
-
return
|
|
86
|
+
return u().length === 0 || i.view() !== "browse" || !i.valid();
|
|
87
87
|
},
|
|
88
88
|
get children() {
|
|
89
89
|
return e.confirmText ?? "Select";
|
|
@@ -92,82 +92,90 @@ function ke(e) {
|
|
|
92
92
|
})();
|
|
93
93
|
},
|
|
94
94
|
get children() {
|
|
95
|
-
var t =
|
|
96
|
-
return
|
|
97
|
-
source:
|
|
98
|
-
})),
|
|
99
|
-
class: "max-h-[200px] min-h-[140px] min-w-0 flex-1 overflow-y-auto",
|
|
100
|
-
role: "listbox",
|
|
101
|
-
get "aria-multiselectable"() {
|
|
102
|
-
return o() === "multiple" ? "true" : void 0;
|
|
103
|
-
}
|
|
104
|
-
}), !1, !0), m(i, u(w, {
|
|
95
|
+
var t = ie();
|
|
96
|
+
return c(t, a(ee, z(e, {
|
|
97
|
+
source: i
|
|
98
|
+
})), null), c(t, a(w, {
|
|
105
99
|
get when() {
|
|
106
|
-
return
|
|
107
|
-
},
|
|
108
|
-
get fallback() {
|
|
109
|
-
return (() => {
|
|
110
|
-
var d = le();
|
|
111
|
-
return m(d, () => e.emptyText ?? v(e).emptyFiles), d;
|
|
112
|
-
})();
|
|
100
|
+
return i.view() === "browse";
|
|
113
101
|
},
|
|
114
102
|
get children() {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
103
|
+
var o = ne(), l = o.firstChild;
|
|
104
|
+
return K(l, z(() => e.scrollViewportProps, {
|
|
105
|
+
class: "max-h-[200px] min-h-[140px] min-w-0 flex-1 overflow-y-auto",
|
|
106
|
+
role: "listbox",
|
|
107
|
+
get "aria-multiselectable"() {
|
|
108
|
+
return s() === "multiple" ? "true" : void 0;
|
|
109
|
+
}
|
|
110
|
+
}), !1, !0), c(l, a(w, {
|
|
111
|
+
get when() {
|
|
112
|
+
return h().length > 0;
|
|
118
113
|
},
|
|
119
|
-
|
|
120
|
-
const x = () => T(d.path), F = () => A() && x() < 0;
|
|
114
|
+
get fallback() {
|
|
121
115
|
return (() => {
|
|
122
|
-
var
|
|
123
|
-
return
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
116
|
+
var m = re();
|
|
117
|
+
return c(m, () => e.emptyText ?? b(e).emptyFiles), m;
|
|
118
|
+
})();
|
|
119
|
+
},
|
|
120
|
+
get children() {
|
|
121
|
+
return a(G, {
|
|
122
|
+
get each() {
|
|
123
|
+
return h();
|
|
124
|
+
},
|
|
125
|
+
children: (m, S) => {
|
|
126
|
+
const v = () => T(m.path), F = () => A() && v() < 0;
|
|
127
|
+
return (() => {
|
|
128
|
+
var r = ae(), _ = r.firstChild;
|
|
129
|
+
return r.$$keydown = (n) => E(n, S()), r.$$dblclick = () => {
|
|
130
|
+
s() === "single" && P([k(m.path)]);
|
|
131
|
+
}, r.$$click = () => B(m), L((n) => {
|
|
132
|
+
$[S()] = n;
|
|
133
|
+
}, r), c(r, a(W, {
|
|
134
|
+
item: m,
|
|
135
|
+
size: 16,
|
|
136
|
+
class: "w-4 h-4 flex-shrink-0"
|
|
137
|
+
}), _), c(_, () => m.name), c(r, a(w, {
|
|
138
138
|
get when() {
|
|
139
|
-
return
|
|
140
|
-
},
|
|
141
|
-
get fallback() {
|
|
142
|
-
return u(Q, {
|
|
143
|
-
class: "h-3 w-3"
|
|
144
|
-
});
|
|
139
|
+
return v() >= 0;
|
|
145
140
|
},
|
|
146
141
|
get children() {
|
|
147
|
-
|
|
142
|
+
var n = oe();
|
|
143
|
+
return c(n, a(w, {
|
|
144
|
+
get when() {
|
|
145
|
+
return s() === "multiple";
|
|
146
|
+
},
|
|
147
|
+
get fallback() {
|
|
148
|
+
return a(Q, {
|
|
149
|
+
class: "h-3 w-3"
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
get children() {
|
|
153
|
+
return v() + 1;
|
|
154
|
+
}
|
|
155
|
+
})), n;
|
|
148
156
|
}
|
|
149
|
-
})), n
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
}
|
|
160
|
-
})
|
|
157
|
+
}), null), j((n) => {
|
|
158
|
+
var C = v() >= 0, I = F(), O = F() ? b(e).selectionLimit : m.name, p = N("flex min-h-9 w-full cursor-pointer items-center gap-2 px-2 py-1.5 text-left text-xs", "transition-colors duration-100 hover:bg-accent/60", "focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring", "disabled:cursor-not-allowed disabled:opacity-45", v() >= 0 && "bg-accent text-accent-foreground font-medium");
|
|
159
|
+
return C !== n.e && M(r, "aria-selected", n.e = C), I !== n.t && (r.disabled = n.t = I), O !== n.a && M(r, "title", n.a = O), p !== n.o && V(r, n.o = p), n;
|
|
160
|
+
}, {
|
|
161
|
+
e: void 0,
|
|
162
|
+
t: void 0,
|
|
163
|
+
a: void 0,
|
|
164
|
+
o: void 0
|
|
165
|
+
}), r;
|
|
166
|
+
})();
|
|
167
|
+
}
|
|
168
|
+
});
|
|
161
169
|
}
|
|
162
|
-
});
|
|
170
|
+
})), o;
|
|
163
171
|
}
|
|
164
|
-
})), t;
|
|
172
|
+
}), null), t;
|
|
165
173
|
}
|
|
166
174
|
});
|
|
167
175
|
}
|
|
168
176
|
R(["click", "dblclick", "keydown"]);
|
|
169
177
|
export {
|
|
170
178
|
ke as FileOpenPicker,
|
|
171
|
-
|
|
172
|
-
|
|
179
|
+
ce as normalizeFileOpenSelection,
|
|
180
|
+
se as updateFileOpenSelection
|
|
173
181
|
};
|
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import { createComponent as a, insert as n, mergeProps as _, spread as z, effect as
|
|
2
|
-
import { createSignal as
|
|
3
|
-
import { cn as
|
|
1
|
+
import { createComponent as a, insert as n, mergeProps as _, spread as z, effect as b, className as B, setAttribute as E, template as u, delegateEvents as D } from "solid-js/web";
|
|
2
|
+
import { createSignal as F, createMemo as k, createEffect as I, on as O, Show as x, For as K } from "solid-js";
|
|
3
|
+
import { cn as C } from "../../utils/cn.js";
|
|
4
4
|
import { Dialog as T } from "./Dialog.js";
|
|
5
|
-
import { Button as
|
|
5
|
+
import { Button as N } from "./Button.js";
|
|
6
6
|
import { Input as M } from "./Input.js";
|
|
7
7
|
import { FileItemIcon as j } from "../file-browser/FileIcons.js";
|
|
8
8
|
import { deferNonBlocking as q } from "../../utils/defer.js";
|
|
9
9
|
import { usePickerNavigation as A, PickerPanel as R, pickerCopy as g } from "./picker/PickerBase.js";
|
|
10
|
-
var V = /* @__PURE__ */
|
|
11
|
-
function
|
|
12
|
-
const [
|
|
13
|
-
|
|
14
|
-
}), h = k(() =>
|
|
15
|
-
I(O(
|
|
16
|
-
|
|
10
|
+
var V = /* @__PURE__ */ u('<div class="flex min-h-[100px] overflow-hidden rounded border border-border"><div>'), G = /* @__PURE__ */ u('<div class="flex flex-col gap-2 -mt-1">'), H = /* @__PURE__ */ u('<div class="flex flex-col w-full gap-2"><div class="flex items-center gap-1.5"><label class="text-xs text-muted-foreground flex-shrink-0"></label><div class=flex-1></div></div><div class="flex items-center gap-2"><span class="flex-1 text-[11px] text-muted-foreground truncate">'), J = /* @__PURE__ */ u('<div class="flex items-center justify-center h-full text-xs text-muted-foreground">'), L = /* @__PURE__ */ u('<span class="ml-auto text-[10px] text-muted-foreground/60 flex-shrink-0">'), Q = /* @__PURE__ */ u("<button type=button><span class=truncate>");
|
|
11
|
+
function ie(e) {
|
|
12
|
+
const [s, v] = F(e.initialFileName ?? ""), [p, m] = F(""), o = A(e, () => e.open, void 0, () => {
|
|
13
|
+
v(e.initialFileName ?? ""), m("");
|
|
14
|
+
}), h = k(() => o.entries().filter((t) => t.type === "file"));
|
|
15
|
+
I(O(s, () => {
|
|
16
|
+
m("");
|
|
17
17
|
}));
|
|
18
18
|
const S = (t) => {
|
|
19
|
-
|
|
20
|
-
},
|
|
21
|
-
if (!
|
|
22
|
-
const t =
|
|
19
|
+
v(t.name), m("");
|
|
20
|
+
}, $ = () => {
|
|
21
|
+
if (e.disabled || o.view() !== "browse" || !o.valid()) return;
|
|
22
|
+
const t = s().trim();
|
|
23
23
|
if (!t) {
|
|
24
|
-
|
|
24
|
+
m(g(e).fileNameRequired);
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
27
|
if (e.validateFileName) {
|
|
28
28
|
const r = e.validateFileName(t);
|
|
29
29
|
if (r) {
|
|
30
|
-
|
|
30
|
+
m(r);
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
const l =
|
|
35
|
-
e.onOpenChange(!1), q(() =>
|
|
34
|
+
const l = o.currentPath(), c = e.onSave;
|
|
35
|
+
e.onOpenChange(!1), q(() => c(l, t));
|
|
36
36
|
}, P = () => {
|
|
37
37
|
e.onOpenChange(!1);
|
|
38
38
|
}, y = (t) => {
|
|
39
|
-
t.key === "Enter" && (t.preventDefault(),
|
|
40
|
-
},
|
|
41
|
-
const t =
|
|
39
|
+
t.key === "Enter" && (t.preventDefault(), $());
|
|
40
|
+
}, w = k(() => {
|
|
41
|
+
const t = o.currentPath(), l = s().trim();
|
|
42
42
|
return l ? t === "/" ? `/${l}` : `${t}/${l}` : t;
|
|
43
43
|
});
|
|
44
44
|
return a(T, {
|
|
@@ -52,89 +52,97 @@ function le(e) {
|
|
|
52
52
|
return e.title ?? "Save File";
|
|
53
53
|
},
|
|
54
54
|
get class() {
|
|
55
|
-
return
|
|
55
|
+
return C("max-w-2xl", e.class);
|
|
56
56
|
},
|
|
57
57
|
get footer() {
|
|
58
58
|
return (() => {
|
|
59
|
-
var t =
|
|
60
|
-
return n(
|
|
59
|
+
var t = H(), l = t.firstChild, c = l.firstChild, r = c.nextSibling, i = l.nextSibling, f = i.firstChild;
|
|
60
|
+
return n(c, () => g(e).fileName), n(r, a(M, {
|
|
61
61
|
size: "sm",
|
|
62
62
|
get value() {
|
|
63
|
-
return
|
|
63
|
+
return s();
|
|
64
64
|
},
|
|
65
|
-
onInput: (d) =>
|
|
65
|
+
onInput: (d) => v(d.currentTarget.value),
|
|
66
66
|
onKeyDown: y,
|
|
67
67
|
placeholder: "filename.ext",
|
|
68
68
|
get error() {
|
|
69
69
|
return p();
|
|
70
70
|
}
|
|
71
|
-
})), n(f,
|
|
71
|
+
})), n(f, w), n(i, a(N, {
|
|
72
72
|
variant: "ghost",
|
|
73
73
|
size: "sm",
|
|
74
74
|
onClick: P,
|
|
75
75
|
get children() {
|
|
76
76
|
return e.cancelText ?? g(e).cancel;
|
|
77
77
|
}
|
|
78
|
-
}), null), n(i, a(
|
|
78
|
+
}), null), n(i, a(N, {
|
|
79
79
|
variant: "primary",
|
|
80
80
|
size: "sm",
|
|
81
|
-
onClick:
|
|
81
|
+
onClick: $,
|
|
82
82
|
get disabled() {
|
|
83
|
-
return !
|
|
83
|
+
return !s().trim() || o.view() !== "browse" || !o.valid();
|
|
84
84
|
},
|
|
85
85
|
get children() {
|
|
86
86
|
return e.confirmText ?? "Save";
|
|
87
87
|
}
|
|
88
|
-
}), null),
|
|
88
|
+
}), null), b(() => E(f, "title", w())), t;
|
|
89
89
|
})();
|
|
90
90
|
},
|
|
91
91
|
get children() {
|
|
92
|
-
var t =
|
|
92
|
+
var t = G();
|
|
93
93
|
return n(t, a(R, _(e, {
|
|
94
|
-
source:
|
|
95
|
-
})),
|
|
96
|
-
class: "max-h-[160px] w-full min-w-0 overflow-y-auto"
|
|
97
|
-
}), !1, !0), n(o, a(w, {
|
|
94
|
+
source: o
|
|
95
|
+
})), null), n(t, a(x, {
|
|
98
96
|
get when() {
|
|
99
|
-
return
|
|
100
|
-
},
|
|
101
|
-
get fallback() {
|
|
102
|
-
return (() => {
|
|
103
|
-
var r = H();
|
|
104
|
-
return n(r, () => g(e).emptyFiles), r;
|
|
105
|
-
})();
|
|
97
|
+
return o.view() === "browse";
|
|
106
98
|
},
|
|
107
99
|
get children() {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
100
|
+
var l = V(), c = l.firstChild;
|
|
101
|
+
return z(c, _(() => e.scrollViewportProps, {
|
|
102
|
+
class: "max-h-[160px] w-full min-w-0 overflow-y-auto"
|
|
103
|
+
}), !1, !0), n(c, a(x, {
|
|
104
|
+
get when() {
|
|
105
|
+
return h().length > 0;
|
|
106
|
+
},
|
|
107
|
+
get fallback() {
|
|
108
|
+
return (() => {
|
|
109
|
+
var r = J();
|
|
110
|
+
return n(r, () => g(e).emptyFiles), r;
|
|
111
|
+
})();
|
|
111
112
|
},
|
|
112
|
-
children
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
size: 16,
|
|
117
|
-
class: "w-4 h-4 flex-shrink-0"
|
|
118
|
-
}), f), n(f, () => r.name), n(i, a(w, {
|
|
119
|
-
get when() {
|
|
120
|
-
return r.size != null;
|
|
113
|
+
get children() {
|
|
114
|
+
return a(K, {
|
|
115
|
+
get each() {
|
|
116
|
+
return h();
|
|
121
117
|
},
|
|
122
|
-
|
|
123
|
-
var
|
|
124
|
-
return
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
118
|
+
children: (r) => (() => {
|
|
119
|
+
var i = Q(), f = i.firstChild;
|
|
120
|
+
return i.$$click = () => S(r), n(i, a(j, {
|
|
121
|
+
item: r,
|
|
122
|
+
size: 16,
|
|
123
|
+
class: "w-4 h-4 flex-shrink-0"
|
|
124
|
+
}), f), n(f, () => r.name), n(i, a(x, {
|
|
125
|
+
get when() {
|
|
126
|
+
return r.size != null;
|
|
127
|
+
},
|
|
128
|
+
get children() {
|
|
129
|
+
var d = L();
|
|
130
|
+
return n(d, () => U(r.size)), d;
|
|
131
|
+
}
|
|
132
|
+
}), null), b(() => B(i, C("flex items-center gap-1.5 w-full text-left text-xs py-1.5 px-2 cursor-pointer", "transition-colors duration-100", "hover:bg-accent/60", "focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring", s() === r.name && "bg-accent text-accent-foreground font-medium"))), i;
|
|
133
|
+
})()
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
})), l;
|
|
129
137
|
}
|
|
130
|
-
})), t;
|
|
138
|
+
}), null), t;
|
|
131
139
|
}
|
|
132
140
|
});
|
|
133
141
|
}
|
|
134
|
-
function
|
|
142
|
+
function U(e) {
|
|
135
143
|
return e < 1024 ? `${e} B` : e < 1024 * 1024 ? `${(e / 1024).toFixed(1)} KB` : `${(e / (1024 * 1024)).toFixed(1)} MB`;
|
|
136
144
|
}
|
|
137
145
|
D(["click"]);
|
|
138
146
|
export {
|
|
139
|
-
|
|
147
|
+
ie as FileSavePicker
|
|
140
148
|
};
|
|
@@ -47,3 +47,5 @@ export { SurfaceAnchoredLayer, type SurfaceAnchoredLayerProps } from './SurfaceA
|
|
|
47
47
|
export { PersistentHorizontalScrollbar, type PersistentHorizontalScrollbarProps } from './PersistentHorizontalScrollbar';
|
|
48
48
|
export { SettingsLayout, SettingsNavigation, SettingsSection, SettingsList, SettingRow, type SettingsNavigationItem, type SettingsNavigationGroup, type SettingsNavigationProps, type SettingsSectionProps, type SettingRowProps, } from './Settings';
|
|
49
49
|
export { KeyedFor, type KeyedForProps } from './KeyedFor';
|
|
50
|
+
export { DirectoryFavoriteButton } from './picker/DirectoryFavorites';
|
|
51
|
+
export type { DirectoryFavorites } from './picker/DirectoryFavorites';
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type JSX } from 'solid-js';
|
|
2
|
+
import type { PickerCopy } from './PickerNavigation';
|
|
3
|
+
/** Controlled navigation metadata. The host owns authentication, persistence and refresh. */
|
|
4
|
+
export interface DirectoryFavorites {
|
|
5
|
+
paths: readonly string[];
|
|
6
|
+
loading?: boolean;
|
|
7
|
+
error?: string;
|
|
8
|
+
editable?: boolean;
|
|
9
|
+
pendingPaths?: readonly string[];
|
|
10
|
+
onRefresh?: () => void | Promise<void>;
|
|
11
|
+
onSetFavorite?: (path: string, favorite: boolean) => Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
export declare function DirectoryFavoriteButton(props: {
|
|
14
|
+
path: string;
|
|
15
|
+
favorites: DirectoryFavorites;
|
|
16
|
+
copy: PickerCopy;
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
onError?: (message: string) => void;
|
|
19
|
+
}): JSX.Element;
|
|
20
|
+
/** A navigation button and favorite action are siblings; the menu captures its target on open. */
|
|
21
|
+
export declare function PickerDirectoryRow(props: {
|
|
22
|
+
path: string;
|
|
23
|
+
favorites?: DirectoryFavorites;
|
|
24
|
+
copy: PickerCopy;
|
|
25
|
+
disabled?: boolean;
|
|
26
|
+
scopeKey?: string;
|
|
27
|
+
children: JSX.Element;
|
|
28
|
+
onError: (message: string) => void;
|
|
29
|
+
}): JSX.Element;
|