@w100n/documents 0.17.0 → 0.18.0

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-43JDIP7D.js} +4 -4
  2. package/dist/{TextEditor-X2GSL4QM.js → TextEditor-CYS4U5XA.js} +5 -5
  3. package/dist/{chunk-B7C6NBBQ.js → chunk-BWU6FPPZ.js} +28 -1
  4. package/dist/chunk-BWU6FPPZ.js.map +1 -0
  5. package/dist/{chunk-ASTNK6WZ.js → chunk-DATYTA4H.js} +2 -2
  6. package/dist/{chunk-FFXAOK4A.js → chunk-Z5STMOD6.js} +2 -2
  7. package/dist/{chunk-A6AHJCEK.js → chunk-ZCSHH24C.js} +3 -3
  8. package/dist/{chunk-A6AHJCEK.js.map → chunk-ZCSHH24C.js.map} +1 -1
  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 +263 -33
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.css +17 -0
  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 +247 -41
  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-43JDIP7D.js.map} +0 -0
  35. /package/dist/{TextEditor-X2GSL4QM.js.map → TextEditor-CYS4U5XA.js.map} +0 -0
  36. /package/dist/{chunk-ASTNK6WZ.js.map → chunk-DATYTA4H.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-CYS4U5XA.js"));
2416
+ var SheetView = lazy(() => import("./SheetView-43JDIP7D.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-CYS4U5XA.js"));
3490
+ var SheetView2 = lazy2(() => import("./SheetView-43JDIP7D.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,19 @@ 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);
3477
3567
  const [naming, setNaming] = useState11(null);
3478
3568
  const [notice, setNotice] = useState11(null);
3479
3569
  const early = useRef6(/* @__PURE__ */ new Map());
3480
3570
  const hover = useRef6(0);
3481
3571
  useEffect6(() => {
3482
- if (!menu) return;
3572
+ if (!menu && !spot2) return;
3483
3573
  const close = (e) => {
3484
3574
  if (e.type === "pointerdown" && e.target.closest(".w100n-docs-context")) return;
3485
3575
  if (e.type === "keydown" && e.key !== "Escape") return;
3486
3576
  setMenu(null);
3577
+ setSpot(null);
3487
3578
  };
3488
3579
  document.addEventListener("pointerdown", close);
3489
3580
  window.addEventListener("keydown", close);
@@ -3493,7 +3584,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3493
3584
  window.removeEventListener("keydown", close);
3494
3585
  window.removeEventListener("scroll", close, true);
3495
3586
  };
3496
- }, [menu]);
3587
+ }, [menu, spot2]);
3497
3588
  const [tab, setTab] = useState11("outline");
3498
3589
  const [outline, setOutline] = useState11([]);
3499
3590
  const [reading, setReading] = useState11(null);
@@ -3520,11 +3611,17 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3520
3611
  const all2 = await host.spaces({ signal });
3521
3612
  return (await Promise.all(all2.map((item) => host.documents(item.id, { signal })))).flat();
3522
3613
  }, [host, spaceId]);
