@hachej/boring-workspace 0.1.64 → 0.1.65

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.
Files changed (36) hide show
  1. package/dist/FileTree-B_fRS4Om.js +230 -0
  2. package/dist/MarkdownEditor-C55gVDyW.js +743 -0
  3. package/dist/WorkspaceLoadingState-D3i4X-eH.js +847 -0
  4. package/dist/WorkspaceProvider-Ddx7GByq.js +8770 -0
  5. package/dist/app-front.d.ts +79 -2
  6. package/dist/app-front.js +3110 -2467
  7. package/dist/app-server.d.ts +2 -2
  8. package/dist/app-server.js +6 -4
  9. package/dist/boring-workspace.css +2 -1
  10. package/dist/charts.d.ts +6 -1
  11. package/dist/charts.js +131 -138
  12. package/dist/plugin.d.ts +64 -1
  13. package/dist/plugin.js +32 -0
  14. package/dist/rolldown-runtime-Dqa2HsxW.js +20 -0
  15. package/dist/{runtimeEnv-HolIkcoB.d.ts → runtimeEnv-CU-c4kaV.d.ts} +7 -0
  16. package/dist/server.d.ts +2 -2
  17. package/dist/server.js +4 -3
  18. package/dist/testing-e2e.d.ts +5 -0
  19. package/dist/testing-e2e.js +33 -42
  20. package/dist/testing.d.ts +6 -1
  21. package/dist/testing.js +9474 -10814
  22. package/dist/utils-BRcxFdrz.js +8 -0
  23. package/dist/workspace.css +2756 -290
  24. package/dist/workspace.d.ts +132 -15
  25. package/dist/workspace.js +568 -734
  26. package/docs/plans/archive/CODE_OWNERSHIP_CLEANUP_PLAN.md +1 -1
  27. package/docs/plans/archive/DECLARATIVE_LAYOUT_MIGRATION.md +4 -4
  28. package/docs/plans/archive/GENERIC_EXPLORER_PLUGIN_PLAN.md +10 -10
  29. package/docs/plans/archive/PLUGIN_MODEL.md +37 -37
  30. package/docs/plans/archive/WORKSPACE_V2_PLAN.md +2 -2
  31. package/package.json +50 -50
  32. package/dist/FileTree-DjhAzlg3.js +0 -315
  33. package/dist/MarkdownEditor-CeN7n6mw.js +0 -610
  34. package/dist/WorkspaceLoadingState-D4SB2awA.js +0 -867
  35. package/dist/WorkspaceProvider-CEZUOy1M.js +0 -8725
  36. package/dist/utils-B6yFEsav.js +0 -8
