@w100n/documents 0.17.0 → 0.18.1

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 (37) hide show
  1. package/dist/{SheetView-SBLAFGTL.js → SheetView-F4CBWEOS.js} +4 -4
  2. package/dist/{TextEditor-X2GSL4QM.js → TextEditor-ZY4B7YIF.js} +5 -5
  3. package/dist/{chunk-A6AHJCEK.js → chunk-2G34AIPU.js} +3 -3
  4. package/dist/{chunk-A6AHJCEK.js.map → chunk-2G34AIPU.js.map} +1 -1
  5. package/dist/{chunk-B7C6NBBQ.js → chunk-BWU6FPPZ.js} +28 -1
  6. package/dist/chunk-BWU6FPPZ.js.map +1 -0
  7. package/dist/{chunk-ASTNK6WZ.js → chunk-TSB2QS56.js} +2 -2
  8. package/dist/{chunk-FFXAOK4A.js → chunk-Z5STMOD6.js} +2 -2
  9. package/dist/collab.cjs +28 -1
  10. package/dist/collab.cjs.map +1 -1
  11. package/dist/collab.d.cts +1 -1
  12. package/dist/collab.d.ts +1 -1
  13. package/dist/collab.js +2 -2
  14. package/dist/index.cjs +277 -45
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.css +28 -2
  17. package/dist/index.css.map +1 -1
  18. package/dist/index.d.cts +2 -2
  19. package/dist/index.d.ts +2 -2
  20. package/dist/index.js +261 -53
  21. package/dist/index.js.map +1 -1
  22. package/dist/kinds.d.cts +1 -1
  23. package/dist/kinds.d.ts +1 -1
  24. package/dist/memory.cjs +33 -5
  25. package/dist/memory.cjs.map +1 -1
  26. package/dist/memory.d.cts +1 -1
  27. package/dist/memory.d.ts +1 -1
  28. package/dist/memory.js +33 -5
  29. package/dist/memory.js.map +1 -1
  30. package/dist/{types-CHmV8GLx.d.cts → types-DyonaPQf.d.cts} +11 -1
  31. package/dist/{types-CHmV8GLx.d.ts → types-DyonaPQf.d.ts} +11 -1
  32. package/package.json +1 -1
  33. package/dist/chunk-B7C6NBBQ.js.map +0 -1
  34. /package/dist/{SheetView-SBLAFGTL.js.map → SheetView-F4CBWEOS.js.map} +0 -0
  35. /package/dist/{TextEditor-X2GSL4QM.js.map → TextEditor-ZY4B7YIF.js.map} +0 -0
  36. /package/dist/{chunk-ASTNK6WZ.js.map → chunk-TSB2QS56.js.map} +0 -0
  37. /package/dist/{chunk-FFXAOK4A.js.map → chunk-Z5STMOD6.js.map} +0 -0
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, RefObject } from 'react';
3
- import { L as Language, D as DocumentsHost, P as Place, a as DocumentFile, G as GuestHost, R as Rights } from './types-CHmV8GLx.cjs';
4
- export { C as Comment, b as DocumentKind, c as DocumentSummary, d as DocumentVersion, F as Fetch, e as GuestFile, f as GuestLink, g as LinkEntry, h as Person, S as Signature, i as SignatureMethod, j as Space } from './types-CHmV8GLx.cjs';
3
+ import { L as Language, D as DocumentsHost, P as Place, a as DocumentFile, G as GuestHost, R as Rights } from './types-DyonaPQf.cjs';
4
+ export { C as Comment, b as DocumentKind, c as DocumentSummary, d as DocumentVersion, F as Fetch, e as FolderPlace, f as GuestFile, g as GuestLink, h as LinkEntry, i as Person, S as Signature, j as SignatureMethod, k as Space } from './types-DyonaPQf.cjs';
5
5
  import { JSONContent } from '@tiptap/core';
6
6
  import { I as Img, S as Setup } from './write-BCI8yool.cjs';
7
7
  export { kindOf, kinds, matches, readable } from './kinds.cjs';
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, RefObject } from 'react';
3
- import { L as Language, D as DocumentsHost, P as Place, a as DocumentFile, G as GuestHost, R as Rights } from './types-CHmV8GLx.js';
4
- export { C as Comment, b as DocumentKind, c as DocumentSummary, d as DocumentVersion, F as Fetch, e as GuestFile, f as GuestLink, g as LinkEntry, h as Person, S as Signature, i as SignatureMethod, j as Space } from './types-CHmV8GLx.js';
3
+ import { L as Language, D as DocumentsHost, P as Place, a as DocumentFile, G as GuestHost, R as Rights } from './types-DyonaPQf.js';
4
+ export { C as Comment, b as DocumentKind, c as DocumentSummary, d as DocumentVersion, F as Fetch, e as FolderPlace, f as GuestFile, g as GuestLink, h as LinkEntry, i as Person, S as Signature, j as SignatureMethod, k as Space } from './types-DyonaPQf.js';
5
5
  import { JSONContent } from '@tiptap/core';
