@floegence/floe-webapp-core 0.35.37 → 0.35.39
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/DirectoryInput.d.ts +4 -1
- package/dist/components/ui/DirectoryInput.js +34 -29
- package/dist/components/ui/DirectoryPicker.js +23 -12
- package/dist/components/ui/FileSavePicker.js +56 -48
- package/dist/components/ui/InfiniteCanvas.d.ts +29 -0
- package/dist/components/ui/InfiniteCanvas.js +153 -0
- package/dist/components/ui/index.d.ts +2 -1
- package/dist/components/ui/picker/PickerBase.d.ts +29 -2
- package/dist/components/ui/picker/PickerBase.js +353 -234
- package/dist/full.js +397 -391
- package/dist/index.js +118 -114
- package/dist/styles.css +1 -1
- package/dist/ui.css +27 -0
- package/dist/ui.js +44 -42
- package/dist/utils/hotInteraction.js +4 -3
- package/dist/utils/index.d.ts +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { insert as q, effect as G, className as I, setAttribute as J, setStyleProperty as K, template as Q, use as ee, delegateEvents as te } from "solid-js/web";
|
|
2
|
+
import { createSignal as T, untrack as D, createEffect as L, onCleanup as y } from "solid-js";
|
|
3
|
+
import { cn as Y } from "../../utils/cn.js";
|
|
4
|
+
import { isTypingElement as _ } from "../../utils/dom.js";
|
|
5
|
+
import { startHotInteraction as b } from "../../utils/hotInteraction.js";
|
|
6
|
+
var ne = /* @__PURE__ */ Q('<div><div style="transform-origin:0 0">');
|
|
7
|
+
const re = 1, ie = 0.45, oe = 2.2, ae = 14e-4, ce = '[data-floe-canvas-pan-surface="true"]', A = 3;
|
|
8
|
+
function le(n, a, d) {
|
|
9
|
+
return Math.max(a, Math.min(d, n));
|
|
10
|
+
}
|
|
11
|
+
function M(n) {
|
|
12
|
+
return {
|
|
13
|
+
x: Number.isFinite(n.x) ? n.x : 0,
|
|
14
|
+
y: Number.isFinite(n.y) ? n.y : 0,
|
|
15
|
+
scale: Number.isFinite(n.scale) && n.scale > 0 ? n.scale : re
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function se(n, a) {
|
|
19
|
+
return n.deltaMode === 1 ? n.deltaY * 16 : n.deltaMode === 2 ? n.deltaY * (a?.clientHeight ?? window.innerHeight) : n.deltaY;
|
|
20
|
+
}
|
|
21
|
+
function we(n) {
|
|
22
|
+
const [a, d] = T(D(() => M(n.viewport))), [p, S] = T(null);
|
|
23
|
+
let o, f, m = !1, l;
|
|
24
|
+
const X = () => n.interactiveSelector ?? '[data-floe-canvas-interactive="true"]', F = () => n.panSurfaceSelector ?? ce, $ = () => n.minScale ?? ie, k = () => n.maxScale ?? oe, V = () => n.wheelZoomSpeed ?? ae, R = () => {
|
|
25
|
+
const e = p();
|
|
26
|
+
return e ? e.startedFromPanSurface ? e.moved : !0 : !1;
|
|
27
|
+
}, C = () => {
|
|
28
|
+
f !== void 0 && (window.clearTimeout(f), f = void 0);
|
|
29
|
+
}, v = () => {
|
|
30
|
+
m = !1, l !== void 0 && (window.clearTimeout(l), l = void 0);
|
|
31
|
+
}, N = () => {
|
|
32
|
+
if (typeof window > "u") {
|
|
33
|
+
m = !1;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
l !== void 0 && window.clearTimeout(l), l = window.setTimeout(() => {
|
|
37
|
+
l = void 0, m = !1;
|
|
38
|
+
}, 0);
|
|
39
|
+
}, h = (e) => {
|
|
40
|
+
D(() => n.onViewportChange?.(e));
|
|
41
|
+
}, U = (e) => {
|
|
42
|
+
if (typeof window > "u") {
|
|
43
|
+
h(e);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
C(), f = window.setTimeout(() => {
|
|
47
|
+
f = void 0, h(e);
|
|
48
|
+
}, 90);
|
|
49
|
+
}, E = (e) => e instanceof Element ? e.closest(X()) ? !0 : _(e) : !1, x = (e) => e instanceof Element ? e.closest(F()) !== null : !1, g = (e) => {
|
|
50
|
+
const t = p();
|
|
51
|
+
if (!t || e !== void 0 && t.pointerId !== e) return;
|
|
52
|
+
t.stopInteraction?.();
|
|
53
|
+
const r = a();
|
|
54
|
+
S(null), o && o.hasPointerCapture(t.pointerId) && o.releasePointerCapture(t.pointerId), t.startedFromPanSurface && t.moved && (m = !0, N()), h(r);
|
|
55
|
+
};
|
|
56
|
+
L(() => {
|
|
57
|
+
p() || d(M(n.viewport));
|
|
58
|
+
}), L(() => {
|
|
59
|
+
const e = o;
|
|
60
|
+
if (!e) return;
|
|
61
|
+
const t = (r) => {
|
|
62
|
+
!m || !x(r.target) || (v(), r.preventDefault(), r.stopPropagation());
|
|
63
|
+
};
|
|
64
|
+
e.addEventListener("click", t, !0), y(() => {
|
|
65
|
+
e.removeEventListener("click", t, !0);
|
|
66
|
+
});
|
|
67
|
+
}), y(() => {
|
|
68
|
+
C(), g(), v();
|
|
69
|
+
});
|
|
70
|
+
const H = (e) => {
|
|
71
|
+
if (e.button !== 0 || _(e.target)) return;
|
|
72
|
+
const t = x(e.target);
|
|
73
|
+
E(e.target) && !t || (C(), v(), t || (e.preventDefault(), o?.setPointerCapture(e.pointerId)), S({
|
|
74
|
+
pointerId: e.pointerId,
|
|
75
|
+
startClientX: e.clientX,
|
|
76
|
+
startClientY: e.clientY,
|
|
77
|
+
startViewport: a(),
|
|
78
|
+
moved: !1,
|
|
79
|
+
startedFromPanSurface: t,
|
|
80
|
+
stopInteraction: t ? void 0 : b({
|
|
81
|
+
kind: "drag",
|
|
82
|
+
cursor: "grabbing"
|
|
83
|
+
})
|
|
84
|
+
}));
|
|
85
|
+
}, O = (e) => {
|
|
86
|
+
const t = p();
|
|
87
|
+
if (!t || t.pointerId !== e.pointerId) return;
|
|
88
|
+
const r = e.clientX - t.startClientX, i = e.clientY - t.startClientY;
|
|
89
|
+
if (!(t.moved || Math.abs(r) > A || Math.abs(i) > A)) return;
|
|
90
|
+
t.moved || (e.preventDefault(), o?.hasPointerCapture(e.pointerId) || o?.setPointerCapture(e.pointerId));
|
|
91
|
+
const u = {
|
|
92
|
+
...t.startViewport,
|
|
93
|
+
x: t.startViewport.x + r,
|
|
94
|
+
y: t.startViewport.y + i
|
|
95
|
+
};
|
|
96
|
+
t.moved || S({
|
|
97
|
+
...t,
|
|
98
|
+
moved: !0,
|
|
99
|
+
stopInteraction: t.stopInteraction ?? b({
|
|
100
|
+
kind: "drag",
|
|
101
|
+
cursor: "grabbing"
|
|
102
|
+
})
|
|
103
|
+
}), d(u);
|
|
104
|
+
}, W = (e) => {
|
|
105
|
+
g(e.pointerId);
|
|
106
|
+
}, Z = (e) => {
|
|
107
|
+
g(e.pointerId);
|
|
108
|
+
}, B = (e) => {
|
|
109
|
+
const t = o?.getBoundingClientRect();
|
|
110
|
+
if (!t) return;
|
|
111
|
+
e.preventDefault();
|
|
112
|
+
const r = a(), i = e.clientX - t.left, c = e.clientY - t.top, u = se(e, o), s = le(r.scale * Math.exp(-u * V()), $(), k());
|
|
113
|
+
if (Math.abs(s - r.scale) < 1e-4) return;
|
|
114
|
+
const w = (i - r.x) / r.scale, j = (c - r.y) / r.scale, P = {
|
|
115
|
+
x: i - w * s,
|
|
116
|
+
y: c - j * s,
|
|
117
|
+
scale: s
|
|
118
|
+
};
|
|
119
|
+
d(P), U(P);
|
|
120
|
+
}, z = (e) => {
|
|
121
|
+
if (E(e.target)) return;
|
|
122
|
+
const t = o?.getBoundingClientRect();
|
|
123
|
+
if (!t) return;
|
|
124
|
+
e.preventDefault();
|
|
125
|
+
const r = e.clientX - t.left, i = e.clientY - t.top, c = a();
|
|
126
|
+
n.onCanvasContextMenu?.({
|
|
127
|
+
clientX: e.clientX,
|
|
128
|
+
clientY: e.clientY,
|
|
129
|
+
localX: r,
|
|
130
|
+
localY: i,
|
|
131
|
+
worldX: (r - c.x) / c.scale,
|
|
132
|
+
worldY: (i - c.y) / c.scale
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
return (() => {
|
|
136
|
+
var e = ne(), t = e.firstChild;
|
|
137
|
+
e.$$contextmenu = z, e.addEventListener("wheel", B), e.addEventListener("pointercancel", Z), e.$$pointerup = W, e.$$pointermove = O, e.$$pointerdown = H;
|
|
138
|
+
var r = o;
|
|
139
|
+
return typeof r == "function" ? ee(r, e) : o = e, q(t, () => n.children), G((i) => {
|
|
140
|
+
var c = Y("floe-infinite-canvas", R() && "is-panning", n.class), u = n.ariaLabel ?? "Infinite canvas", s = Y("floe-infinite-canvas__viewport", n.contentClass), w = `translate(${a().x}px, ${a().y}px) scale(${a().scale})`;
|
|
141
|
+
return c !== i.e && I(e, i.e = c), u !== i.t && J(e, "aria-label", i.t = u), s !== i.a && I(t, i.a = s), w !== i.o && K(t, "transform", i.o = w), i;
|
|
142
|
+
}, {
|
|
143
|
+
e: void 0,
|
|
144
|
+
t: void 0,
|
|
145
|
+
a: void 0,
|
|
146
|
+
o: void 0
|
|
147
|
+
}), e;
|
|
148
|
+
})();
|
|
149
|
+
}
|
|
150
|
+
te(["pointerdown", "pointermove", "pointerup", "contextmenu"]);
|
|
151
|
+
export {
|
|
152
|
+
we as InfiniteCanvas
|
|
153
|
+
};
|
|
@@ -6,12 +6,13 @@ export { FloatingWindow, type FloatingWindowProps } from './FloatingWindow';
|
|
|
6
6
|
export { Dropdown, Select, type DropdownProps, type DropdownItem, type SelectProps, } from './Dropdown';
|
|
7
7
|
export { Tooltip, type TooltipProps } from './Tooltip';
|
|
8
8
|
export { CommandPalette } from './CommandPalette';
|
|
9
|
+
export { InfiniteCanvas, type InfiniteCanvasProps, type InfiniteCanvasPoint, type InfiniteCanvasContextMenuEvent, } from './InfiniteCanvas';
|
|
9
10
|
export { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter, Interactive3DCard, AnimatedBorderCard, NeonCard, MorphCard, type CardProps, type CardVariant, type CardHeaderProps, type CardTitleProps, type CardDescriptionProps, type CardContentProps, type CardFooterProps, type Interactive3DCardProps, type AnimatedBorderCardProps, type NeonCardProps, type MorphCardProps, } from './Card';
|
|
10
11
|
export { Tabs, TabPanel, type TabsProps, type TabPanelProps, type TabItem, type TabsFeatures, type TabsSlotClassNames, type TabsIndicatorMode, type TabsIndicatorColorToken, } from './Tabs';
|
|
11
12
|
export { DirectoryPicker, type DirectoryPickerProps } from './DirectoryPicker';
|
|
12
13
|
export { DirectoryInput, type DirectoryInputProps, type DirectoryInputSize, } from './DirectoryInput';
|
|
13
14
|
export { FileSavePicker, type FileSavePickerProps } from './FileSavePicker';
|
|
14
|
-
export { type BasePickerProps } from './picker/PickerBase';
|
|
15
|
+
export { type BasePickerProps, type PickerEnsurePath, type PickerEnsurePathOptions, type PickerPathResolveResult, type PickerPathResolveStatus, type PickerPathNavigateReason, } from './picker/PickerBase';
|
|
15
16
|
export { QuoteBlock, type QuoteBlockProps } from './QuoteBlock';
|
|
16
17
|
export { HighlightBlock, InfoBlock, WarningBlock, SuccessBlock, ErrorBlock, NoteBlock, TipBlock, type HighlightBlockProps, type HighlightVariant, } from './HighlightBlock';
|
|
17
18
|
export { ProcessingIndicator, type ProcessingIndicatorProps, type ProcessingIndicatorVariant, type ProcessingIndicatorStatus, } from './ProcessingIndicator';
|
|
@@ -33,7 +33,13 @@ export interface BasePickerProps {
|
|
|
33
33
|
* Use this to dynamically load children for the expanded directory.
|
|
34
34
|
* The path parameter is the internal tree path (not the display path).
|
|
35
35
|
*/
|
|
36
|
-
onExpand?: (path: string) => void
|
|
36
|
+
onExpand?: (path: string) => void | Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Async resolver used when a navigation target may exist outside the current
|
|
39
|
+
* in-memory tree snapshot. A ready result guarantees the target path and its
|
|
40
|
+
* ancestor chain are now represented in `files`.
|
|
41
|
+
*/
|
|
42
|
+
ensurePath?: PickerEnsurePath;
|
|
37
43
|
/** Filter which directories are selectable (return false to grey-out) */
|
|
38
44
|
filter?: (item: FileItem) => boolean;
|
|
39
45
|
/** Label for the home/root directory (default: 'Root') */
|
|
@@ -67,7 +73,9 @@ export interface UsePickerTreeOptions {
|
|
|
67
73
|
* Callback when user expands a directory.
|
|
68
74
|
* Use this to dynamically load children for the expanded directory.
|
|
69
75
|
*/
|
|
70
|
-
onExpand?: (path: string) => void
|
|
76
|
+
onExpand?: (path: string) => void | Promise<void>;
|
|
77
|
+
/** Async resolver that ensures a target path exists in the current tree snapshot. */
|
|
78
|
+
ensurePath?: PickerEnsurePath;
|
|
71
79
|
/** Label for the home/root directory in tree and breadcrumb (default: 'Root'). Supports accessor for reactivity. */
|
|
72
80
|
homeLabel?: string | Accessor<string | undefined>;
|
|
73
81
|
/**
|
|
@@ -84,6 +92,7 @@ export interface PickerTreeState {
|
|
|
84
92
|
toggleExpand: (path: string) => void;
|
|
85
93
|
pathInput: Accessor<string>;
|
|
86
94
|
setPathInput: (value: string) => void;
|
|
95
|
+
pathPending: Accessor<boolean>;
|
|
87
96
|
pathInputError: Accessor<string>;
|
|
88
97
|
setPathInputError: (value: string) => void;
|
|
89
98
|
folderIndex: Accessor<Map<string, FileItem>>;
|
|
@@ -95,6 +104,7 @@ export interface PickerTreeState {
|
|
|
95
104
|
handlePathInputGo: () => void;
|
|
96
105
|
handlePathInputKeyDown: (e: KeyboardEvent) => void;
|
|
97
106
|
expandToPath: (path: string) => void;
|
|
107
|
+
navigateToPath: (path: string, options: PickerEnsurePathOptions) => Promise<PickerPathResolveResult>;
|
|
98
108
|
breadcrumbSegments: Accessor<{
|
|
99
109
|
name: string;
|
|
100
110
|
path: string;
|
|
@@ -104,7 +114,20 @@ export interface PickerTreeState {
|
|
|
104
114
|
homeLabel: Accessor<string>;
|
|
105
115
|
/** Convert internal tree path to display (real filesystem) path */
|
|
106
116
|
toDisplayPath: (internalPath: string) => string;
|
|
117
|
+
/** Monotonic counter used to reveal the selected row after async navigation. */
|
|
118
|
+
revealNonce: Accessor<number>;
|
|
119
|
+
}
|
|
120
|
+
export type PickerPathResolveStatus = 'ready' | 'missing' | 'error';
|
|
121
|
+
export type PickerPathNavigateReason = 'open' | 'path-input' | 'tree-expand' | 'tree-select' | 'breadcrumb';
|
|
122
|
+
export interface PickerEnsurePathOptions {
|
|
123
|
+
reason: PickerPathNavigateReason;
|
|
124
|
+
}
|
|
125
|
+
export interface PickerPathResolveResult {
|
|
126
|
+
status: PickerPathResolveStatus;
|
|
127
|
+
resolvedPath: string;
|
|
128
|
+
message?: string;
|
|
107
129
|
}
|
|
130
|
+
export type PickerEnsurePath = (path: string, options: PickerEnsurePathOptions) => PickerPathResolveResult | Promise<PickerPathResolveResult>;
|
|
108
131
|
export declare function resolvePickerInitialPath(initialPath: string | undefined, homePath: string | undefined): string;
|
|
109
132
|
export declare function usePickerTree(opts: UsePickerTreeOptions): PickerTreeState;
|
|
110
133
|
export interface NewFolderSectionProps {
|
|
@@ -117,6 +140,7 @@ export declare function NewFolderSection(props: NewFolderSectionProps): JSX.Elem
|
|
|
117
140
|
export interface PathInputBarProps {
|
|
118
141
|
value: Accessor<string>;
|
|
119
142
|
onInput: (value: string) => void;
|
|
143
|
+
pending?: Accessor<boolean>;
|
|
120
144
|
error: Accessor<string>;
|
|
121
145
|
onGo: () => void;
|
|
122
146
|
onKeyDown: (e: KeyboardEvent) => void;
|
|
@@ -135,6 +159,7 @@ export interface PickerFolderTreeProps {
|
|
|
135
159
|
rootFolders: Accessor<FileItem[]>;
|
|
136
160
|
selectedPath: Accessor<string>;
|
|
137
161
|
expandedPaths: Accessor<Set<string>>;
|
|
162
|
+
revealNonce?: Accessor<number>;
|
|
138
163
|
onToggle: (path: string) => void;
|
|
139
164
|
onSelect: (item: FileItem) => void;
|
|
140
165
|
onSelectRoot: () => void;
|
|
@@ -151,8 +176,10 @@ export interface PickerTreeNodeProps {
|
|
|
151
176
|
depth: number;
|
|
152
177
|
selectedPath: Accessor<string>;
|
|
153
178
|
expandedPaths: Accessor<Set<string>>;
|
|
179
|
+
revealNonce?: Accessor<number>;
|
|
154
180
|
onToggle: (path: string) => void;
|
|
155
181
|
onSelect: (item: FileItem) => void;
|
|
156
182
|
isSelectable: (item: FileItem) => boolean;
|
|
183
|
+
registerRow: (path: string, el: HTMLButtonElement | null) => void;
|
|
157
184
|
}
|
|
158
185
|
export declare function PickerTreeNode(props: PickerTreeNodeProps): JSX.Element;
|