@floegence/floe-webapp-core 0.15.0 → 0.15.2

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.
@@ -28,6 +28,12 @@ export interface BasePickerProps {
28
28
  * When provided, a "New Folder" button is shown.
29
29
  */
30
30
  onCreateFolder?: (parentPath: string, name: string) => Promise<void>;
31
+ /**
32
+ * Callback when user expands a directory.
33
+ * Use this to dynamically load children for the expanded directory.
34
+ * The path parameter is the internal tree path (not the display path).
35
+ */
36
+ onExpand?: (path: string) => void;
31
37
  /** Filter which directories are selectable (return false to grey-out) */
32
38
  filter?: (item: FileItem) => boolean;
33
39
  /** Label for the home/root directory (default: 'Root') */
@@ -57,6 +63,11 @@ export interface UsePickerTreeOptions {
57
63
  filter?: (item: FileItem) => boolean;
58
64
  /** Additional reset logic when the dialog opens */
59
65
  onReset?: (initialPath: string) => void;
66
+ /**
67
+ * Callback when user expands a directory.
68
+ * Use this to dynamically load children for the expanded directory.
69
+ */
70
+ onExpand?: (path: string) => void;
60
71
  /** Label for the home/root directory in tree and breadcrumb (default: 'Root'). Supports accessor for reactivity. */
61
72
  homeLabel?: string | Accessor<string | undefined>;
62
73
  /**
@@ -149,6 +149,13 @@ export interface PersistApi {
149
149
  debouncedSave: <T>(key: string, value: T, delayMs?: number) => void;
150
150
  remove: (key: string) => void;
151
151
  clearAll: () => void;
152
+ /**
153
+ * Flush pending debounced saves immediately.
154
+ *
155
+ * Note: This is primarily used to ensure the latest state is persisted on page refresh/close,
156
+ * while keeping debounced persistence in the hot interaction path.
157
+ */
158
+ flush?: () => void;
152
159
  }
153
160
  export interface FloeConfigValue {
154
161
  config: FloeConfig;
package/dist/index29.js CHANGED
@@ -1,4 +1,4 @@
1
- import { createComponent as n, insert as l, effect as h, setAttribute as g, template as i } from "solid-js/web";
1
+ import { createComponent as r, insert as l, effect as h, setAttribute as g, template as i } from "solid-js/web";
2
2
  import { Show as d } from "solid-js";
3
3
  import { cn as m } from "./index111.js";
4
4
  import { Dialog as s } from "./index22.js";
@@ -6,22 +6,24 @@ import { Button as o } from "./index20.js";
6
6
  import { deferNonBlocking as f } from "./index112.js";
7
7
  import { usePickerTree as P, PathInputBar as x, PickerBreadcrumb as C, PickerFolderTree as S, NewFolderSection as p } from "./index31.js";
8
8
  var b = /* @__PURE__ */ i('<div class="flex flex-col gap-2 -mt-1">'), y = /* @__PURE__ */ i('<div class="flex items-center w-full gap-2"><span class="flex-1 text-[11px] text-muted-foreground truncate">');
9
- function T(t) {
9
+ function E(t) {
10
10
  const e = P({
11
11
  initialPath: t.initialPath,
12
12
  open: () => t.open,
13
13
  files: () => t.files,
14
14
  // eslint-disable-next-line solid/reactivity -- filter is a static callback
15
- filter: t.filter ? (r) => t.filter(r) : void 0,
15
+ filter: t.filter ? (n) => t.filter(n) : void 0,
16
+ // eslint-disable-next-line solid/reactivity -- onExpand is a static callback
17
+ onExpand: t.onExpand,
16
18
  homeLabel: () => t.homeLabel,
17
19
  homePath: () => t.homePath
18
20
  }), c = () => {
19
- const r = e.selectedPath(), a = t.onSelect;
20
- t.onOpenChange(!1), f(() => a(r));
21
+ const n = e.selectedPath(), a = t.onSelect;
22
+ t.onOpenChange(!1), f(() => a(n));
21
23
  }, u = () => {
22
24
  t.onOpenChange(!1);
23
25
  };
24
- return n(s, {
26
+ return r(s, {
25
27
  get open() {
26
28
  return t.open;
27
29
  },
@@ -36,27 +38,27 @@ function T(t) {
36
38
  },
37
39
  get footer() {
38
40
  return (() => {
39
- var r = y(), a = r.firstChild;
40
- return l(a, () => e.toDisplayPath(e.selectedPath())), l(r, n(o, {
41
+ var n = y(), a = n.firstChild;
42
+ return l(a, () => e.toDisplayPath(e.selectedPath())), l(n, r(o, {
41
43
  variant: "ghost",
42
44
  size: "sm",
43
45
  onClick: u,
44
46
  get children() {
45
47
  return t.cancelText ?? "Cancel";
46
48
  }
47
- }), null), l(r, n(o, {
49
+ }), null), l(n, r(o, {
48
50
  variant: "primary",
49
51
  size: "sm",
50
52
  onClick: c,
51
53
  get children() {
52
54
  return t.confirmText ?? "Select";
53
55
  }
54
- }), null), h(() => g(a, "title", e.toDisplayPath(e.selectedPath()))), r;
56
+ }), null), h(() => g(a, "title", e.toDisplayPath(e.selectedPath()))), n;
55
57
  })();
56
58
  },
57
59
  get children() {
58
- var r = b();
59
- return l(r, n(x, {
60
+ var n = b();
61
+ return l(n, r(x, {
60
62
  get value() {
61
63
  return e.pathInput;
62
64
  },
@@ -72,14 +74,14 @@ function T(t) {
72
74
  get onKeyDown() {
73
75
  return e.handlePathInputKeyDown;
74
76
  }
75
- }), null), l(r, n(C, {
77
+ }), null), l(n, r(C, {
76
78
  get segments() {
77
79
  return e.breadcrumbSegments;
78
80
  },
79
81
  get onClick() {
80
82
  return e.handleBreadcrumbClick;
81
83
  }
82
- }), null), l(r, n(S, {
84
+ }), null), l(n, r(S, {
83
85
  get rootFolders() {
84
86
  return e.rootFolders;
85
87
  },
@@ -108,12 +110,12 @@ function T(t) {
108
110
  "max-height": "280px",
109
111
  "min-height": "160px"
110
112
  }
111
- }), null), l(r, n(d, {
113
+ }), null), l(n, r(d, {
112
114
  get when() {
113
115
  return t.onCreateFolder;
114
116
  },
115
117
  get children() {
116
- return n(p, {
118
+ return r(p, {
117
119
  get parentPath() {
118
120
  return e.selectedPath;
119
121
  },
@@ -125,10 +127,10 @@ function T(t) {
125
127
  }
126
128
  });
127
129
  }
128
- }), null), r;
130
+ }), null), n;
129
131
  }
130
132
  });
131
133
  }
132
134
  export {
133
- T as DirectoryPicker
135
+ E as DirectoryPicker
134
136
  };
package/dist/index30.js CHANGED
@@ -1,5 +1,5 @@
1
- import { delegateEvents as I, createComponent as i, insert as a, effect as F, className as N, setAttribute as D, template as h } from "solid-js/web";
2
- import { createSignal as $, createMemo as p, createEffect as B, on as E, Show as g, For as z } from "solid-js";
1
+ import { delegateEvents as I, createComponent as i, insert as a, effect as F, className as N, setAttribute as E, template as h } from "solid-js/web";
2
+ import { createSignal as $, createMemo as p, createEffect as D, on as B, Show as g, For as z } from "solid-js";
3
3
  import { cn as C } from "./index111.js";
4
4
  import { Dialog as T } from "./index22.js";
5
5
  import { Button as w } from "./index20.js";
@@ -15,6 +15,8 @@ function ae(e) {
15
15
  files: () => e.files,
16
16
  // eslint-disable-next-line solid/reactivity -- filter is a static callback
17
17
  filter: e.filter ? (t) => e.filter(t) : void 0,
18
+ // eslint-disable-next-line solid/reactivity -- onExpand is a static callback
19
+ onExpand: e.onExpand,
18
20
  homeLabel: () => e.homeLabel,
19
21
  homePath: () => e.homePath,
20
22
  onReset: () => {
@@ -27,7 +29,7 @@ function ae(e) {
27
29
  const n = r.folderIndex().get(t);
28
30
  return n?.children ? n.children.filter((o) => o.type === "file") : [];
29
31
  });
30
- B(E(u, () => {
32
+ D(B(u, () => {
31
33
  s("");
32
34
  }));
33
35
  const k = (t) => {
@@ -99,7 +101,7 @@ function ae(e) {
99
101
  get children() {
100
102
  return e.confirmText ?? "Save";
101
103
  }
102
- }), null), F(() => D(c, "title", P())), t;
104
+ }), null), F(() => E(c, "title", P())), t;
103
105
  })();
104
106
  },
105
107
  get children() {
package/dist/index31.js CHANGED
@@ -1,116 +1,117 @@
1
- import { delegateEvents as Z, insert as h, createComponent as s, effect as T, className as C, style as ee, memo as B, template as w, setAttribute as te, setStyleProperty as ne } from "solid-js/web";
2
- import { createSignal as S, createMemo as E, createEffect as A, on as G, For as z, Show as I } from "solid-js";
3
- import { cn as _ } from "./index111.js";
1
+ import { delegateEvents as Z, insert as d, createComponent as s, effect as E, className as _, style as ee, memo as B, template as y, setAttribute as te, setStyleProperty as ne } from "solid-js/web";
2
+ import { createSignal as C, createMemo as D, createEffect as A, on as G, For as z, Show as I } from "solid-js";
3
+ import { cn as p } from "./index111.js";
4
4
  import { deferAfterPaint as re } from "./index112.js";
5
5
  import { Button as N } from "./index20.js";
6
6
  import { Input as H } from "./index21.js";
7
- import { ChevronRight as M, Check as le, X as oe, Plus as ae } from "./index40.js";
7
+ import { ChevronRight as M, Check as oe, X as le, Plus as ae } from "./index40.js";
8
8
  import { FolderOpenIcon as W, FolderIcon as ie } from "./index54.js";
9
- var O = /* @__PURE__ */ w('<div class="flex items-center gap-1.5"><div class=flex-1>'), ce = /* @__PURE__ */ w('<p class="text-[11px] text-muted-foreground -mt-1">Creating in: '), se = /* @__PURE__ */ w("<button type=button><span>New Folder"), ue = /* @__PURE__ */ w('<nav class="flex items-center gap-0.5 min-w-0 overflow-x-auto py-0.5"aria-label="Selected path">'), V = /* @__PURE__ */ w("<button type=button>"), de = /* @__PURE__ */ w('<div class="flex items-center justify-center py-6 text-xs text-muted-foreground">'), he = /* @__PURE__ */ w("<div><button type=button><span>"), fe = /* @__PURE__ */ w("<div class=overflow-hidden>"), ge = /* @__PURE__ */ w('<div class="flex flex-col"><div><button type=button><span class="flex-shrink-0 w-4 h-4"></span><span class=truncate>'), me = /* @__PURE__ */ w('<span class="flex-shrink-0 w-4 h-4">');
10
- function k(e) {
11
- const o = (e ?? "").trim();
12
- if (o === "" || o === "/") return "/";
13
- const n = o.replace(/\/+$/, "");
9
+ var O = /* @__PURE__ */ y('<div class="flex items-center gap-1.5"><div class=flex-1>'), ce = /* @__PURE__ */ y('<p class="text-[11px] text-muted-foreground -mt-1">Creating in: '), se = /* @__PURE__ */ y("<button type=button><span>New Folder"), ue = /* @__PURE__ */ y('<nav class="flex items-center gap-0.5 min-w-0 overflow-x-auto py-0.5"aria-label="Selected path">'), V = /* @__PURE__ */ y("<button type=button>"), de = /* @__PURE__ */ y('<div class="flex items-center justify-center py-6 text-xs text-muted-foreground">'), he = /* @__PURE__ */ y("<div><button type=button><span>"), fe = /* @__PURE__ */ y("<div class=overflow-hidden>"), ge = /* @__PURE__ */ y('<div class="flex flex-col"><div><button type=button><span class="flex-shrink-0 w-4 h-4"></span><span class=truncate>'), me = /* @__PURE__ */ y('<span class="flex-shrink-0 w-4 h-4">');
10
+ function S(e) {
11
+ const l = (e ?? "").trim();
12
+ if (l === "" || l === "/") return "/";
13
+ const n = l.replace(/\/+$/, "");
14
14
  return n.startsWith("/") ? n : "/" + n;
15
15
  }
16
16
  function j(e) {
17
- const o = e.split("/").filter(Boolean), n = [];
17
+ const l = e.split("/").filter(Boolean), n = [];
18
18
  let c = "";
19
- for (let r = 0; r < o.length - 1; r++)
20
- c += "/" + o[r], n.push(c);
19
+ for (let r = 0; r < l.length - 1; r++)
20
+ c += "/" + l[r], n.push(c);
21
21
  return n;
22
22
  }
23
23
  function ve(e) {
24
- return E(() => {
25
- const o = /* @__PURE__ */ new Map(), n = (c) => {
24
+ return D(() => {
25
+ const l = /* @__PURE__ */ new Map(), n = (c) => {
26
26
  for (const r of c)
27
- r.type === "folder" && (o.set(k(r.path), r), r.children?.length && n(r.children));
27
+ r.type === "folder" && (l.set(S(r.path), r), r.children?.length && n(r.children));
28
28
  };
29
- return n(e()), o;
29
+ return n(e()), l;
30
30
  });
31
31
  }
32
32
  function _e(e) {
33
- const o = e.initialPath ?? "/", n = () => (typeof e.homeLabel == "function" ? e.homeLabel() : e.homeLabel) ?? "Root", c = () => {
33
+ const l = e.initialPath ?? "/", n = () => (typeof e.homeLabel == "function" ? e.homeLabel() : e.homeLabel) ?? "Root", c = () => {
34
34
  const t = typeof e.homePath == "function" ? e.homePath() : e.homePath;
35
- return t ? k(t) : void 0;
35
+ return t ? S(t) : void 0;
36
36
  }, r = (t) => {
37
37
  const i = c();
38
38
  if (!i) return t;
39
- const d = k(t);
40
- return d === "/" ? i : i === "/" ? d : i + d;
39
+ const h = S(t);
40
+ return h === "/" ? i : i === "/" ? h : i + h;
41
41
  }, u = (t) => {
42
42
  const i = c();
43
- if (!i) return k(t);
44
- const d = k(t);
45
- return d === i ? "/" : i !== "/" && d.startsWith(i + "/") ? d.slice(i.length) || "/" : k(t);
46
- }, [b, m] = S(o), [f, v] = S(/* @__PURE__ */ new Set(["/"])), [P, l] = S(r(o)), [x, a] = S(""), g = ve(e.files), y = E(() => e.files().filter((t) => t.type === "folder"));
43
+ if (!i) return S(t);
44
+ const h = S(t);
45
+ return h === i ? "/" : i !== "/" && h.startsWith(i + "/") ? h.slice(i.length) || "/" : S(t);
46
+ }, [x, m] = C(l), [f, v] = C(/* @__PURE__ */ new Set(["/"])), [w, o] = C(r(l)), [b, a] = C(""), g = ve(e.files), $ = D(() => e.files().filter((t) => t.type === "folder"));
47
47
  A(G(e.open, (t) => {
48
48
  if (t) {
49
49
  const i = e.initialPath ?? "/";
50
- m(i), l(r(i)), a("");
51
- const d = j(i);
52
- v(/* @__PURE__ */ new Set(["/", ...d])), e.onReset?.(i);
50
+ m(i), o(r(i)), a("");
51
+ const h = j(i);
52
+ v(/* @__PURE__ */ new Set(["/", ...h])), e.onReset?.(i);
53
53
  }
54
- })), A(G(b, (t) => {
55
- l(r(t)), a("");
54
+ })), A(G(x, (t) => {
55
+ o(r(t)), a("");
56
56
  }));
57
- const $ = (t) => {
58
- const i = k(t);
57
+ const k = (t) => {
58
+ const i = S(t);
59
59
  return i === "/" || g().has(i);
60
60
  }, F = (t) => e.filter ? e.filter(t) : !0, L = (t) => {
61
61
  const i = j(t);
62
- v((d) => {
63
- const p = new Set(d);
64
- for (const D of i) p.add(D);
65
- return p.add(t), p;
62
+ v((h) => {
63
+ const P = new Set(h);
64
+ for (const T of i) P.add(T);
65
+ return P.add(t), P;
66
66
  });
67
67
  }, q = (t) => {
68
- v((i) => {
69
- const d = new Set(i);
70
- return d.has(t) ? d.delete(t) : d.add(t), d;
71
- });
68
+ const i = f().has(t);
69
+ v((h) => {
70
+ const P = new Set(h);
71
+ return P.has(t) ? P.delete(t) : P.add(t), P;
72
+ }), i || e.onExpand?.(t);
72
73
  }, J = (t) => {
73
74
  F(t) && (m(t.path), v((i) => {
74
- const d = new Set(i);
75
- return d.add(t.path), d;
75
+ const h = new Set(i);
76
+ return h.add(t.path), h;
76
77
  }));
77
78
  }, Q = () => {
78
79
  m("/");
79
80
  }, R = () => {
80
- const t = u(P().trim());
81
- $(t) ? (m(t), a(""), L(t)) : a("Path not found");
81
+ const t = u(w().trim());
82
+ k(t) ? (m(t), a(""), L(t)) : a("Path not found");
82
83
  }, U = (t) => {
83
84
  t.key === "Enter" && (t.preventDefault(), R());
84
- }, Y = E(() => {
85
- const t = b(), i = n();
85
+ }, Y = D(() => {
86
+ const t = x(), i = n();
86
87
  if (t === "/" || t === "") return [{
87
88
  name: i,
88
89
  path: "/"
89
90
  }];
90
- const d = t.split("/").filter(Boolean), p = [{
91
+ const h = t.split("/").filter(Boolean), P = [{
91
92
  name: i,
92
93
  path: "/"
93
94
  }];
94
- let D = "";
95
- for (const K of d)
96
- D += "/" + K, p.push({
95
+ let T = "";
96
+ for (const K of h)
97
+ T += "/" + K, P.push({
97
98
  name: K,
98
- path: D
99
+ path: T
99
100
  });
100
- return p;
101
+ return P;
101
102
  });
102
103
  return {
103
- selectedPath: b,
104
+ selectedPath: x,
104
105
  setSelectedPath: m,
105
106
  expandedPaths: f,
106
107
  toggleExpand: q,
107
- pathInput: P,
108
- setPathInput: l,
109
- pathInputError: x,
108
+ pathInput: w,
109
+ setPathInput: o,
110
+ pathInputError: b,
110
111
  setPathInputError: a,
111
112
  folderIndex: g,
112
- rootFolders: y,
113
- isValidPath: $,
113
+ rootFolders: $,
114
+ isValidPath: k,
114
115
  isSelectable: F,
115
116
  handleSelectFolder: J,
116
117
  handleSelectRoot: Q,
@@ -126,55 +127,55 @@ function _e(e) {
126
127
  };
127
128
  }
128
129
  function pe(e) {
129
- const [o, n] = S(!1), [c, r] = S(""), [u, b] = S(!1), m = () => {
130
+ const [l, n] = C(!1), [c, r] = C(""), [u, x] = C(!1), m = () => {
130
131
  n(!0), r("");
131
132
  }, f = () => {
132
133
  n(!1), r("");
133
134
  }, v = () => {
134
- const l = c().trim();
135
- if (!l || u()) return;
136
- b(!0);
137
- const x = e.parentPath(), a = l, g = e.onCreateFolder;
135
+ const o = c().trim();
136
+ if (!o || u()) return;
137
+ x(!0);
138
+ const b = e.parentPath(), a = o, g = e.onCreateFolder;
138
139
  re(() => {
139
- g(x, a).then(() => {
140
+ g(b, a).then(() => {
140
141
  n(!1), r("");
141
- }).catch((y) => {
142
- console.error("Failed to create folder:", y);
142
+ }).catch(($) => {
143
+ console.error("Failed to create folder:", $);
143
144
  }).finally(() => {
144
- b(!1);
145
+ x(!1);
145
146
  });
146
147
  });
147
- }, P = (l) => {
148
- l.key === "Enter" ? (l.preventDefault(), v()) : l.key === "Escape" && (l.preventDefault(), f());
148
+ }, w = (o) => {
149
+ o.key === "Enter" ? (o.preventDefault(), v()) : o.key === "Escape" && (o.preventDefault(), f());
149
150
  };
150
151
  return s(I, {
151
152
  get when() {
152
- return o();
153
+ return l();
153
154
  },
154
155
  get fallback() {
155
156
  return (() => {
156
- var l = se(), x = l.firstChild;
157
- return l.$$click = m, h(l, s(ae, {
157
+ var o = se(), b = o.firstChild;
158
+ return o.$$click = m, d(o, s(ae, {
158
159
  class: "w-3.5 h-3.5"
159
- }), x), T(() => C(l, _("flex items-center gap-1 text-xs text-muted-foreground cursor-pointer", "hover:text-foreground transition-colors duration-100", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded px-1 py-0.5"))), l;
160
+ }), b), E(() => _(o, p("flex items-center gap-1 text-xs text-muted-foreground cursor-pointer", "hover:text-foreground transition-colors duration-100", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring rounded px-1 py-0.5"))), o;
160
161
  })();
161
162
  },
162
163
  get children() {
163
164
  return [(() => {
164
- var l = O(), x = l.firstChild;
165
- return h(x, s(H, {
165
+ var o = O(), b = o.firstChild;
166
+ return d(b, s(H, {
166
167
  size: "sm",
167
168
  get value() {
168
169
  return c();
169
170
  },
170
171
  onInput: (a) => r(a.currentTarget.value),
171
- onKeyDown: P,
172
+ onKeyDown: w,
172
173
  placeholder: "Folder name",
173
174
  get disabled() {
174
175
  return u();
175
176
  },
176
177
  autofocus: !0
177
- })), h(l, s(N, {
178
+ })), d(o, s(N, {
178
179
  variant: "primary",
179
180
  size: "sm",
180
181
  onClick: v,
@@ -185,11 +186,11 @@ function pe(e) {
185
186
  return !c().trim();
186
187
  },
187
188
  get children() {
188
- return s(le, {
189
+ return s(oe, {
189
190
  class: "w-3.5 h-3.5"
190
191
  });
191
192
  }
192
- }), null), h(l, s(N, {
193
+ }), null), d(o, s(N, {
193
194
  variant: "ghost",
194
195
  size: "sm",
195
196
  class: "bg-transparent text-muted-foreground hover:bg-red-500 hover:text-white",
@@ -198,25 +199,25 @@ function pe(e) {
198
199
  return u();
199
200
  },
200
201
  get children() {
201
- return s(oe, {
202
+ return s(le, {
202
203
  class: "w-3.5 h-3.5"
203
204
  });
204
205
  }
205
- }), null), l;
206
+ }), null), o;
206
207
  })(), (() => {
207
- var l = ce();
208
- return l.firstChild, h(l, (() => {
209
- var x = B(() => !!e.toDisplayPath);
210
- return () => x() ? e.toDisplayPath(e.parentPath()) : e.parentPath();
211
- })(), null), l;
208
+ var o = ce();
209
+ return o.firstChild, d(o, (() => {
210
+ var b = B(() => !!e.toDisplayPath);
211
+ return () => b() ? e.toDisplayPath(e.parentPath()) : e.parentPath();
212
+ })(), null), o;
212
213
  })()];
213
214
  }
214
215
  });
215
216
  }
216
217
  function Ie(e) {
217
218
  return (() => {
218
- var o = O(), n = o.firstChild;
219
- return h(n, s(H, {
219
+ var l = O(), n = l.firstChild;
220
+ return d(n, s(H, {
220
221
  size: "sm",
221
222
  get value() {
222
223
  return e.value();
@@ -231,20 +232,20 @@ function Ie(e) {
231
232
  get error() {
232
233
  return e.error();
233
234
  }
234
- })), h(o, s(N, {
235
+ })), d(l, s(N, {
235
236
  variant: "outline",
236
237
  size: "sm",
237
238
  get onClick() {
238
239
  return e.onGo;
239
240
  },
240
241
  children: "Go"
241
- }), null), o;
242
+ }), null), l;
242
243
  })();
243
244
  }
244
245
  function Fe(e) {
245
246
  return (() => {
246
- var o = ue();
247
- return h(o, s(z, {
247
+ var l = ue();
248
+ return d(l, s(z, {
248
249
  get each() {
249
250
  return e.segments();
250
251
  },
@@ -259,18 +260,18 @@ function Fe(e) {
259
260
  }
260
261
  }), (() => {
261
262
  var r = V();
262
- return r.$$click = () => e.onClick(n.path), h(r, () => n.name), T(() => C(r, _("text-xs px-1 py-0.5 rounded cursor-pointer flex-shrink-0", "transition-colors duration-100", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring", c() === e.segments().length - 1 ? "font-medium text-foreground" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"))), r;
263
+ return r.$$click = () => e.onClick(n.path), d(r, () => n.name), E(() => _(r, p("text-xs px-1 py-0.5 rounded cursor-pointer flex-shrink-0", "transition-colors duration-100", "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring", c() === e.segments().length - 1 ? "font-medium text-foreground" : "text-muted-foreground hover:text-foreground hover:bg-muted/50"))), r;
263
264
  })()]
264
- })), o;
265
+ })), l;
265
266
  })();
266
267
  }
267
- function Te(e) {
268
- const o = () => (typeof e.homeLabel == "function" ? e.homeLabel() : e.homeLabel) ?? "Root";
268
+ function Ee(e) {
269
+ const l = () => (typeof e.homeLabel == "function" ? e.homeLabel() : e.homeLabel) ?? "Root";
269
270
  return (() => {
270
271
  var n = he(), c = n.firstChild, r = c.firstChild;
271
- return c.$$click = () => e.onSelectRoot(), h(c, s(W, {
272
+ return c.$$click = () => e.onSelectRoot(), d(c, s(W, {
272
273
  class: "w-4 h-4 flex-shrink-0"
273
- }), r), h(r, o), h(n, s(z, {
274
+ }), r), d(r, l), d(n, s(z, {
274
275
  get each() {
275
276
  return e.rootFolders();
276
277
  },
@@ -293,17 +294,17 @@ function Te(e) {
293
294
  return e.isSelectable;
294
295
  }
295
296
  })
296
- }), null), h(n, s(I, {
297
+ }), null), d(n, s(I, {
297
298
  get when() {
298
299
  return e.rootFolders().length === 0;
299
300
  },
300
301
  get children() {
301
302
  var u = de();
302
- return h(u, () => e.emptyText ?? "No directories available"), u;
303
+ return d(u, () => e.emptyText ?? "No directories available"), u;
303
304
  }
304
- }), null), T((u) => {
305
- var b = _("border border-border rounded overflow-y-auto", e.class), m = e.style, f = _("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", e.selectedPath() === "/" && "bg-accent text-accent-foreground font-medium");
306
- return b !== u.e && C(n, u.e = b), u.t = ee(n, m, u.t), f !== u.a && C(c, u.a = f), u;
305
+ }), null), E((u) => {
306
+ var x = p("border border-border rounded overflow-y-auto", e.class), m = e.style, f = p("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", e.selectedPath() === "/" && "bg-accent text-accent-foreground font-medium");
307
+ return x !== u.e && _(n, u.e = x), u.t = ee(n, m, u.t), f !== u.a && _(c, u.a = f), u;
307
308
  }, {
308
309
  e: void 0,
309
310
  t: void 0,
@@ -312,14 +313,14 @@ function Te(e) {
312
313
  })();
313
314
  }
314
315
  function X(e) {
315
- const o = () => e.expandedPaths().has(e.item.path), n = () => e.selectedPath() === e.item.path, c = () => e.isSelectable(e.item), r = E(() => e.item.children?.filter((f) => f.type === "folder") ?? []), u = () => r().length > 0, b = (f) => {
316
+ const l = () => e.expandedPaths().has(e.item.path), n = () => e.selectedPath() === e.item.path, c = () => e.isSelectable(e.item), r = D(() => e.item.children?.filter((f) => f.type === "folder") ?? []), u = () => r().length > 0, x = (f) => {
316
317
  f.stopPropagation(), e.onToggle(e.item.path);
317
318
  }, m = () => {
318
319
  e.onSelect(e.item);
319
320
  };
320
321
  return (() => {
321
- var f = ge(), v = f.firstChild, P = v.firstChild, l = P.firstChild, x = l.nextSibling;
322
- return h(v, s(I, {
322
+ var f = ge(), v = f.firstChild, w = v.firstChild, o = w.firstChild, b = o.nextSibling;
323
+ return d(v, s(I, {
323
324
  get when() {
324
325
  return u();
325
326
  },
@@ -328,19 +329,19 @@ function X(e) {
328
329
  },
329
330
  get children() {
330
331
  var a = V();
331
- return a.$$click = b, h(a, s(M, {
332
+ return a.$$click = x, d(a, s(M, {
332
333
  class: "w-3 h-3 opacity-60"
333
- })), T((g) => {
334
- var y = _("flex-shrink-0 w-4 h-4 flex items-center justify-center cursor-pointer", "transition-transform duration-150", o() && "rotate-90", "focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring"), $ = o() ? "Collapse folder" : "Expand folder";
335
- return y !== g.e && C(a, g.e = y), $ !== g.t && te(a, "aria-label", g.t = $), g;
334
+ })), E((g) => {
335
+ var $ = p("flex-shrink-0 w-4 h-4 flex items-center justify-center cursor-pointer", "transition-transform duration-150", l() && "rotate-90", "focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring"), k = l() ? "Collapse folder" : "Expand folder";
336
+ return $ !== g.e && _(a, g.e = $), k !== g.t && te(a, "aria-label", g.t = k), g;
336
337
  }, {
337
338
  e: void 0,
338
339
  t: void 0
339
340
  }), a;
340
341
  }
341
- }), P), P.$$click = m, h(l, s(I, {
342
+ }), w), w.$$click = m, d(o, s(I, {
342
343
  get when() {
343
- return B(() => !!u())() && o();
344
+ return B(() => !!u())() && l();
344
345
  },
345
346
  get fallback() {
346
347
  return s(ie, {
@@ -352,13 +353,13 @@ function X(e) {
352
353
  class: "w-4 h-4"
353
354
  });
354
355
  }
355
- })), h(x, () => e.item.name), h(f, s(I, {
356
+ })), d(b, () => e.item.name), d(f, s(I, {
356
357
  get when() {
357
- return B(() => !!o())() && u();
358
+ return B(() => !!l())() && u();
358
359
  },
359
360
  get children() {
360
361
  var a = fe();
361
- return h(a, s(z, {
362
+ return d(a, s(z, {
362
363
  get each() {
363
364
  return r();
364
365
  },
@@ -385,9 +386,9 @@ function X(e) {
385
386
  })
386
387
  })), a;
387
388
  }
388
- }), null), T((a) => {
389
- var g = _("group flex items-center w-full text-xs", "transition-colors duration-100", c() ? "hover:bg-accent/60" : "opacity-50", n() && c() && "bg-accent text-accent-foreground font-medium"), y = `${4 + e.depth * 14}px`, $ = !c(), F = _("flex items-center gap-1 flex-1 min-w-0 text-left py-1.5 pl-0.5 pr-2", c() ? "cursor-pointer" : "cursor-not-allowed", "focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring");
390
- return g !== a.e && C(v, a.e = g), y !== a.t && ne(v, "padding-left", a.t = y), $ !== a.a && (P.disabled = a.a = $), F !== a.o && C(P, a.o = F), a;
389
+ }), null), E((a) => {
390
+ var g = p("group flex items-center w-full text-xs", "transition-colors duration-100", c() ? "hover:bg-accent/60" : "opacity-50", n() && c() && "bg-accent text-accent-foreground font-medium"), $ = `${4 + e.depth * 14}px`, k = !c(), F = p("flex items-center gap-1 flex-1 min-w-0 text-left py-1.5 pl-0.5 pr-2", c() ? "cursor-pointer" : "cursor-not-allowed", "focus:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-ring");
391
+ return g !== a.e && _(v, a.e = g), $ !== a.t && ne(v, "padding-left", a.t = $), k !== a.a && (w.disabled = a.a = k), F !== a.o && _(w, a.o = F), a;
391
392
  }, {
392
393
  e: void 0,
393
394
  t: void 0,
@@ -401,10 +402,10 @@ export {
401
402
  pe as NewFolderSection,
402
403
  Ie as PathInputBar,
403
404
  Fe as PickerBreadcrumb,
404
- Te as PickerFolderTree,
405
+ Ee as PickerFolderTree,
405
406
  X as PickerTreeNode,
406
407
  j as getAncestorPaths,
407
- k as normalizePath,
408
+ S as normalizePath,
408
409
  ve as useFolderIndex,
409
410
  _e as usePickerTree
410
411
  };
package/dist/index93.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createComponent as v } from "solid-js/web";
2
- import { createContext as C, useContext as p, createMemo as d } from "solid-js";
1
+ import { createComponent as I } from "solid-js/web";
2
+ import { createContext as b, useContext as h, createMemo as u } from "solid-js";
3
3
  const m = {
4
4
  storage: {
5
5
  namespace: "floe",
@@ -70,7 +70,7 @@ const m = {
70
70
  }
71
71
  }
72
72
  };
73
- function I() {
73
+ function F() {
74
74
  if (!(typeof window > "u"))
75
75
  return {
76
76
  getItem: (e) => localStorage.getItem(e),
@@ -79,97 +79,126 @@ function I() {
79
79
  keys: () => Object.keys(localStorage)
80
80
  };
81
81
  }
82
- function g(e) {
83
- const t = e.adapter ?? I(), c = e.namespace ? `${e.namespace}-` : "", o = (r) => `${c}${r}`, n = () => e.enabled && !!t, i = /* @__PURE__ */ new Map();
82
+ function v(e) {
83
+ const t = e.adapter ?? F(), c = e.namespace ? `${e.namespace}-` : "", i = (n) => `${c}${n}`, o = () => e.enabled && !!t, a = /* @__PURE__ */ new Map(), d = () => {
84
+ if (o()) {
85
+ for (const [n, r] of a.entries()) {
86
+ clearTimeout(r.timer);
87
+ try {
88
+ t.setItem(n, JSON.stringify(r.value));
89
+ } catch (s) {
90
+ console.warn(`Failed to save ${n}:`, s);
91
+ }
92
+ }
93
+ a.clear();
94
+ }
95
+ };
96
+ if (typeof window < "u")
97
+ try {
98
+ window.addEventListener("pagehide", d), window.addEventListener("beforeunload", d), typeof document < "u" && document.addEventListener("visibilitychange", () => {
99
+ document.visibilityState === "hidden" && d();
100
+ });
101
+ } catch {
102
+ }
84
103
  return {
85
- key: o,
86
- load: (r, a) => {
87
- if (!n()) return a;
104
+ key: i,
105
+ load: (n, r) => {
106
+ if (!o()) return r;
88
107
  try {
89
- const s = t.getItem(o(r));
90
- return s === null ? a : JSON.parse(s);
108
+ const s = t.getItem(i(n));
109
+ return s === null ? r : JSON.parse(s);
91
110
  } catch {
92
- return a;
111
+ return r;
93
112
  }
94
113
  },
95
- save: (r, a) => {
96
- if (n())
114
+ save: (n, r) => {
115
+ if (o())
97
116
  try {
98
- t.setItem(o(r), JSON.stringify(a));
117
+ t.setItem(i(n), JSON.stringify(r));
99
118
  } catch (s) {
100
- console.warn(`Failed to save ${o(r)}:`, s);
119
+ console.warn(`Failed to save ${i(n)}:`, s);
101
120
  }
102
121
  },
103
- debouncedSave: (r, a, s = 300) => {
104
- if (!n()) return;
105
- const l = o(r), u = i.get(l);
106
- u && clearTimeout(u), i.set(l, setTimeout(() => {
107
- try {
108
- t.setItem(l, JSON.stringify(a)), i.delete(l);
109
- } catch (h) {
110
- console.warn(`Failed to save ${l}:`, h);
122
+ debouncedSave: (n, r, s = 300) => {
123
+ if (!o()) return;
124
+ const l = i(n), g = a.get(l);
125
+ g && clearTimeout(g.timer);
126
+ const p = setTimeout(() => {
127
+ const f = a.get(l);
128
+ if (!(!f || f.timer !== p)) {
129
+ a.delete(l);
130
+ try {
131
+ t.setItem(l, JSON.stringify(f.value));
132
+ } catch (C) {
133
+ console.warn(`Failed to save ${l}:`, C);
134
+ }
111
135
  }
112
- }, s));
136
+ }, s);
137
+ a.set(l, {
138
+ timer: p,
139
+ value: r
140
+ });
113
141
  },
114
- remove: (r) => {
115
- if (n())
142
+ remove: (n) => {
143
+ if (o())
116
144
  try {
117
- t.removeItem(o(r));
145
+ t.removeItem(i(n));
118
146
  } catch {
119
147
  }
120
148
  },
121
149
  clearAll: () => {
122
- if (!n()) return;
123
- const r = t.keys?.() ?? [];
124
- for (const a of r)
125
- a.startsWith(c) && t.removeItem(a);
126
- }
150
+ if (!o()) return;
151
+ const n = t.keys?.() ?? [];
152
+ for (const r of n)
153
+ r.startsWith(c) && t.removeItem(r);
154
+ },
155
+ flush: d
127
156
  };
128
157
  }
129
- function y(e, t) {
158
+ function w(e, t) {
130
159
  if (!t) return e;
131
160
  if (typeof e != "object" || e === null || Array.isArray(e)) return t ?? e;
132
161
  const c = {
133
162
  ...e
134
163
  };
135
- for (const [o, n] of Object.entries(t)) {
136
- if (n === void 0) continue;
137
- const i = e[o];
138
- typeof i == "object" && i !== null && typeof n == "object" && n !== null && !Array.isArray(n) ? c[o] = y(i, n) : c[o] = n;
164
+ for (const [i, o] of Object.entries(t)) {
165
+ if (o === void 0) continue;
166
+ const a = e[i];
167
+ typeof a == "object" && a !== null && typeof o == "object" && o !== null && !Array.isArray(o) ? c[i] = w(a, o) : c[i] = o;
139
168
  }
140
169
  return c;
141
170
  }
142
- const f = C();
143
- function x(e) {
144
- const t = d(() => y(m, e.config)), c = d(() => g(t().storage)), o = d(() => ({
171
+ const y = b();
172
+ function A(e) {
173
+ const t = u(() => w(m, e.config)), c = u(() => v(t().storage)), i = u(() => ({
145
174
  config: t(),
146
175
  persist: c()
147
176
  }));
148
- return v(f.Provider, {
177
+ return I(y.Provider, {
149
178
  get value() {
150
- return o();
179
+ return i();
151
180
  },
152
181
  get children() {
153
182
  return e.children;
154
183
  }
155
184
  });
156
185
  }
157
- function S() {
158
- const e = p(f);
186
+ function E() {
187
+ const e = h(y);
159
188
  if (!e)
160
189
  throw new Error("FloeConfigContext not found. Make sure to wrap your app with FloeConfigProvider (or FloeProvider).");
161
190
  return e;
162
191
  }
163
- const F = g(m.storage), k = {
192
+ const S = v(m.storage), k = {
164
193
  config: m,
165
- persist: F
194
+ persist: S
166
195
  };
167
- function T() {
168
- return p(f) ?? k;
196
+ function L() {
197
+ return h(y) ?? k;
169
198
  }
170
199
  export {
171
200
  m as DEFAULT_FLOE_CONFIG,
172
- x as FloeConfigProvider,
173
- S as useFloeConfig,
174
- T as useResolvedFloeConfig
201
+ A as FloeConfigProvider,
202
+ E as useFloeConfig,
203
+ L as useResolvedFloeConfig
175
204
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/floe-webapp-core",
3
- "version": "0.15.0",
3
+ "version": "0.15.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",