3614
+ const dirs = useLoad(async (signal) => {
3615
+ if (!host.folders) return /* @__PURE__ */ new Map();
3616
+ const ids = spaceId ? [spaceId] : (await host.spaces({ signal })).map((item) => item.id);
3617
+ return new Map(await Promise.all(ids.map(async (id) => [id, await host.folders(id, { signal })])));
3618
+ }, [host, spaceId]);
3523
3619
  useEffect6(() => {
3524
3620
  const sync = () => {
3525
3621
  if (document.visibilityState !== "visible") return;
3526
3622
  spaces.retry();
3527
3623
  list.retry();
3624
+ dirs.retry();
3528
3625
  };
3529
3626
  const timer = window.setInterval(sync, 3e4);
3530
3627
  window.addEventListener("focus", sync);
@@ -3688,8 +3785,8 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3688
3785
  clearTimeout(hover.current);
3689
3786
  hover.current = window.setTimeout(() => {
3690
3787
  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");
3788
+ if (item.kind === "docx" || item.kind === "markdown") void import("./TextEditor-CYS4U5XA.js");
3789
+ if (item.kind === "sheet") void import("./SheetView-43JDIP7D.js");
3693
3790
  const kept2 = early.current.get(item.id);
3694
3791
  if (kept2 && Date.now() - kept2.at < 15e3 || item.size > 5e6) return;
3695
3792
  const next = { at: Date.now(), doc: host.document(item.id), bytes: host.content(item.id, null) };
@@ -3702,6 +3799,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3702
3799
  };
3703
3800
  const act = async (run2, done) => {
3704
3801
  setMenu(null);
3802
+ setSpot(null);
3705
3803
  setNotice(null);
3706
3804
  try {
3707
3805
  await run2();
@@ -3758,10 +3856,25 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3758
3856
  setSending("failed");
3759
3857
  }
3760
3858
  };
3859
+ const refresh = () => {
3860
+ list.retry();
3861
+ dirs.retry();
3862
+ };
3863
+ const moveTo = (item, to) => {
3864
+ if (item.spaceId === to.spaceId && (item.folder ?? "") === to.folder) return setMenu(null);
3865
+ void act(() => host.move(item.id, to)).then(refresh);
3866
+ };
3867
+ const folderNamed = (at) => at.folder.split("/").pop() || names2.get(at.spaceId) || t.topLevel;
3868
+ const commit = () => {
3869
+ if (!edit) return;
3870
+ setEdit(null);
3871
+ const text2 = edit.text.trim();
3872
+ if (text2) void edit.run(text2);
3873
+ };
3761
3874
  const notes = doc.data?.kind === "markdown" ? all.filter((item) => item.kind === "markdown" && item.spaceId === doc.data.spaceId) : [];
3762
- const note = async (name, show) => {
3875
+ const note = async (name, show, at) => {
3763
3876
  try {
3764
- const made = await host.create({ name: `${name}.md`, bytes: new TextEncoder().encode("").buffer, mimeType: "text/markdown", near: here.documentId ?? void 0 });
3877
+ 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
3878
  list.retry();
3766
3879
  if (show) opened(made);
3767
3880
  return made.id;
@@ -4195,12 +4308,27 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4195
4308
  Tree,
4196
4309
  {
4197
4310
  items: shown,
4311
+ folders: query.trim() || picked.length ? /* @__PURE__ */ new Map() : dirs.data ?? /* @__PURE__ */ new Map(),
4198
4312
  names: names2,
4199
- bySpace: !spaceId,
4313
+ spaceId,
4200
4314
  current: here.documentId,
4201
4315
  t,
4316
+ edit,
4317
+ onEdit: (text2) => setEdit(text2 === null ? null : edit && { ...edit, text: text2 }),
4318
+ onEditDone: commit,
4202
4319
  onOpen: open,
4203
- onMenu: (item, e) => setMenu({ item, x: Math.min(e.clientX, innerWidth - 290), y: Math.min(e.clientY, innerHeight - 440), sure: false }),
4320
+ onMenu: (item, e) => {
4321
+ setSpot(null);
4322
+ setMenu({ item, x: Math.min(e.clientX, innerWidth - 290), y: Math.min(e.clientY, innerHeight - 440), sure: false });
4323
+ },
4324
+ onFolderMenu: host.create || host.makeFolder ? (at, key, e) => {
4325
+ setMenu(null);
4326
+ setSpot({ at, key, x: Math.min(e.clientX, innerWidth - 250), y: Math.min(e.clientY, innerHeight - 260), sure: false });
4327
+ } : void 0,
4328
+ onMove: host.move ? (id, to) => {
4329
+ const item = all.find((x) => x.id === id);
4330
+ if (item) moveTo(item, to);
4331
+ } : void 0,
4204
4332
  onWarm: (item) => item ? warm(item) : clearTimeout(hover.current)
4205
4333
  }
4206
4334
  ),
@@ -4441,7 +4569,21 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4441
4569
  menu.item.createdAt && /* @__PURE__ */ jsx12("small", { children: [t.createdOn.replace("{when}", date(menu.item.createdAt)), menu.item.createdBy?.name].filter(Boolean).join(" \xB7 ") }),
4442
4570
  /* @__PURE__ */ jsx12("small", { children: [t.updatedOn.replace("{when}", ago(menu.item.updatedAt)), menu.item.updatedBy?.name].filter(Boolean).join(" \xB7 ") })
4443
4571
  ] }),
4444
- menu.sure ? /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-context-ask", children: [
4572
+ menu.moving ? /* @__PURE__ */ jsx12("div", { className: "w100n-docs-context-list", children: ["", ...dirs.data.get(menu.item.spaceId)].map((folder2) => /* @__PURE__ */ jsxs12(
4573
+ "button",
4574
+ {
4575
+ type: "button",
4576
+ role: "menuitem",
4577
+ disabled: (menu.item.folder ?? "") === folder2,
4578
+ onClick: () => moveTo(menu.item, { spaceId: menu.item.spaceId, folder: folder2 }),
4579
+ style: { paddingLeft: 10 + 14 * (folder2 ? folder2.split("/").length : 0) },
4580
+ children: [
4581
+ /* @__PURE__ */ jsx12(Folder2, { "aria-hidden": true }),
4582
+ folder2 ? folder2.split("/").pop() : names2.get(menu.item.spaceId) ?? t.topLevel
4583
+ ]
4584
+ },
4585
+ folder2
4586
+ )) }) : menu.sure ? /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-context-ask", children: [
4445
4587
  /* @__PURE__ */ jsx12("p", { children: t.trashAsk.replace("{name}", menu.item.name) }),
4446
4588
  /* @__PURE__ */ jsxs12("span", { className: "w100n-pdf-dialog-end", children: [
4447
4589
  /* @__PURE__ */ jsx12("button", { type: "button", className: "w100n-pdf-link", onClick: () => setMenu({ ...menu, sure: false }), children: t.cancel }),
@@ -4478,12 +4620,18 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4478
4620
  ] }),
4479
4621
  /* @__PURE__ */ jsx12("hr", {}),
4480
4622
  host.rename && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => {
4623
+ const item = menu.item;
4481
4624
  setMenu(null);
4482
- setNaming({ id: menu.item.id, text: menu.item.name.replace(/\.[^.]+$/, "") });
4625
+ if (shape2 === "tree") setEdit({ key: `file:${item.id}`, text: item.name.replace(/\.[^.]+$/, ""), run: (text2) => retitle(item, text2) });
4626
+ else setNaming({ id: item.id, text: item.name.replace(/\.[^.]+$/, "") });
4483
4627
  }, children: [
4484
4628
  /* @__PURE__ */ jsx12(Pencil, { "aria-hidden": true }),
4485
4629
  t.rename
4486
4630
  ] }),