@@ -1,315 +0,0 @@
1
- import { jsx as d, jsxs as y } from "react/jsx-runtime";
2
- import { useRef as C, useMemo as I, useEffect as M, useCallback as k, createContext as E, useContext as J } from "react";
3
- import { Tree as K } from "react-arborist";
4
- import { FolderOpenIcon as U, FolderIcon as V, ChevronRightIcon as X, Loader2Icon as Y } from "lucide-react";
5
- import { a2 as Z } from "./WorkspaceProvider-CEZUOy1M.js";
6
- import { EmptyState as G, Input as H } from "@hachej/boring-ui-kit";
7
- import { c as g } from "./utils-B6yFEsav.js";
8
- import { createDragDropManager as Q } from "dnd-core";
9
- import { HTML5Backend as tt } from "react-dnd-html5-backend";
10
- const D = Symbol.for("@hachej/boring-workspace/file-tree-dnd-manager");
11
- function et() {
12
- const r = globalThis;
13
- return r[D] ?? (r[D] = Q(
14
- tt,
15
- typeof window > "u" ? void 0 : window
16
- )), r[D];
17
- }
18
- const W = /* @__PURE__ */ new Set(), j = E({
19
- onContextMenu: void 0,
20
- editing: null,
21
- pendingPaths: W,
22
- onSubmitEdit: void 0,
23
- onCancelEdit: void 0
24
- });
25
- function rt({
26
- initialValue: r,
27
- onSubmit: u,
28
- onCancel: s,
29
- isDraft: l
30
- }) {
31
- const e = C(null), a = C(!1);
32
- M(() => {
33
- const t = e.current;
34
- if (t)
35
- if (t.focus(), !l && r.includes(".")) {
36
- const i = r.lastIndexOf(".");
37
- t.setSelectionRange(0, i);
38
- } else
39
- t.select();
40
- }, [r, l]);
41
- const n = () => {
42
- var i;
43
- if (a.current) return;
44
- a.current = !0;
45
- const t = ((i = e.current) == null ? void 0 : i.value.trim()) ?? "";
46
- !t || t === r ? s() : u(t);
47
- };
48
- return /* @__PURE__ */ d(
49
- H,
50
- {
51
- ref: e,
52
- type: "text",
53
- defaultValue: r,
54
- "data-testid": "file-tree-edit-input",
55
- "aria-label": l ? "Name" : "Rename",
56
- onPointerDown: (t) => t.stopPropagation(),
57
- onClick: (t) => t.stopPropagation(),
58
- onKeyDown: (t) => {
59
- t.stopPropagation(), t.key === "Enter" ? (t.preventDefault(), n()) : t.key === "Escape" && (t.preventDefault(), a.current = !0, s());
60
- },
61
- onBlur: n,
62
- className: "h-5 min-w-0 flex-1 rounded-sm border-[color:var(--accent)]/60 px-1 text-[13px] leading-[1.2] focus-visible:ring-[color:var(--accent)]"
63
- }
64
- );
65
- }
66
- function nt(r) {
67
- const u = /* @__PURE__ */ new Set();
68
- let s = 0;
69
- const l = (e) => {
70
- const a = [];
71
- for (const n of e) {
72
- if (typeof (n == null ? void 0 : n.path) != "string" || n.path.length === 0 || u.has(n.path)) {
73
- s++;
74
- continue;
75
- }
76
- u.add(n.path), a.push(
77
- n.children && n.children.length > 0 ? { ...n, children: l(n.children) } : n
78
- );
79
- }
80
- return a;
81
- };
82
- return { nodes: l(r), dropped: s };
83
- }
84
- function ot(r, u) {
85
- if (!(u != null && u.trim())) return r.length;
86
- const s = u.trim().toLowerCase(), l = (e) => {
87
- var n;
88
- let a = 0;
89
- for (const t of e) {
90
- const i = t.name.toLowerCase().includes(s), m = (n = t.children) != null && n.length ? l(t.children) : 0;
91
- (i || m > 0) && (a += 1);
92
- }
93
- return a;
94
- };
95
- return l(r);
96
- }
97
- function it({ node: r, style: u, dragHandle: s }) {
98
- const { onContextMenu: l, editing: e, pendingPaths: a, onSubmitEdit: n, onCancelEdit: t } = J(j), i = r.data, m = i.kind === "dir", h = (e == null ? void 0 : e.path) === i.path, w = a.has(i.path), F = m ? r.isOpen ? U : V : Z(i.name || "untitled");
99
- return /* @__PURE__ */ y(
100
- "div",
101
- {
102
- ref: s,
103
- style: u,
104
- className: g(
105
- "group relative mx-1 flex items-center gap-1.5 rounded-md px-2 py-0.5 text-[13px] leading-[1.4] cursor-pointer select-none text-foreground",
106
- "transition-colors duration-150 ease-[cubic-bezier(0.22,1,0.36,1)]",
107
- !h && "hover:bg-foreground/[0.04]",
108
- r.isSelected && !h && "bg-[oklch(from_var(--accent)_l_c_h/0.10)] text-foreground font-medium",
109
- r.willReceiveDrop && "bg-foreground/5 outline outline-1 outline-border"
110
- ),
111
- onClick: (f) => {
112
- h || (f.stopPropagation(), m ? r.toggle() : (r.select(), r.activate()));
113
- },
114
- onContextMenu: (f) => {
115
- h || i.isDraft || (f.preventDefault(), f.stopPropagation(), l == null || l(f, i));
116
- },
117
- children: [
118
- m ? /* @__PURE__ */ d(
119
- X,
120
- {
121
- className: g(
122
- "h-3 w-3 shrink-0 text-muted-foreground/70 transition-transform duration-150 ease-[cubic-bezier(0.22,1,0.36,1)]",
123
- r.isOpen && "rotate-90"
124
- ),
125
- strokeWidth: 2
126
- }
127
- ) : /* @__PURE__ */ d("span", { className: "w-3 shrink-0" }),
128
- /* @__PURE__ */ d(
129
- F,
130
- {
131
- className: g(
132
- "h-4 w-4 shrink-0",
133
- r.isSelected ? "text-[color:var(--accent)]" : "text-muted-foreground/80"
134
- ),
135
- strokeWidth: 1.5
136
- }
137
- ),
138
- h ? /* @__PURE__ */ d(
139
- rt,
140
- {
141
- initialValue: (e == null ? void 0 : e.initialValue) ?? i.name ?? "",
142
- isDraft: !!(e != null && e.isDraft),
143
- onSubmit: (f) => n == null ? void 0 : n(i.path, f),
144
- onCancel: () => t == null ? void 0 : t()
145
- }
146
- ) : /* @__PURE__ */ d(
147
- "span",
148
- {
149
- className: g(
150
- "truncate",
151
- w && "text-muted-foreground italic"
152
- ),
153
- children: i.name
154
- }
155
- ),
156
- w && !h && /* @__PURE__ */ d(
157
- Y,
158
- {
159
- "data-testid": "file-tree-pending-spinner",
160
- "aria-label": "Pending",
161
- className: "ml-auto h-3 w-3 shrink-0 animate-spin text-muted-foreground/70",
162
- strokeWidth: 2
163
- }
164
- )
165
- ]
166
- }
167
- );
168
- }
169
- function ht({
170
- files: r,
171
- selectedPath: u,
172
- searchQuery: s,
173
- height: l = 400,
174
- editing: e,
175
- revealPath: a,
176
- pendingPaths: n,
177
- onSelect: t,
178
- onExpand: i,
179
- onCollapse: m,
180
- onContextMenu: h,
181
- onSubmitEdit: w,
182
- onCancelEdit: F,
183
- onRevealHandled: f,
184
- onDragDrop: A,
185
- className: P
186
- }) {
187
- const b = C(null), { nodes: T, dropped: v } = I(
188
- () => nt(r),
189
- [r]
190
- ), L = C(0);
191
- M(() => {
192
- v > 0 && v !== L.current && console.warn(
193
- `[filesystem] dropped ${v} file-tree node(s) with a missing or duplicate path`
194
- ), L.current = v;
195
- }, [v]), M(() => {
196
- if (!(e != null && e.isDraft)) return;
197
- const o = requestAnimationFrame(() => {
198
- var c;
199
- (c = b.current) == null || c.scrollTo(e.path);
200
- });
201
- return () => cancelAnimationFrame(o);
202
- }, [e == null ? void 0 : e.isDraft, e == null ? void 0 : e.path]), M(() => {
203
- if (!a) return;
204
- let o = 0;
205
- const c = requestAnimationFrame(() => {
206
- const p = b.current;
207
- if (!p) return;
208
- p.openParents(a);
209
- const x = p.get(a);
210
- x && (x.isInternal && x.open(), o = requestAnimationFrame(() => {
211
- var N;
212
- (N = b.current) == null || N.scrollTo(a), f == null || f(a);
213
- }));
214
- });
215
- return () => {
216
- cancelAnimationFrame(c), cancelAnimationFrame(o);
217
- };
218
- }, [r, f, a]);
219
- const O = I(
220
- () => u || void 0,
221
- [u]
222
- ), R = k(
223
- (o) => {
224
- o.data.kind === "file" && (t == null || t(o.data.path));
225
- },
226
- [t]
227
- ), q = k(
228
- (o) => {
229
- var p;
230
- const c = (p = b.current) == null ? void 0 : p.get(o);
231
- c && (c.isOpen ? i == null || i(c.data.path) : m == null || m(c.data.path));
232
- },
233
- [i, m]
234
- ), z = k(
235
- (o) => {
236
- if (!A) return;
237
- const c = !o.parentNode || o.parentNode.isRoot, p = c ? "." : o.parentNode.data.path;
238
- if (!(!c && o.parentNode.data.kind !== "dir"))
239
- for (const x of o.dragNodes) {
240
- const N = x.data.path;
241
- if (p === N || p !== "." && p.startsWith(N + "/")) return;
242
- A(N, p);
243
- }
244
- },
245
- [A]
246
- ), B = k(
247
- (o) => {
248
- if (!o.parentNode || o.parentNode.isRoot) return !1;
249
- if (o.parentNode.data.kind !== "dir") return !0;
250
- for (const c of o.dragNodes)
251
- if (o.parentNode.data.path === c.data.path || o.parentNode.data.path.startsWith(c.data.path + "/")) return !0;
252
- return !1;
253
- },
254
- []
255
- ), S = k(
256
- (o, c) => o.data.name.toLowerCase().includes(c.toLowerCase()),
257
- []
258
- ), _ = I(
259
- () => ({
260
- onContextMenu: h,
261
- editing: e ?? null,
262
- pendingPaths: n ?? W,
263
- onSubmitEdit: w,
264
- onCancelEdit: F
265
- }),
266
- [h, e, n, w, F]
267
- ), $ = I(
268
- () => ot(T, s),
269
- [T, s]
270
- );
271
- return T.length === 0 ? /* @__PURE__ */ d(
272
- "div",
273
- {
274
- className: g(
275
- "flex h-full items-center justify-center text-sm text-muted-foreground",
276
- P
277
- ),
278
- children: "No files"
279
- }
280
- ) : $ === 0 ? /* @__PURE__ */ d("div", { className: g("flex h-full items-center justify-center p-6", P), children: /* @__PURE__ */ d(
281
- G,
282
- {
283
- className: "min-h-0 border-0",
284
- title: "No matching files",
285
- description: s != null && s.trim() ? `No files match “${s.trim()}”.` : "No files match the current filter."
286
- }
287
- ) }) : /* @__PURE__ */ d(j.Provider, { value: _, children: /* @__PURE__ */ d("div", { "data-boring-workspace-part": "file-tree", className: g("file-tree", P), children: /* @__PURE__ */ d(
288
- K,
289
- {
290
- ref: b,
291
- data: T,
292
- idAccessor: "path",
293
- childrenAccessor: "children",
294
- openByDefault: !1,
295
- width: "100%",
296
- height: l,
297
- rowHeight: 26,
298
- indent: 14,
299
- selection: O,
300
- searchTerm: s ?? "",
301
- searchMatch: S,
302
- onActivate: R,
303
- onToggle: q,
304
- onMove: z,
305
- disableDrop: B,
306
- disableEdit: !0,
307
- dndManager: et(),
308
- children: it
309
- }
310
- ) }) });
311
- }
312
- export {
313
- ht as FileTree,
314
- nt as sanitizeFileTree
315
- };