6
6
  import { I as Img, S as Setup } from './write-BCI8yool.js';
7
7
  export { kindOf, kinds, matches, readable } from './kinds.js';
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-2CA3HQTI.js";
8
8
  import {
9
9
  findNote
10
- } from "./chunk-FFXAOK4A.js";
10
+ } from "./chunk-Z5STMOD6.js";
11
11
  import {
12
12
  useLoad
13
13
  } from "./chunk-QDH7EZAF.js";
@@ -17,7 +17,7 @@ import {
17
17
  } from "./chunk-TDP6OJET.js";
18
18
  import {
19
19
  texts
20
- } from "./chunk-B7C6NBBQ.js";
20
+ } from "./chunk-BWU6FPPZ.js";
21
21
  import {
22
22
  escape,
23
23
  readDocx,
@@ -2412,8 +2412,8 @@ function PdfView({ bytes, t, language, worker, rights, host, documentId, onSaved
2412
2412
 
2413
2413
  // src/DocumentOverlay.tsx
2414
2414
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2415
- var TextEditor = lazy(() => import("./TextEditor-X2GSL4QM.js"));
2416
- var SheetView = lazy(() => import("./SheetView-SBLAFGTL.js"));
2415
+ var TextEditor = lazy(() => import("./TextEditor-ZY4B7YIF.js"));
2416
+ var SheetView = lazy(() => import("./SheetView-F4CBWEOS.js"));
2417
2417
  var icons = { docx: FileText, markdown: FileType, pdf: Files, sheet: FileSpreadsheet, slides: Presentation };
2418
2418
  var read = { view: true, comment: false, edit: false };
2419
2419
  var quiet = () => {
@@ -2539,6 +2539,9 @@ import {
2539
2539
  FileText as FileText4,
2540
2540
  FileType as FileType6,
2541
2541
  Files as Files3,
2542
+ Folder as Folder2,
2543
+ FolderInput,
2544
+ FolderPlus,
2542
2545
  FolderTree,
2543
2546
  History,
2544
2547
  Info,
@@ -3315,21 +3318,31 @@ import { useState as useState10 } from "react";
3315
3318
  import { ChevronDown as ChevronDown2, ChevronRight as ChevronRight2, FileSpreadsheet as FileSpreadsheet3, FileText as FileText3, FileType as FileType5, Files as Files2, Folder, Presentation as Presentation3 } from "lucide-react";
3316
3319
  import { Fragment as Fragment10, jsx as jsx11, jsxs as jsxs11 } from "react/jsx-runtime";
3317
3320
  var icons3 = { docx: FileText3, markdown: FileType5, pdf: Files2, sheet: FileSpreadsheet3, slides: Presentation3 };
3318
- function grow(items, names2, bySpace, other) {
3319
- const root = { key: "", name: "", folders: [], files: [], count: 0 };
3320
- for (const item of items) {
3321
- const path = [...bySpace ? [names2.get(item.spaceId) ?? other] : [], ...(item.folder ?? "").split("/").filter(Boolean)];
3322
- let at = root;
3323
- at.count++;
3324
- for (const part of path) {
3325
- const key = `${at.key}/${part}`;
3326
- let next = at.folders.find((f) => f.key === key);
3327
- if (!next) at.folders.push(next = { key, name: part, folders: [], files: [], count: 0 });
3328
- next.count++;
3329
- at = next;
3321
+ var dragged = "application/x-w100n-document";
3322
+ function grow(items, folders, names2, spaceId, other) {
3323
+ const root = { key: "", name: "", at: spaceId ? { spaceId, folder: "" } : null, folders: [], files: [], count: 0 };
3324
+ const step = (from, name, at, count) => {
3325
+ const key = `${from.key}/${name}`;
3326
+ let next = from.folders.find((f) => f.key === key);
3327
+ if (!next) from.folders.push(next = { key, name, at, folders: [], files: [], count: 0 });
3328
+ if (count) next.count++;
3329
+ return next;
3330
+ };
3331
+ const reach = (space, folder2, count) => {
3332
+ if (count) root.count++;
3333
+ let at = spaceId ? root : step(root, names2.get(space) ?? other, { spaceId: space, folder: "" }, count);
3334
+ let path = "";
3335
+ for (const part of folder2.split("/").filter(Boolean)) {
3336
+ path = path ? `${path}/${part}` : part;
3337
+ at = step(at, part, { spaceId: space, folder: path }, count);
3330
3338
  }
3331
- at.files.push(item);
3339
+ return at;
3340
+ };
3341
+ if (!spaceId) {
3342
+ for (const id of names2.keys()) if (folders.has(id)) reach(id, "", false);
3332
3343
  }
3344
+ for (const [space, paths] of folders) for (const path of paths) reach(space, path, false);
3345
+ for (const item of items) reach(item.spaceId, item.folder ?? "", true).files.push(item);
3333
3346
  const sort = (b) => {
3334
3347
  b.folders.sort((x, y) => x.name.localeCompare(y.name));
3335
3348
  b.files.sort((x, y) => x.name.localeCompare(y.name));
@@ -3345,29 +3358,84 @@ var remembered = () => {
3345
3358
  return /* @__PURE__ */ new Set();
3346
3359
  }
3347
3360
  };
3348
- function Tree({ items, names: names2, bySpace, current, t, onOpen, onMenu, onWarm }) {
3361
+ function Tree({ items, folders, names: names2, spaceId, current, t, edit, onOpen, onMenu, onFolderMenu, onMove, onEdit, onEditDone, onWarm }) {
3349
3362
  const [closed, setClosed] = useState10(remembered);
3363
+ const [over, setOver] = useState10(null);
3350
3364
  const flip = (key) => {
3351
3365
  const next = new Set(closed);
3352
3366
  if (!next.delete(key)) next.add(key);
3353
3367
  setClosed(next);
3354
3368
  localStorage.setItem("w100n-docs-closed", JSON.stringify([...next]));
3355
3369
  };
3370
+ const field = (pad, label) => /* @__PURE__ */ jsx11(
3371
+ "input",
3372
+ {
3373
+ className: "w100n-tree-row w100n-tree-input",
3374
+ style: { paddingLeft: pad },
3375
+ autoFocus: true,
3376
+ value: edit.text,
3377
+ "aria-label": label,
3378
+ onFocus: (e) => e.currentTarget.select(),
3379
+ onChange: (e) => onEdit(e.target.value),
3380
+ onBlur: onEditDone,
3381
+ onKeyDown: (e) => {
3382
+ if (e.key === "Enter") e.currentTarget.blur();
3383
+ if (e.key === "Escape") {
3384
+ e.stopPropagation();
3385
+ onEdit(null);
3386
+ }
3387
+ }
3388
+ }
3389
+ );
3390
+ const target = (b) => onMove && b.at ? {
3391
+ onDragOver: (e) => {
3392
+ if (!e.dataTransfer.types.includes(dragged)) return;
3393
+ e.preventDefault();
3394
+ e.stopPropagation();
3395
+ setOver(b.key);
3396
+ },
3397
+ onDragLeave: () => setOver(null),
3398
+ onDrop: (e) => {
3399
+ const id = e.dataTransfer.getData(dragged);
3400
+ setOver(null);
3401
+ if (!id) return;
3402
+ e.preventDefault();
3403
+ e.stopPropagation();
3404
+ onMove(id, b.at);
3405
+ }
3406
+ } : {};
3356
3407
  const branch = (b, depth) => /* @__PURE__ */ jsxs11(Fragment10, { children: [
3408
+ edit?.key === `new:${b.key}` && field(24 + depth * 16, t.folderName),
3357
3409
  b.folders.map((f) => {
3358
- const open = !closed.has(f.key);
3359
- return /* @__PURE__ */ jsxs11("div", { role: "group", "aria-label": f.name, children: [
3360
- /* @__PURE__ */ jsxs11("button", { type: "button", className: "w100n-tree-row", "aria-expanded": open, style: { paddingLeft: 8 + depth * 16 }, onClick: () => flip(f.key), children: [
3361
- open ? /* @__PURE__ */ jsx11(ChevronDown2, { "aria-hidden": true, className: "w100n-tree-fold" }) : /* @__PURE__ */ jsx11(ChevronRight2, { "aria-hidden": true, className: "w100n-tree-fold" }),
3362
- /* @__PURE__ */ jsx11(Folder, { "aria-hidden": true }),
3363
- /* @__PURE__ */ jsx11("span", { children: f.name }),
3364
- /* @__PURE__ */ jsx11("small", { children: f.count })
3365
- ] }),
3410
+ const open = !closed.has(f.key) || edit?.key === `new:${f.key}`;
3411
+ return /* @__PURE__ */ jsxs11("div", { role: "group", "aria-label": f.name, "data-over": over === f.key || void 0, ...target(f), children: [
3412
+ edit?.key === `dir:${f.key}` ? field(24 + depth * 16, t.renameFolder) : /* @__PURE__ */ jsxs11(
3413
+ "button",
3414
+ {
3415
+ type: "button",
3416
+ className: "w100n-tree-row",
3417
+ "aria-expanded": open,
3418
+ style: { paddingLeft: 24 + depth * 16 },
3419
+ onClick: () => flip(f.key),
3420
+ onContextMenu: onFolderMenu && f.at ? (e) => {
3421
+ e.preventDefault();
3422
+ e.stopPropagation();
3423
+ onFolderMenu(f.at, f.key, e);
3424
+ } : void 0,
3425
+ children: [
3426
+ open ? /* @__PURE__ */ jsx11(ChevronDown2, { "aria-hidden": true, className: "w100n-tree-fold" }) : /* @__PURE__ */ jsx11(ChevronRight2, { "aria-hidden": true, className: "w100n-tree-fold" }),
3427
+ /* @__PURE__ */ jsx11(Folder, { "aria-hidden": true }),
3428
+ /* @__PURE__ */ jsx11("span", { children: f.name }),
3429
+ f.count > 0 && /* @__PURE__ */ jsx11("small", { children: f.count })
3430
+ ]
3431
+ }
3432
+ ),
3366
3433
  open && branch(f, depth + 1)
3367
3434
  ] }, f.key);
3368
3435
  }),
3369
3436
  b.files.map((item) => {
3370
3437
  const Icon = icons3[item.kind];
3438
+ if (edit?.key === `file:${item.id}`) return /* @__PURE__ */ jsx11("div", { children: field(24 + depth * 16, t.rename) }, item.id);
3371
3439
  return /* @__PURE__ */ jsxs11(
3372
3440
  "button",
3373
3441
  {
@@ -3376,11 +3444,17 @@ function Tree({ items, names: names2, bySpace, current, t, onOpen, onMenu, onWar
3376
3444
  "aria-current": item.id === current,
3377
3445
  title: item.name,
3378
3446
  style: { paddingLeft: 24 + depth * 16 },
3447
+ draggable: !!onMove,
3448
+ onDragStart: (e) => {
3449
+ e.dataTransfer.setData(dragged, item.id);
3450
+ e.dataTransfer.effectAllowed = "move";
3451
+ },
3379
3452
  onClick: () => onOpen(item),
3380
3453
  onPointerEnter: () => onWarm(item),
3381
3454
  onPointerLeave: () => onWarm(null),
3382
3455
  onContextMenu: (e) => {
3383
3456
  e.preventDefault();
3457
+ e.stopPropagation();
3384
3458
  onMenu(item, e);
3385
3459
  },
3386
3460
  children: [
@@ -3393,13 +3467,27 @@ function Tree({ items, names: names2, bySpace, current, t, onOpen, onMenu, onWar
3393
3467
  );
3394
3468
  })
3395
3469
  ] });
3396
- return /* @__PURE__ */ jsx11("nav", { className: "w100n-tree", "aria-label": t.tree, children: branch(grow(items, names2, bySpace, t.elsewhere), 0) });
3470
+ const root = grow(items, folders, names2, spaceId, t.elsewhere);
3471
+ return /* @__PURE__ */ jsx11(
3472
+ "nav",
3473
+ {
3474
+ className: "w100n-tree",
3475
+ "aria-label": t.tree,
3476
+ "data-over": over === "" || void 0,
3477
+ ...target(root),
3478
+ onContextMenu: onFolderMenu && root.at ? (e) => {
3479
+ e.preventDefault();
3480
+ onFolderMenu(root.at, "", e);
3481
+ } : void 0,
3482
+ children: branch(root, 0)
3483
+ }
3484
+ );
3397
3485
  }
3398
3486
 
3399
3487
  // src/DocumentsWorkspace.tsx
3400
3488
  import { Fragment as Fragment11, jsx as jsx12, jsxs as jsxs12 } from "react/jsx-runtime";
3401
- var TextEditor2 = lazy2(() => import("./TextEditor-X2GSL4QM.js"));
3402
- var SheetView2 = lazy2(() => import("./SheetView-SBLAFGTL.js"));
3489
+ var TextEditor2 = lazy2(() => import("./TextEditor-ZY4B7YIF.js"));
3490
+ var SheetView2 = lazy2(() => import("./SheetView-F4CBWEOS.js"));
3403
3491
  var Compare = lazy2(() => import("./Compare-RHAUAKUJ.js"));
3404
3492
  var icons4 = { docx: FileText4, markdown: FileType6, pdf: Files3, sheet: FileSpreadsheet4, slides: Presentation4 };
3405
3493
  function DocumentsWorkspace({ host, language = "en", theme = "light", place, onPlace, start, end, aside, actions }) {
@@ -3474,16 +3562,27 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3474
3562
  return () => document.removeEventListener("pointerdown", close);
3475
3563
  }, [picking]);
3476
3564
  const [menu, setMenu] = useState11(null);
3565
+ const [spot2, setSpot] = useState11(null);
3566
+ const [edit, setEdit] = useState11(null);
3567
+ const popup = useRef6(null);
3568
+ useLayoutEffect3(() => {
3569
+ const el = popup.current;
3570
+ const at = menu ?? spot2;
3571
+ if (!el || !at) return;
3572
+ el.style.top = `${Math.max(8, Math.min(at.y, innerHeight - el.offsetHeight - 8))}px`;
3573
+ el.style.left = `${Math.max(8, Math.min(at.x, innerWidth - el.offsetWidth - 8))}px`;
3574
+ }, [menu, spot2]);
3477
3575
  const [naming, setNaming] = useState11(null);
3478
3576
  const [notice, setNotice] = useState11(null);
3479
3577
  const early = useRef6(/* @__PURE__ */ new Map());
3480
3578
  const hover = useRef6(0);
3481
3579
  useEffect6(() => {
3482
- if (!menu) return;
3580
+ if (!menu && !spot2) return;
3483
3581
  const close = (e) => {
3484
3582
  if (e.type === "pointerdown" && e.target.closest(".w100n-docs-context")) return;
3485
3583
  if (e.type === "keydown" && e.key !== "Escape") return;
3486
3584
  setMenu(null);
3585
+ setSpot(null);
3487
3586
  };
3488
3587
  document.addEventListener("pointerdown", close);
3489
3588
  window.addEventListener("keydown", close);
@@ -3493,7 +3592,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3493
3592
  window.removeEventListener("keydown", close);
3494
3593
  window.removeEventListener("scroll", close, true);
3495
3594
  };
3496
- }, [menu]);
3595
+ }, [menu, spot2]);
3497
3596
  const [tab, setTab] = useState11("outline");
3498
3597
  const [outline, setOutline] = useState11([]);
3499
3598
  const [reading, setReading] = useState11(null);
@@ -3520,11 +3619,17 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3520
3619
  const all2 = await host.spaces({ signal });
3521
3620
  return (await Promise.all(all2.map((item) => host.documents(item.id, { signal })))).flat();
3522
3621
  }, [host, spaceId]);
3622
+ const dirs = useLoad(async (signal) => {
3623
+ if (!host.folders) return /* @__PURE__ */ new Map();
3624
+ const ids = spaceId ? [spaceId] : (await host.spaces({ signal })).map((item) => item.id);
3625
+ return new Map(await Promise.all(ids.map(async (id) => [id, await host.folders(id, { signal })])));
3626
+ }, [host, spaceId]);
3523
3627
  useEffect6(() => {
3524
3628
  const sync = () => {
3525
3629
  if (document.visibilityState !== "visible") return;
3526
3630
  spaces.retry();
3527
3631
  list.retry();
3632
+ dirs.retry();
3528
3633
  };
3529
3634
  const timer = window.setInterval(sync, 3e4);
3530
3635
  window.addEventListener("focus", sync);
@@ -3688,8 +3793,8 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3688
3793
  clearTimeout(hover.current);
3689
3794
  hover.current = window.setTimeout(() => {
3690
3795
  if (item.id === here.documentId) return;
3691
- if (item.kind === "docx" || item.kind === "markdown") void import("./TextEditor-X2GSL4QM.js");
3692
- if (item.kind === "sheet") void import("./SheetView-SBLAFGTL.js");
3796
+ if (item.kind === "docx" || item.kind === "markdown") void import("./TextEditor-ZY4B7YIF.js");
3797
+ if (item.kind === "sheet") void import("./SheetView-F4CBWEOS.js");
3693
3798
  const kept2 = early.current.get(item.id);
3694
3799
  if (kept2 && Date.now() - kept2.at < 15e3 || item.size > 5e6) return;
3695
3800
  const next = { at: Date.now(), doc: host.document(item.id), bytes: host.content(item.id, null) };
@@ -3702,6 +3807,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3702
3807
  };
3703
3808
  const act = async (run2, done) => {
3704
3809
  setMenu(null);
3810
+ setSpot(null);
3705
3811
  setNotice(null);
3706
3812
  try {
3707
3813
  await run2();
@@ -3758,10 +3864,25 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3758
3864
  setSending("failed");
3759
3865
  }
3760
3866
  };
3867
+ const refresh = () => {
3868
+ list.retry();
3869
+ dirs.retry();
3870
+ };
3871
+ const moveTo = (item, to) => {
3872
+ if (item.spaceId === to.spaceId && (item.folder ?? "") === to.folder) return setMenu(null);
3873
+ void act(() => host.move(item.id, to)).then(refresh);
3874
+ };
3875
+ const folderNamed = (at) => at.folder.split("/").pop() || names2.get(at.spaceId) || t.topLevel;
3876
+ const commit = () => {
3877
+ if (!edit) return;
3878
+ setEdit(null);
3879
+ const text2 = edit.text.trim();
3880
+ if (text2) void edit.run(text2);
3881
+ };
3761
3882
  const notes = doc.data?.kind === "markdown" ? all.filter((item) => item.kind === "markdown" && item.spaceId === doc.data.spaceId) : [];
3762
- const note = async (name, show) => {
3883
+ const note = async (name, show, at) => {
3763
3884
  try {
3764
- const made = await host.create({ name: `${name}.md`, bytes: new TextEncoder().encode("").buffer, mimeType: "text/markdown", near: here.documentId ?? void 0 });
3885
+ const made = await host.create({ name: `${name}.md`, bytes: new TextEncoder().encode("").buffer, mimeType: "text/markdown", near: at ? void 0 : here.documentId ?? void 0, at });
3765
3886
  list.retry();
3766
3887
  if (show) opened(made);
3767
3888
  return made.id;
@@ -4038,28 +4159,22 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4038
4159
  kept?.id === here.documentId && kept.state === "failed" && /* @__PURE__ */ jsx12("span", { className: "w100n-docs-muted", role: "alert", children: t.templateFailed }),
4039
4160
  renamed === "failed" && /* @__PURE__ */ jsx12("span", { className: "w100n-docs-muted", children: t.renameFailed }),
4040
4161
  docbar && /* @__PURE__ */ jsx12("span", { ref: setStatusAt, className: "w100n-docs-status" }),
4041
- host.send && doc.data && !versionId && !doc.data.id.includes(":") && /* @__PURE__ */ jsxs12(
4162
+ host.send && doc.data && !versionId && !doc.data.id.includes(":") && /* @__PURE__ */ jsx12(
4042
4163
  "button",
4043
4164
  {
4044
4165
  type: "button",
4045
- className: "w100n-docs-action",
4166
+ className: "w100n-docs-action w100n-docs-square",
4046
4167
  "data-tone": "blue",
4047
4168
  "aria-label": t.sendChat,
4048
4169
  title: t.sendChat,
4049
4170
  onClick: () => host.send(doc.data.id),
4050
- children: [
4051
- /* @__PURE__ */ jsx12(Send, { "aria-hidden": true }),
4052
- /* @__PURE__ */ jsx12("span", { children: t.sendChat })
4053
- ]
4171
+ children: /* @__PURE__ */ jsx12(Send, { "aria-hidden": true })
4054
4172
  }
4055
4173
  ),
4056
- sharing && /* @__PURE__ */ jsxs12("button", { type: "button", className: "w100n-docs-action", "aria-label": t.share, title: t.share, onClick: () => {
4174
+ sharing && /* @__PURE__ */ jsx12("button", { type: "button", className: "w100n-docs-action w100n-docs-square", "aria-label": t.share, title: t.share, onClick: () => {
4057
4175
  setTab("sharing");
4058
4176
  side("panel", true);
4059
- }, children: [
4060
- /* @__PURE__ */ jsx12(Share2, { "aria-hidden": true }),
4061
- /* @__PURE__ */ jsx12("span", { children: t.share })
4062
- ] }),
4177
+ }, children: /* @__PURE__ */ jsx12(Share2, { "aria-hidden": true }) }),
4063
4178
  doc.data && !versionId && actions?.(doc.data),
4064
4179
  narrow && panelToggle,
4065
4180
  end && /* @__PURE__ */ jsx12("div", { className: "w100n-docs-end w100n-docs-slot", children: slot(end) })
@@ -4195,12 +4310,27 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4195
4310
  Tree,
4196
4311
  {
4197
4312
  items: shown,
4313
+ folders: query.trim() || picked.length ? /* @__PURE__ */ new Map() : dirs.data ?? /* @__PURE__ */ new Map(),
4198
4314
  names: names2,
4199
- bySpace: !spaceId,
4315
+ spaceId,
4200
4316
  current: here.documentId,
4201
4317
  t,
4318
+ edit,
4319
+ onEdit: (text2) => setEdit(text2 === null ? null : edit && { ...edit, text: text2 }),
4320
+ onEditDone: commit,
4202
4321
  onOpen: open,
4203
- onMenu: (item, e) => setMenu({ item, x: Math.min(e.clientX, innerWidth - 290), y: Math.min(e.clientY, innerHeight - 440), sure: false }),
4322
+ onMenu: (item, e) => {
4323
+ setSpot(null);
4324
+ setMenu({ item, x: Math.min(e.clientX, innerWidth - 290), y: Math.min(e.clientY, innerHeight - 440), sure: false });
4325
+ },
4326
+ onFolderMenu: host.create || host.makeFolder ? (at, key, e) => {
4327
+ setMenu(null);
4328
+ setSpot({ at, key, x: Math.min(e.clientX, innerWidth - 250), y: Math.min(e.clientY, innerHeight - 260), sure: false });
4329
+ } : void 0,
4330
+ onMove: host.move ? (id, to) => {
4331
+ const item = all.find((x) => x.id === id);
4332
+ if (item) moveTo(item, to);
4333
+ } : void 0,
4204
4334
  onWarm: (item) => item ? warm(item) : clearTimeout(hover.current)
4205
4335
  }
4206
4336
  ),
@@ -4434,14 +4564,28 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4434
4564
  setMaking(false);
4435
4565
  opened(made);
4436
4566
  } }),
4437
- menu && /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-menu w100n-docs-context", role: "menu", "aria-label": t.fileActions, style: { left: menu.x, top: menu.y }, children: [
4567
+ menu && /* @__PURE__ */ jsxs12("div", { ref: popup, className: "w100n-docs-menu w100n-docs-context", role: "menu", "aria-label": t.fileActions, style: { left: menu.x, top: menu.y }, children: [
4438
4568
  /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-context-head", children: [
4439
4569
  /* @__PURE__ */ jsx12("b", { children: menu.item.name }),
4440
4570
  /* @__PURE__ */ jsx12("small", { children: [t.kinds[menu.item.kind], size(menu.item.size), names2.get(menu.item.spaceId), menu.item.folder].filter(Boolean).join(" \xB7 ") }),
4441
4571
  menu.item.createdAt && /* @__PURE__ */ jsx12("small", { children: [t.createdOn.replace("{when}", date(menu.item.createdAt)), menu.item.createdBy?.name].filter(Boolean).join(" \xB7 ") }),
4442
4572
  /* @__PURE__ */ jsx12("small", { children: [t.updatedOn.replace("{when}", ago(menu.item.updatedAt)), menu.item.updatedBy?.name].filter(Boolean).join(" \xB7 ") })
4443
4573
  ] }),
4444
- menu.sure ? /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-context-ask", children: [
4574
+ menu.moving ? /* @__PURE__ */ jsx12("div", { className: "w100n-docs-context-list", children: ["", ...dirs.data.get(menu.item.spaceId)].map((folder2) => /* @__PURE__ */ jsxs12(
4575
+ "button",
4576
+ {
4577
+ type: "button",
4578
+ role: "menuitem",
4579
+ disabled: (menu.item.folder ?? "") === folder2,
4580
+ onClick: () => moveTo(menu.item, { spaceId: menu.item.spaceId, folder: folder2 }),
4581
+ style: { paddingLeft: 10 + 14 * (folder2 ? folder2.split("/").length : 0) },
4582
+ children: [
4583
+ /* @__PURE__ */ jsx12(Folder2, { "aria-hidden": true }),
4584
+ folder2 ? folder2.split("/").pop() : names2.get(menu.item.spaceId) ?? t.topLevel
4585
+ ]
4586
+ },
4587
+ folder2
4588
+ )) }) : menu.sure ? /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-context-ask", children: [
4445
4589
  /* @__PURE__ */ jsx12("p", { children: t.trashAsk.replace("{name}", menu.item.name) }),
4446
4590
  /* @__PURE__ */ jsxs12("span", { className: "w100n-pdf-dialog-end", children: [
4447
4591
  /* @__PURE__ */ jsx12("button", { type: "button", className: "w100n-pdf-link", onClick: () => setMenu({ ...menu, sure: false }), children: t.cancel }),
@@ -4478,12 +4622,18 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4478
4622
  ] }),
4479
4623
  /* @__PURE__ */ jsx12("hr", {}),
4480
4624
  host.rename && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => {
4625
+ const item = menu.item;
4481
4626
  setMenu(null);
4482
- setNaming({ id: menu.item.id, text: menu.item.name.replace(/\.[^.]+$/, "") });
4627
+ if (shape2 === "tree") setEdit({ key: `file:${item.id}`, text: item.name.replace(/\.[^.]+$/, ""), run: (text2) => retitle(item, text2) });
4628
+ else setNaming({ id: item.id, text: item.name.replace(/\.[^.]+$/, "") });
4483
4629
  }, children: [
4484
4630
  /* @__PURE__ */ jsx12(Pencil, { "aria-hidden": true }),
4485
4631
  t.rename
4486
4632
  ] }),
4633
+ host.move && dirs.data?.has(menu.item.spaceId) && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", "aria-haspopup": "menu", onClick: () => setMenu({ ...menu, moving: true }), children: [
4634
+ /* @__PURE__ */ jsx12(FolderInput, { "aria-hidden": true }),
4635
+ t.moveTo
4636
+ ] }),
4487
4637
  host.create && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => void act(async () => copy(await host.document(menu.item.id))), children: [
4488
4638
  /* @__PURE__ */ jsx12(Copy3, { "aria-hidden": true }),
4489
4639
  t.makeCopy
@@ -4514,6 +4664,64 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4514
4664
  ] })
4515
4665
  ] })
4516
4666
  ] }),
4667
+ spot2 && /* @__PURE__ */ jsxs12("div", { ref: popup, className: "w100n-docs-menu w100n-docs-context", role: "menu", "aria-label": t.folderActions, style: { left: spot2.x, top: spot2.y }, children: [
4668
+ /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-context-head", children: [
4669
+ /* @__PURE__ */ jsx12("b", { children: folderNamed(spot2.at) }),
4670
+ spot2.at.folder && /* @__PURE__ */ jsx12("small", { children: [names2.get(spot2.at.spaceId), ...spot2.at.folder.split("/").slice(0, -1)].filter(Boolean).join(" / ") })
4671
+ ] }),
4672
+ spot2.sure ? /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-context-ask", children: [
4673
+ /* @__PURE__ */ jsx12("p", { children: t.folderTrashAsk.replace("{name}", folderNamed(spot2.at)) }),
4674
+ /* @__PURE__ */ jsxs12("span", { className: "w100n-pdf-dialog-end", children: [
4675
+ /* @__PURE__ */ jsx12("button", { type: "button", className: "w100n-pdf-link", onClick: () => setSpot({ ...spot2, sure: false }), children: t.cancel }),
4676
+ /* @__PURE__ */ jsxs12("button", { type: "button", className: "w100n-docs-action", "data-tone": "red", onClick: () => {
4677
+ const at = spot2.at;
4678
+ const inside2 = doc.data && doc.data.spaceId === at.spaceId && `${doc.data.folder ?? ""}/`.startsWith(`${at.folder}/`);
4679
+ void act(() => host.removeFolder(at), t.trashed).then(() => {
4680
+ refresh();
4681
+ if (inside2) go({ spaceId: here.spaceId, documentId: null });
4682
+ });
4683
+ }, children: [
4684
+ /* @__PURE__ */ jsx12(Trash24, { "aria-hidden": true }),
4685
+ t.trash
4686
+ ] })
4687
+ ] })
4688
+ ] }) : /* @__PURE__ */ jsxs12(Fragment11, { children: [
4689
+ host.create && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => {
4690
+ const at = spot2.at;
4691
+ setSpot(null);
4692
+ void note(t.untitled, true, at);
4693
+ }, children: [
4694
+ /* @__PURE__ */ jsx12(FilePlus, { "aria-hidden": true }),
4695
+ t.newNoteHere
4696
+ ] }),
4697
+ host.makeFolder && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => {
4698
+ const at = spot2.at;
4699
+ setSpot(null);
4700
+ setEdit({ key: `new:${spot2.key}`, text: t.newFolder, run: (name) => act(() => host.makeFolder(at, name)).then(refresh) });
4701
+ }, children: [
4702
+ /* @__PURE__ */ jsx12(FolderPlus, { "aria-hidden": true }),
4703
+ t.newFolder
4704
+ ] }),
4705
+ spot2.at.folder && host.renameFolder && /* @__PURE__ */ jsxs12(Fragment11, { children: [
4706
+ /* @__PURE__ */ jsx12("hr", {}),
4707
+ /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => {
4708
+ const at = spot2.at;
4709
+ setSpot(null);
4710
+ setEdit({ key: `dir:${spot2.key}`, text: folderNamed(at), run: (name) => name === folderNamed(at) ? Promise.resolve() : act(() => host.renameFolder(at, name)).then(refresh) });
4711
+ }, children: [
4712
+ /* @__PURE__ */ jsx12(Pencil, { "aria-hidden": true }),
4713
+ t.renameFolder
4714
+ ] })
4715
+ ] }),
4716
+ spot2.at.folder && host.removeFolder && /* @__PURE__ */ jsxs12(Fragment11, { children: [
4717
+ /* @__PURE__ */ jsx12("hr", {}),
4718
+ /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", "data-tone": "red", onClick: () => setSpot({ ...spot2, sure: true }), children: [
4719
+ /* @__PURE__ */ jsx12(Trash24, { "aria-hidden": true }),
4720
+ t.trashFolder
4721
+ ] })
4722
+ ] })
4723
+ ] })
4724
+ ] }),
4517
4725
  dialog
