@w100n/documents 0.19.0 → 0.20.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.
package/dist/index.d.cts CHANGED
@@ -2,6 +2,7 @@ import * as react from 'react';
2
2
  import { ReactNode, RefObject } from 'react';
3
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
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
+ import { LucideIcon } from 'lucide-react';
5
6
  import { JSONContent } from '@tiptap/core';
6
7
  import { I as Img, S as Setup } from './write-BCI8yool.cjs';
7
8
  export { kindOf, kinds, matches, readable } from './kinds.cjs';
@@ -43,8 +44,21 @@ declare function DocumentOverlay({ source, name, mimeType, info, download, actio
43
44
  documentId?: string;
44
45
  }): react.ReactPortal;
45
46
 
47
+ type Spot$1 = {
48
+ sheet?: string;
49
+ range?: string;
50
+ quote?: string;
51
+ };
52
+ type PanelTab = {
53
+ id: string;
54
+ icon: LucideIcon;
55
+ label: string;
56
+ count?: number;
57
+ wide?: boolean;
58
+ body: ReactNode;
59
+ };
46
60
  type Slot = ReactNode | ((leave: (then: () => void) => void) => ReactNode);
47
- declare function DocumentsWorkspace({ host, language, theme, place, onPlace, start, end, aside, actions }: {
61
+ declare function DocumentsWorkspace({ host, language, theme, place, onPlace, start, end, aside, actions, tabs }: {
48
62
  host: DocumentsHost;
49
63
  language?: Language;
50
64
  theme?: 'light' | 'dark';
@@ -54,6 +68,7 @@ declare function DocumentsWorkspace({ host, language, theme, place, onPlace, sta
54
68
  end?: Slot;
55
69
  aside?: (doc: DocumentFile) => ReactNode;
56
70
  actions?: (doc: DocumentFile) => ReactNode;
71
+ tabs?: (doc: DocumentFile, spot: Spot$1 | null) => PanelTab[];
57
72
  }): react.JSX.Element;
58
73
 
59
74
  declare function FilePreview({ url, name, mimeType, size, bytes, pdfWorker }: {
@@ -176,4 +191,4 @@ declare function SlidesView({ html, name, rights, language, theme, baseUrl, scri
176
191
  guard?: Guard;
177
192
  }): react.JSX.Element;
178
193
 
179
- export { type Deck, type DeckKind, DocumentFile, DocumentOverlay, DocumentsHost, DocumentsWorkspace, type DocxModel, FilePreview, GuestDocument, GuestHost, type GuestRefusal, GuestRefused, Language, Place, PreviewCard, Rights, type Slide, SlidesView, readDeck, readDocx, writeDeck, writeDocx };
194
+ export { type Deck, type DeckKind, DocumentFile, DocumentOverlay, DocumentsHost, DocumentsWorkspace, type DocxModel, FilePreview, GuestDocument, GuestHost, type GuestRefusal, GuestRefused, Language, type PanelTab, Place, PreviewCard, Rights, type Slide, SlidesView, type Spot$1 as Spot, readDeck, readDocx, writeDeck, writeDocx };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import * as react from 'react';
2
2
  import { ReactNode, RefObject } from 'react';
3
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
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
+ import { LucideIcon } from 'lucide-react';
5
6
  import { JSONContent } from '@tiptap/core';
6
7
  import { I as Img, S as Setup } from './write-BCI8yool.js';
7
8
  export { kindOf, kinds, matches, readable } from './kinds.js';
@@ -43,8 +44,21 @@ declare function DocumentOverlay({ source, name, mimeType, info, download, actio
43
44
  documentId?: string;
44
45
  }): react.ReactPortal;
45
46
 
47
+ type Spot$1 = {
48
+ sheet?: string;
49
+ range?: string;
50
+ quote?: string;
51
+ };
52
+ type PanelTab = {
53
+ id: string;
54
+ icon: LucideIcon;
55
+ label: string;
56
+ count?: number;
57
+ wide?: boolean;
58
+ body: ReactNode;
59
+ };
46
60
  type Slot = ReactNode | ((leave: (then: () => void) => void) => ReactNode);
47
- declare function DocumentsWorkspace({ host, language, theme, place, onPlace, start, end, aside, actions }: {
61
+ declare function DocumentsWorkspace({ host, language, theme, place, onPlace, start, end, aside, actions, tabs }: {
48
62
  host: DocumentsHost;
49
63
  language?: Language;
50
64
  theme?: 'light' | 'dark';
@@ -54,6 +68,7 @@ declare function DocumentsWorkspace({ host, language, theme, place, onPlace, sta
54
68
  end?: Slot;
55
69
  aside?: (doc: DocumentFile) => ReactNode;
56
70
  actions?: (doc: DocumentFile) => ReactNode;
71
+ tabs?: (doc: DocumentFile, spot: Spot$1 | null) => PanelTab[];
57
72
  }): react.JSX.Element;
58
73
 
59
74
  declare function FilePreview({ url, name, mimeType, size, bytes, pdfWorker }: {
@@ -176,4 +191,4 @@ declare function SlidesView({ html, name, rights, language, theme, baseUrl, scri
176
191
  guard?: Guard;
177
192
  }): react.JSX.Element;
178
193
 
179
- export { type Deck, type DeckKind, DocumentFile, DocumentOverlay, DocumentsHost, DocumentsWorkspace, type DocxModel, FilePreview, GuestDocument, GuestHost, type GuestRefusal, GuestRefused, Language, Place, PreviewCard, Rights, type Slide, SlidesView, readDeck, readDocx, writeDeck, writeDocx };
194
+ export { type Deck, type DeckKind, DocumentFile, DocumentOverlay, DocumentsHost, DocumentsWorkspace, type DocxModel, FilePreview, GuestDocument, GuestHost, type GuestRefusal, GuestRefused, Language, type PanelTab, Place, PreviewCard, Rights, type Slide, SlidesView, type Spot$1 as Spot, readDeck, readDocx, writeDeck, writeDocx };
package/dist/index.js CHANGED
@@ -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-Z4KSBLBV.js"));
2416
- var SheetView = lazy(() => import("./SheetView-PUSRW7W2.js"));
2415
+ var TextEditor = lazy(() => import("./TextEditor-NDWZUYDA.js"));
2416
+ var SheetView = lazy(() => import("./SheetView-Q6K3UGVP.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 = () => {
@@ -3461,7 +3461,7 @@ function Tree({ items, folders, names: names2, spaceId, current, t, edit, hits,
3461
3461
  e.dataTransfer.effectAllowed = "move";
3462
3462
  },
3463
3463
  onClick: () => onOpen(item),
3464
- onPointerEnter: (e) => onWarm(item, e.pointerType === "mouse" ? e.currentTarget.getBoundingClientRect() : void 0),
3464
+ onPointerEnter: () => onWarm(item),
3465
3465
  onPointerLeave: () => onWarm(null),
3466
3466
  onContextMenu: (e) => {
3467
3467
  e.preventDefault();
@@ -3501,10 +3501,10 @@ function Tree({ items, folders, names: names2, spaceId, current, t, edit, hits,
3501
3501
 
3502
3502
  // src/DocumentsWorkspace.tsx
3503
3503
  import { Fragment as Fragment11, jsx as jsx13, jsxs as jsxs13 } from "react/jsx-runtime";
3504
- var TextEditor2 = lazy2(() => import("./TextEditor-Z4KSBLBV.js"));
3505
- var SheetView2 = lazy2(() => import("./SheetView-PUSRW7W2.js"));
3504
+ var TextEditor2 = lazy2(() => import("./TextEditor-NDWZUYDA.js"));
3505
+ var SheetView2 = lazy2(() => import("./SheetView-Q6K3UGVP.js"));
3506
3506
  var Compare = lazy2(() => import("./Compare-RHAUAKUJ.js"));
3507
- function DocumentsWorkspace({ host, language = "en", theme = "light", place, onPlace, start, end, aside, actions }) {
3507
+ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onPlace, start, end, aside, actions, tabs }) {
3508
3508
  const t = texts[language];
3509
3509
  const [own, setOwn] = useState11({ spaceId: null, documentId: null });
3510
3510
  const here = place ?? own;
@@ -3588,8 +3588,6 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3588
3588
  const [notice, setNotice] = useState11(null);
3589
3589
  const early = useRef6(/* @__PURE__ */ new Map());
3590
3590
  const hover = useRef6(0);
3591
- const peeking = useRef6(0);
3592
- const [peek, setPeek] = useState11(null);
3593
3591
  useEffect6(() => {
3594
3592
  if (!menu && !spot2) return;
3595
3593
  const close = (e) => {
@@ -3608,6 +3606,8 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3608
3606
  };
3609
3607
  }, [menu, spot2]);
3610
3608
  const [tab, setTab] = useState11("outline");
3609
+ const [heard, setHeard] = useState11(0);
3610
+ const [aim, setAim] = useState11(null);
3611
3611
  const [outline, setOutline] = useState11([]);
3612
3612
  const [reading, setReading] = useState11(null);
3613
3613
  const [hunt, setHunt] = useState11("");
@@ -3724,6 +3724,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3724
3724
  setHunt("");
3725
3725
  setFold({});
3726
3726
  setTab("outline");
3727
+ setAim(null);
3727
3728
  go({ spaceId: here.spaceId, documentId: item.id });
3728
3729
  if (narrow) setListOpen(false);
3729
3730
  });
@@ -3802,14 +3803,12 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3802
3803
  setKept({ id: file.id, state: "failed" });
3803
3804
  }
3804
3805
  };
3805
- const warm = (item, at) => {
3806
- clearTimeout(peeking.current);
3807
- if (at) peeking.current = window.setTimeout(() => setPeek({ item, x: Math.min(at.right + 8, innerWidth - 300), y: Math.min(at.top, innerHeight - 300) }), 500);
3806
+ const warm = (item) => {
3808
3807
  clearTimeout(hover.current);
3809
3808
  hover.current = window.setTimeout(() => {
3810
3809
  if (item.id === here.documentId) return;
3811
- if (item.kind === "docx" || item.kind === "markdown") void import("./TextEditor-Z4KSBLBV.js");
3812
- if (item.kind === "sheet") void import("./SheetView-PUSRW7W2.js");
3810
+ if (item.kind === "docx" || item.kind === "markdown") void import("./TextEditor-NDWZUYDA.js");
3811
+ if (item.kind === "sheet") void import("./SheetView-Q6K3UGVP.js");
3813
3812
  const kept2 = early.current.get(item.id);
3814
3813
  if (kept2 && Date.now() - kept2.at < 15e3 || item.size > 5e6) return;
3815
3814
  const next = { at: Date.now(), doc: host.document(item.id), bytes: host.content(item.id, null) };
@@ -3982,6 +3981,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
3982
3981
  documentId: doc.data.id,
3983
3982
  onOutline: setOutline,
3984
3983
  onReading: setReading,
3984
+ onSpot: setAim,
3985
3985
  onPanel: (next) => {
3986
3986
  setPanelOpen(true);
3987
3987
  setTab(next);
@@ -4060,6 +4060,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4060
4060
  host: versionId ? void 0 : host,
4061
4061
  together: doc.data.live,
4062
4062
  documentId: doc.data.id,
4063
+ onSpot: setAim,
4063
4064
  onSaved: () => {
4064
4065
  versions.retry();
4065
4066
  doc.retry();
@@ -4099,6 +4100,16 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4099
4100
  if (text && host.comments && !versionId) panelTabs.push(["comments", MessagesSquare, t.comments]);
4100
4101
  const sharing = !!host.links && !!doc.data?.rights.edit && !versionId;
4101
4102
  if (sharing) panelTabs.push(["sharing", Share2, t.sharing]);
4103
+ const extra = doc.data ? tabs?.(doc.data, aim) ?? [] : [];
4104
+ const waiting2 = extra.find((x) => x.count);
4105
+ const pending = extra.reduce((n, x) => n + (x.count ?? 0), 0);
4106
+ if (pending !== heard) {
4107
+ setHeard(pending);
4108
+ if (waiting2 && pending > heard) {
4109
+ setTab(`host:${waiting2.id}`);
4110
+ setPanelOpen(true);
4111
+ }
4112
+ }
4102
4113
  const listToggle = /* @__PURE__ */ jsx13(
4103
4114
  "button",
4104
4115
  {
@@ -4338,7 +4349,6 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4338
4349
  onOpen: open,
4339
4350
  onMenu: (item, e) => {
4340
4351
  setSpot(null);
4341
- setPeek(null);
4342
4352
  setMenu({ item, x: Math.min(e.clientX, innerWidth - 290), y: Math.min(e.clientY, innerHeight - 440), sure: false });
4343
4353
  },
4344
4354
  onFolderMenu: host.create || host.makeFolder ? (at, key, e) => {
@@ -4349,13 +4359,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4349
4359
  const item = all.find((x) => x.id === id);
4350
4360
  if (item) moveTo(item, to);
4351
4361
  } : void 0,
4352
- onWarm: (item, at) => {
4353
- if (item) warm(item, at);
4354
- else {
4355
- clearTimeout(hover.current);
4356
- setPeek(null);
4357
- }
4358
- }
4362
+ onWarm: (item) => item ? warm(item) : clearTimeout(hover.current)
4359
4363
  }
4360
4364
  )
4361
4365
  ] })
@@ -4365,15 +4369,23 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4365
4369
  !narrow && !panelOpen && panelToggle,
4366
4370
  /* @__PURE__ */ jsx13("div", { className: "w100n-docs-bare", children: stage })
4367
4371
  ] }),
4368
- doc.data && panelOpen && /* @__PURE__ */ jsxs13("aside", { ref: panel, className: "w100n-docs-side w100n-docs-panel", "aria-label": t.details, children: [
4369
- /* @__PURE__ */ jsx13("div", { className: "w100n-docs-head", children: /* @__PURE__ */ jsxs13("div", { className: "w100n-docs-row", children: [
4370
- /* @__PURE__ */ jsx13("div", { className: "w100n-docs-tabs", role: "tablist", "aria-label": t.details, "data-compact": panelTabs.length > 3, onKeyDown: rove, children: panelTabs.map(([key, Icon, label]) => /* @__PURE__ */ jsxs13("button", { type: "button", role: "tab", "aria-selected": tab === key, tabIndex: tab === key ? 0 : -1, "aria-label": label, title: label, onClick: () => setTab(key), children: [
4371
- /* @__PURE__ */ jsx13(Icon, { "aria-hidden": true }),
4372
- (panelTabs.length < 4 || tab === key && panelTabs.length < 5) && /* @__PURE__ */ jsx13("span", { children: label })
4373
- ] }, key)) }),
4374
- /* @__PURE__ */ jsx13("button", { type: "button", className: "w100n-docs-close", onClick: () => side("panel", false), "aria-label": t.closePanel, title: t.closePanel, children: /* @__PURE__ */ jsx13(X6, { "aria-hidden": true }) })
4375
- ] }) }),
4376
- /* @__PURE__ */ jsxs13("div", { className: "w100n-docs-panel-body", role: "tabpanel", "aria-label": panelTabs.find(([key]) => key === tab)?.[2], children: [
4372
+ doc.data && panelOpen && /* @__PURE__ */ jsxs13("aside", { ref: panel, className: "w100n-docs-side w100n-docs-panel", "data-wide": !!extra.find((x) => `host:${x.id}` === tab)?.wide, "aria-label": t.details, children: [
4373
+ /* @__PURE__ */ jsxs13("div", { className: "w100n-docs-head", children: [
4374
+ /* @__PURE__ */ jsxs13("div", { className: "w100n-docs-row", children: [
4375
+ /* @__PURE__ */ jsx13("div", { className: "w100n-docs-tabs", role: "tablist", "aria-label": t.details, "data-compact": panelTabs.length > 3, onKeyDown: rove, children: panelTabs.map(([key, Icon, label, count]) => /* @__PURE__ */ jsxs13("button", { type: "button", role: "tab", "aria-selected": tab === key, tabIndex: tab === key ? 0 : -1, "aria-label": label, title: label, onClick: () => setTab(key), children: [
4376
+ /* @__PURE__ */ jsx13(Icon, { "aria-hidden": true }),
4377
+ (panelTabs.length < 4 || tab === key && panelTabs.length < 5) && /* @__PURE__ */ jsx13("span", { children: label }),
4378
+ !!count && /* @__PURE__ */ jsx13("b", { className: "w100n-docs-count", children: count })
4379
+ ] }, key)) }),
4380
+ /* @__PURE__ */ jsx13("button", { type: "button", className: "w100n-docs-close", onClick: () => side("panel", false), "aria-label": t.closePanel, title: t.closePanel, children: /* @__PURE__ */ jsx13(X6, { "aria-hidden": true }) })
4381
+ ] }),
4382
+ !!extra.length && /* @__PURE__ */ jsx13("div", { className: "w100n-docs-hosttabs", role: "tablist", "aria-label": t.details, children: extra.map((x) => /* @__PURE__ */ jsxs13("button", { type: "button", role: "tab", "aria-selected": tab === `host:${x.id}`, onClick: () => setTab(`host:${x.id}`), children: [
4383
+ /* @__PURE__ */ jsx13(x.icon, { "aria-hidden": true }),
4384
+ /* @__PURE__ */ jsx13("span", { children: x.label }),
4385
+ !!x.count && /* @__PURE__ */ jsx13("b", { className: "w100n-docs-count", children: x.count })
4386
+ ] }, x.id)) })
4387
+ ] }),
4388
+ /* @__PURE__ */ jsxs13("div", { className: "w100n-docs-panel-body", role: "tabpanel", "aria-label": panelTabs.find(([key]) => key === tab)?.[2] ?? extra.find((x) => `host:${x.id}` === tab)?.label, children: [
4377
4389
  tab === "outline" && (outline.length ? /* @__PURE__ */ jsxs13("nav", { className: "w100n-docs-outline", "aria-label": t.outline, children: [
4378
4390
  now && /* @__PURE__ */ jsxs13("div", { className: "w100n-docs-reading", children: [
4379
4391
  /* @__PURE__ */ jsx13("span", { children: /* @__PURE__ */ jsx13("i", { style: { width: `${Math.round(now.progress * 100)}%` } }) }),
@@ -4518,6 +4530,7 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4518
4530
  );
4519
4531
  })
4520
4532
  ] }),
4533
+ extra.find((x) => `host:${x.id}` === tab)?.body,
4521
4534
  aside?.(doc.data)
4522
4535
  ] })
4523
4536
  ] })
@@ -4539,7 +4552,6 @@ function DocumentsWorkspace({ host, language = "en", theme = "light", place, onP
4539
4552
  setMaking(false);
4540
4553
  opened(made);
4541
4554
  } }),
4542
- peek && !menu && /* @__PURE__ */ jsx13("div", { className: "w100n-docs-peek", role: "tooltip", style: { left: peek.x, top: peek.y }, children: card(peek.item) }),
4543
4555
  menu && /* @__PURE__ */ jsxs13("div", { ref: popup, className: "w100n-docs-menu w100n-docs-context", role: "menu", "aria-label": t.fileActions, style: { left: menu.x, top: menu.y }, children: [
4544
4556
  /* @__PURE__ */ jsx13("div", { className: "w100n-docs-context-head", children: card(menu.item) }),
4545
4557
  menu.moving ? /* @__PURE__ */ jsx13("div", { className: "w100n-docs-context-list", children: ["", ...dirs.data.get(menu.item.spaceId)].map((folder2) => /* @__PURE__ */ jsxs13(
@@ -4710,8 +4722,8 @@ function FilePreview({ url, name, mimeType, size = 0, bytes, pdfWorker }) {
4710
4722
  import { lazy as lazy3, Suspense as Suspense3, useRef as useRef7, useState as useState13 } from "react";
4711
4723
  import { Ban as Ban2, Download as Download4, Eye as Eye2, FileDown as FileDown2, FileSpreadsheet as FileSpreadsheet5, FileText as FileText5, FileType as FileType6, Files as Files3, Lock as Lock2, Presentation as Presentation4, UserRound } from "lucide-react";
4712
4724
  import { Fragment as Fragment12, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
4713
- var TextEditor3 = lazy3(() => import("./TextEditor-Z4KSBLBV.js"));
4714
- var SheetView3 = lazy3(() => import("./SheetView-PUSRW7W2.js"));
4725
+ var TextEditor3 = lazy3(() => import("./TextEditor-NDWZUYDA.js"));
4726
+ var SheetView3 = lazy3(() => import("./SheetView-Q6K3UGVP.js"));
4715
4727
  var icons4 = { docx: FileText5, markdown: FileType6, pdf: Files3, sheet: FileSpreadsheet5, slides: Presentation4 };
4716
4728
  var GuestRefused = class extends Error {
4717
4729
  constructor(reason, file = "", sharedBy = "") {