4631
+ host.move && dirs.data?.has(menu.item.spaceId) && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", "aria-haspopup": "menu", onClick: () => setMenu({ ...menu, moving: true }), children: [
4632
+ /* @__PURE__ */ jsx12(FolderInput, { "aria-hidden": true }),
4633
+ t.moveTo
4634
+ ] }),
4487
4635
  host.create && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => void act(async () => copy(await host.document(menu.item.id))), children: [
4488
4636
  /* @__PURE__ */ jsx12(Copy3, { "aria-hidden": true }),
4489
4637
  t.makeCopy
@@ -4514,6 +4662,64 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4514
4662
  ] })
4515
4663
  ] })
4516
4664
  ] }),
4665
+ spot2 && /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-menu w100n-docs-context", role: "menu", "aria-label": t.folderActions, style: { left: spot2.x, top: spot2.y }, children: [
4666
+ /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-context-head", children: [
4667
+ /* @__PURE__ */ jsx12("b", { children: folderNamed(spot2.at) }),
4668
+ spot2.at.folder && /* @__PURE__ */ jsx12("small", { children: [names2.get(spot2.at.spaceId), ...spot2.at.folder.split("/").slice(0, -1)].filter(Boolean).join(" / ") })
4669
+ ] }),
4670
+ spot2.sure ? /* @__PURE__ */ jsxs12("div", { className: "w100n-docs-context-ask", children: [
4671
+ /* @__PURE__ */ jsx12("p", { children: t.folderTrashAsk.replace("{name}", folderNamed(spot2.at)) }),
4672
+ /* @__PURE__ */ jsxs12("span", { className: "w100n-pdf-dialog-end", children: [
4673
+ /* @__PURE__ */ jsx12("button", { type: "button", className: "w100n-pdf-link", onClick: () => setSpot({ ...spot2, sure: false }), children: t.cancel }),
4674
+ /* @__PURE__ */ jsxs12("button", { type: "button", className: "w100n-docs-action", "data-tone": "red", onClick: () => {
4675
+ const at = spot2.at;
4676
+ const inside2 = doc.data && doc.data.spaceId === at.spaceId && `${doc.data.folder ?? ""}/`.startsWith(`${at.folder}/`);
4677
+ void act(() => host.removeFolder(at), t.trashed).then(() => {
4678
+ refresh();
4679
+ if (inside2) go({ spaceId: here.spaceId, documentId: null });
4680
+ });
4681
+ }, children: [
4682
+ /* @__PURE__ */ jsx12(Trash24, { "aria-hidden": true }),
4683
+ t.trash
4684
+ ] })
4685
+ ] })
4686
+ ] }) : /* @__PURE__ */ jsxs12(Fragment11, { children: [
4687
+ host.create && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => {
4688
+ const at = spot2.at;
4689
+ setSpot(null);
4690
+ void note(t.untitled, true, at);
4691
+ }, children: [
4692
+ /* @__PURE__ */ jsx12(FilePlus, { "aria-hidden": true }),
4693
+ t.newNoteHere
4694
+ ] }),
4695
+ host.makeFolder && /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => {
4696
+ const at = spot2.at;
4697
+ setSpot(null);
4698
+ setEdit({ key: `new:${spot2.key}`, text: t.newFolder, run: (name) => act(() => host.makeFolder(at, name)).then(refresh) });
4699
+ }, children: [
4700
+ /* @__PURE__ */ jsx12(FolderPlus, { "aria-hidden": true }),
4701
+ t.newFolder
4702
+ ] }),
4703
+ spot2.at.folder && host.renameFolder && /* @__PURE__ */ jsxs12(Fragment11, { children: [
4704
+ /* @__PURE__ */ jsx12("hr", {}),
4705
+ /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", onClick: () => {
4706
+ const at = spot2.at;
4707
+ setSpot(null);
4708
+ setEdit({ key: `dir:${spot2.key}`, text: folderNamed(at), run: (name) => name === folderNamed(at) ? Promise.resolve() : act(() => host.renameFolder(at, name)).then(refresh) });
4709
+ }, children: [
4710
+ /* @__PURE__ */ jsx12(Pencil, { "aria-hidden": true }),
4711
+ t.renameFolder
4712
+ ] })
4713
+ ] }),
4714
+ spot2.at.folder && host.removeFolder && /* @__PURE__ */ jsxs12(Fragment11, { children: [
4715
+ /* @__PURE__ */ jsx12("hr", {}),
4716
+ /* @__PURE__ */ jsxs12("button", { type: "button", role: "menuitem", "data-tone": "red", onClick: () => setSpot({ ...spot2, sure: true }), children: [
4717
+ /* @__PURE__ */ jsx12(Trash24, { "aria-hidden": true }),
4718
+ t.trashFolder
4719
+ ] })
4720
+ ] })
4721
+ ] })
4722
+ ] }),
4517
4723
  dialog
4518
4724
  ] });
4519
4725
  }
@@ -4532,8 +4738,8 @@ function FilePreview({ url, name, mimeType, size = 0, bytes, pdfWorker }) {
4532
4738
  import { lazy as lazy3, Suspense as Suspense3, useRef as useRef7, useState as useState13 } from "react";
4533
4739
  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
4740
  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"));
4741
+ var TextEditor3 = lazy3(() => import("./TextEditor-CYS4U5XA.js"));
4742
+ var SheetView3 = lazy3(() => import("./SheetView-43JDIP7D.js"));
4537
4743
  var icons5 = { docx: FileText5, markdown: FileType7, pdf: Files4, sheet: FileSpreadsheet5, slides: Presentation5 };
4538
4744
  var GuestRefused = class extends Error {
4539
4745
  constructor(reason, file = "", sharedBy = "") {