4518
4726
  ] });
4519
4727
  }
@@ -4532,8 +4740,8 @@ function FilePreview({ url, name, mimeType, size = 0, bytes, pdfWorker }) {
4532
4740
  import { lazy as lazy3, Suspense as Suspense3, useRef as useRef7, useState as useState13 } from "react";
4533
4741
  import { Ban as Ban2, Download as Download4, Eye as Eye2, FileDown as FileDown2, FileSpreadsheet as FileSpreadsheet5, FileText as FileText5, FileType as FileType7, Files as Files4, Lock as Lock2, Presentation as Presentation5, UserRound } from "lucide-react";
4534
4742
  import { Fragment as Fragment12, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
4535
- var TextEditor3 = lazy3(() => import("./TextEditor-X2GSL4QM.js"));
4536
- var SheetView3 = lazy3(() => import("./SheetView-SBLAFGTL.js"));
4743
+ var TextEditor3 = lazy3(() => import("./TextEditor-ZY4B7YIF.js"));
4744
+ var SheetView3 = lazy3(() => import("./SheetView-F4CBWEOS.js"));
4537
4745
  var icons5 = { docx: FileText5, markdown: FileType7, pdf: Files4, sheet: FileSpreadsheet5, slides: Presentation5 };
4538
4746
  var GuestRefused = class extends Error {
4539
4747
  constructor(reason, file = "", sharedBy = "") {