@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
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { createComponent as l, insert as m, memo as S, effect as p, template as k, use as g, delegateEvents as D } from "solid-js/web";
|
|
2
|
+
import { createSignal as E, createEffect as b, on as L, onCleanup as B, Show as w } from "solid-js";
|
|
3
|
+
import { Star as F } from "../../icons/index.js";
|
|
4
|
+
import { Button as C } from "../Button.js";
|
|
5
|
+
import { SurfaceFloatingLayer as M } from "../SurfaceFloatingLayer.js";
|
|
6
|
+
import { useOverlayMask as P } from "../../../hooks/useOverlayMask.js";
|
|
7
|
+
var _ = /* @__PURE__ */ k('<div class="flex min-w-0 items-center">'), R = /* @__PURE__ */ k('<button type=button role=menuitem class="flex w-full cursor-pointer items-center gap-2 rounded px-2 py-1.5 text-left text-xs hover:bg-accent focus:bg-accent focus:outline-none">');
|
|
8
|
+
function z(e) {
|
|
9
|
+
const [s, f] = E(!1), a = () => e.favorites.paths.includes(e.path), u = () => a() ? e.copy.unfavoriteDirectory : e.copy.favoriteDirectory, v = async () => {
|
|
10
|
+
const n = e.favorites, d = e.path;
|
|
11
|
+
if (!(!n.editable || !n.onSetFavorite || s() || e.disabled || n.pendingPaths?.includes(d))) {
|
|
12
|
+
f(!0), e.onError?.("");
|
|
13
|
+
try {
|
|
14
|
+
await n.onSetFavorite(d, !a());
|
|
15
|
+
} catch (o) {
|
|
16
|
+
e.onError?.(o instanceof Error ? o.message : e.copy.favoritesLoadFailed);
|
|
17
|
+
} finally {
|
|
18
|
+
f(!1);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
return l(C, {
|
|
23
|
+
type: "button",
|
|
24
|
+
size: "sm",
|
|
25
|
+
variant: "ghost",
|
|
26
|
+
class: "shrink-0",
|
|
27
|
+
get "aria-label"() {
|
|
28
|
+
return u() + ": " + e.path;
|
|
29
|
+
},
|
|
30
|
+
get title() {
|
|
31
|
+
return u();
|
|
32
|
+
},
|
|
33
|
+
get "aria-pressed"() {
|
|
34
|
+
return a();
|
|
35
|
+
},
|
|
36
|
+
get loading() {
|
|
37
|
+
return s() || e.favorites.pendingPaths?.includes(e.path);
|
|
38
|
+
},
|
|
39
|
+
icon: () => l(F, {
|
|
40
|
+
get class() {
|
|
41
|
+
return a() ? "h-3.5 w-3.5 fill-current text-warning" : "h-3.5 w-3.5";
|
|
42
|
+
}
|
|
43
|
+
}),
|
|
44
|
+
get disabled() {
|
|
45
|
+
return e.disabled || !e.favorites.editable || !e.favorites.onSetFavorite;
|
|
46
|
+
},
|
|
47
|
+
onClick: () => {
|
|
48
|
+
v();
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function Y(e) {
|
|
53
|
+
const [s, f] = E();
|
|
54
|
+
let a, u, v;
|
|
55
|
+
const n = (o = !1) => {
|
|
56
|
+
const r = s()?.owner;
|
|
57
|
+
f(void 0), o && r?.isConnected && r.focus();
|
|
58
|
+
}, d = (o) => {
|
|
59
|
+
if (!e.favorites?.editable || e.disabled) return;
|
|
60
|
+
o.preventDefault(), o.stopPropagation();
|
|
61
|
+
const r = o.target instanceof HTMLElement ? o.target.closest("button") ?? a : a, t = r.getBoundingClientRect();
|
|
62
|
+
f({
|
|
63
|
+
path: e.path,
|
|
64
|
+
favorites: e.favorites,
|
|
65
|
+
favorite: !e.favorites.paths.includes(e.path),
|
|
66
|
+
owner: r,
|
|
67
|
+
x: o instanceof MouseEvent ? o.clientX : t.left,
|
|
68
|
+
y: o instanceof MouseEvent ? o.clientY : t.bottom
|
|
69
|
+
}), queueMicrotask(() => u?.focus());
|
|
70
|
+
};
|
|
71
|
+
return b(L(() => e.scopeKey, () => n())), P({
|
|
72
|
+
open: () => !!s(),
|
|
73
|
+
root: () => v,
|
|
74
|
+
onClose: () => n(!0),
|
|
75
|
+
closeOnEscape: !0,
|
|
76
|
+
lockBodyScroll: !1,
|
|
77
|
+
trapFocus: !1,
|
|
78
|
+
autoFocus: !1,
|
|
79
|
+
restoreFocus: !1,
|
|
80
|
+
blockHotkeys: !1
|
|
81
|
+
}), b(() => {
|
|
82
|
+
if (!s()) return;
|
|
83
|
+
const o = (t) => {
|
|
84
|
+
(!(t.target instanceof Element) || !t.target.closest("[data-picker-favorite-menu]")) && n();
|
|
85
|
+
}, r = (t) => {
|
|
86
|
+
(t.key === "Escape" || t.key === "Tab") && (t.key === "Escape" && (t.preventDefault(), t.stopPropagation()), n(t.key === "Escape"));
|
|
87
|
+
};
|
|
88
|
+
document.addEventListener("pointerdown", o, !0), document.addEventListener("keydown", r, !0), B(() => {
|
|
89
|
+
document.removeEventListener("pointerdown", o, !0), document.removeEventListener("keydown", r, !0);
|
|
90
|
+
});
|
|
91
|
+
}), (() => {
|
|
92
|
+
var o = _();
|
|
93
|
+
o.$$keydown = (t) => {
|
|
94
|
+
(t.key === "ContextMenu" || t.shiftKey && t.key === "F10") && d(t);
|
|
95
|
+
}, o.$$contextmenu = d;
|
|
96
|
+
var r = a;
|
|
97
|
+
return typeof r == "function" ? g(r, o) : a = o, m(o, () => e.children, null), m(o, l(w, {
|
|
98
|
+
get when() {
|
|
99
|
+
return e.favorites;
|
|
100
|
+
},
|
|
101
|
+
children: (t) => l(z, {
|
|
102
|
+
get path() {
|
|
103
|
+
return e.path;
|
|
104
|
+
},
|
|
105
|
+
get favorites() {
|
|
106
|
+
return t();
|
|
107
|
+
},
|
|
108
|
+
get copy() {
|
|
109
|
+
return e.copy;
|
|
110
|
+
},
|
|
111
|
+
get disabled() {
|
|
112
|
+
return e.disabled;
|
|
113
|
+
},
|
|
114
|
+
get onError() {
|
|
115
|
+
return e.onError;
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
}), null), m(o, l(w, {
|
|
119
|
+
get when() {
|
|
120
|
+
return s();
|
|
121
|
+
},
|
|
122
|
+
children: (t) => l(M, {
|
|
123
|
+
get position() {
|
|
124
|
+
return t();
|
|
125
|
+
},
|
|
126
|
+
get owner() {
|
|
127
|
+
return t().owner;
|
|
128
|
+
},
|
|
129
|
+
estimatedSize: {
|
|
130
|
+
width: 250,
|
|
131
|
+
height: 40
|
|
132
|
+
},
|
|
133
|
+
layerRef: (i) => {
|
|
134
|
+
v = i;
|
|
135
|
+
},
|
|
136
|
+
"data-picker-favorite-menu": "",
|
|
137
|
+
role: "menu",
|
|
138
|
+
class: "z-50 rounded-md border border-border bg-background p-1 shadow-lg",
|
|
139
|
+
get children() {
|
|
140
|
+
var i = R();
|
|
141
|
+
i.$$click = () => {
|
|
142
|
+
const c = t();
|
|
143
|
+
if (!c.favorites.editable || c.favorites.pendingPaths?.includes(c.path)) return;
|
|
144
|
+
const $ = e.onError, x = e.copy.favoritesLoadFailed;
|
|
145
|
+
n(!0), c.favorites.onSetFavorite?.(c.path, c.favorite).catch((h) => $(h instanceof Error ? h.message : x));
|
|
146
|
+
};
|
|
147
|
+
var y = u;
|
|
148
|
+
return typeof y == "function" ? g(y, i) : u = i, m(i, l(F, {
|
|
149
|
+
class: "h-3.5 w-3.5"
|
|
150
|
+
}), null), m(i, (() => {
|
|
151
|
+
var c = S(() => !!t().favorite);
|
|
152
|
+
return () => c() ? e.copy.favoriteDirectory : e.copy.unfavoriteDirectory;
|
|
153
|
+
})(), null), p(() => i.disabled = !t().favorites.editable || !t().favorites.onSetFavorite || t().favorites.pendingPaths?.includes(t().path)), i;
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
}), null), o;
|
|
157
|
+
})();
|
|
158
|
+
}
|
|
159
|
+
D(["contextmenu", "keydown", "click"]);
|
|
160
|
+
export {
|
|
161
|
+
z as DirectoryFavoriteButton,
|
|
162
|
+
Y as PickerDirectoryRow
|
|
163
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { type Accessor, type JSX } from 'solid-js';
|
|
2
|
-
import {
|
|
2
|
+
import { type DirectoryFavorites } from './DirectoryFavorites';
|
|
3
|
+
import { parsePickerPath, type PickerDataProps } from './PickerNavigation';
|
|
3
4
|
export interface PickerPanelProps extends PickerDataProps {
|
|
5
|
+
/** Host-owned directory navigation metadata for the current authenticated environment. */
|
|
6
|
+
directoryFavorites?: DirectoryFavorites;
|
|
4
7
|
disabled?: boolean;
|
|
5
8
|
/** Props for the actual constrained scrolling viewport, including host interaction markers. */
|
|
6
9
|
scrollViewportProps?: JSX.HTMLAttributes<HTMLDivElement>;
|
|
@@ -16,6 +19,13 @@ export interface BasePickerProps extends PickerPanelProps {
|
|
|
16
19
|
class?: string;
|
|
17
20
|
}
|
|
18
21
|
export declare function pickerCopy(config: PickerDataProps): {
|
|
22
|
+
favorites: string;
|
|
23
|
+
favoriteDirectory: string;
|
|
24
|
+
unfavoriteDirectory: string;
|
|
25
|
+
favoritesEmpty: string;
|
|
26
|
+
favoritesFilter: string;
|
|
27
|
+
favoritesNoMatches: string;
|
|
28
|
+
favoritesLoadFailed: string;
|
|
19
29
|
path: string;
|
|
20
30
|
go: string;
|
|
21
31
|
roots: string;
|
|
@@ -42,7 +52,9 @@ export declare function pickerCopy(config: PickerDataProps): {
|
|
|
42
52
|
};
|
|
43
53
|
export declare function pickerErrorMessage(props: PickerDataProps, error: unknown): string;
|
|
44
54
|
/** One owner for dialog and embedded pickers. Identity changes close the previous session first. */
|
|
45
|
-
export declare function usePickerNavigation(props:
|
|
55
|
+
export declare function usePickerNavigation(props: PickerPanelProps, open: Accessor<boolean>, onValidated?: (path: string) => void, onReset?: () => void, initialView?: Accessor<PickerLocation>): {
|
|
56
|
+
view: Accessor<PickerLocation>;
|
|
57
|
+
setView: import("solid-js").Setter<PickerLocation>;
|
|
46
58
|
context: Accessor<import("./PickerNavigation").PickerPathContext | null>;
|
|
47
59
|
currentPath: Accessor<string>;
|
|
48
60
|
entries: Accessor<readonly import("../..").FileItem[]>;
|
|
@@ -59,14 +71,13 @@ export declare function usePickerNavigation(props: PickerDataProps, open: Access
|
|
|
59
71
|
setShowHidden(value: boolean): Promise<void>;
|
|
60
72
|
retry(): Promise<void>;
|
|
61
73
|
};
|
|
74
|
+
export type PickerLocation = 'browse' | 'suggestions' | 'favorites';
|
|
62
75
|
/** Absolute directory navigation shared by all picker presentations. */
|
|
63
76
|
export declare function PickerPanel(props: PickerPanelProps & {
|
|
64
|
-
source:
|
|
77
|
+
source: ReturnType<typeof usePickerNavigation>;
|
|
65
78
|
suggestions?: {
|
|
66
79
|
paths: readonly string[];
|
|
67
80
|
label: string;
|
|
68
|
-
visible: boolean;
|
|
69
|
-
onVisibilityChange: (visible: boolean) => void;
|
|
70
81
|
};
|
|
71
82
|
}): JSX.Element;
|
|
72
83
|
export declare const normalizePath: typeof parsePickerPath;
|