@bendyline/docblocks-react 2.6.2 → 2.7.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 (57) hide show
  1. package/README.md +3 -10
  2. package/THIRD_PARTY_NOTICES.txt +4284 -3651
  3. package/dist/AiDiagrams-LFV4YU6W.js +13 -0
  4. package/dist/AiEditorAssistant-GN2KXKZD.js +786 -0
  5. package/dist/AudioExportDialog-F23QXNPB.js +253 -0
  6. package/dist/DocumentConflictDialog-5LRVIGXS.js +111 -0
  7. package/dist/ExportDialog-IMBVGRYG.js +9 -0
  8. package/dist/{ExportToolbarControls-QYLBRWM7.js → ExportToolbarControls-MUM6HM3K.js} +117 -49
  9. package/dist/{GitToolbarControl-O5AXBC6T.js → GitToolbarControl-B7KG4MFP.js} +6 -6
  10. package/dist/{GitUI-L5T3XHZG.js → GitUI-RCWUZVS6.js} +6 -6
  11. package/dist/PresentationMaker-W2JIBHRN.js +9 -0
  12. package/dist/QuickOpenDialog-2KK4SEBU.js +356 -0
  13. package/dist/Settings-DuXk6baH.d.ts +144 -0
  14. package/dist/ShareDialog-XUA2OVGI.js +292 -0
  15. package/dist/SpeechToolbarControl-OSQS7NVY.js +434 -0
  16. package/dist/TextFromNarration-XYRAB6O2.js +598 -0
  17. package/dist/WorkspaceSearchPanel-BKZJRPMY.js +334 -0
  18. package/dist/chunk-2IYBBFQX.js +201 -0
  19. package/dist/{chunk-LG6HAWCK.js → chunk-56KO2LYN.js} +35 -4
  20. package/dist/chunk-6B7G33D5.js +88 -0
  21. package/dist/chunk-ARATARVJ.js +40 -0
  22. package/dist/{chunk-ODYNOPC3.js → chunk-BCQZTWE5.js} +57 -17
  23. package/dist/{chunk-FMDLZ4ZG.js → chunk-BD54Z5XP.js} +12 -3
  24. package/dist/chunk-EA4BO6E4.js +73 -0
  25. package/dist/chunk-EPOLZNFD.js +518 -0
  26. package/dist/chunk-G4MFB3IO.js +208 -0
  27. package/dist/{chunk-MRUK56JS.js → chunk-GMA4KGGO.js} +7 -3
  28. package/dist/chunk-I44HKDQX.js +314 -0
  29. package/dist/chunk-K4I3NJFL.js +49 -0
  30. package/dist/chunk-KBDZDFPU.js +61 -0
  31. package/dist/{chunk-FNSRCCBC.js → chunk-KWG6UP5O.js} +0 -10
  32. package/dist/chunk-NAH52736.js +1884 -0
  33. package/dist/chunk-RP3DVNTI.js +62 -0
  34. package/dist/chunk-SPUPWCSI.js +111 -0
  35. package/dist/chunk-TBLZBNQF.js +25 -0
  36. package/dist/{chunk-M5Y5WO7Z.js → chunk-UG4G7PJ4.js} +1 -1
  37. package/dist/chunk-UONFWKJ7.js +22 -0
  38. package/dist/chunk-VO2JYYQZ.js +40 -0
  39. package/dist/chunk-W55E6TE2.js +1714 -0
  40. package/dist/chunk-X3DDTJKR.js +574 -0
  41. package/dist/{chunk-EBWYGTN7.js → chunk-X437UAF7.js} +6 -0
  42. package/dist/editor.d.ts +36 -1
  43. package/dist/editor.js +16 -1
  44. package/dist/export/index.d.ts +27 -11
  45. package/dist/export/index.js +11 -7
  46. package/dist/index.d.ts +100 -13
  47. package/dist/index.js +3927 -1638
  48. package/dist/proofing/index.js +11 -1
  49. package/dist/{run-export-I2XOVGG4.js → run-export-47X5FTYZ.js} +3 -3
  50. package/dist/settings/index.d.ts +32 -101
  51. package/dist/settings/index.js +14 -2
  52. package/package.json +9 -9
  53. package/src/styles/docblocks.css +2344 -657
  54. package/dist/ExportDialog-Q4VWI43H.js +0 -9
  55. package/dist/ShareDialog-4OX3UPJ4.js +0 -359
  56. package/dist/chunk-JDJVRDOP.js +0 -92
  57. package/dist/chunk-Q6XNIKDG.js +0 -669
@@ -0,0 +1,88 @@
1
+ import {
2
+ Dialog
3
+ } from "./chunk-56KO2LYN.js";
4
+
5
+ // src/components/useConfirmDialog.ts
6
+ import React2, { useCallback as useCallback2, useEffect, useRef as useRef2, useState } from "react";
7
+
8
+ // src/components/ConfirmDialog.tsx
9
+ import { useCallback, useRef } from "react";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
+ function ConfirmDialog({ request, onSettle }) {
12
+ const acknowledge = request.kind === "acknowledge";
13
+ const destructive = request.kind === "confirm" && request.destructive === true;
14
+ const cancelRef = useRef(null);
15
+ const confirmRef = useRef(null);
16
+ const accept = useCallback(() => onSettle(true), [onSettle]);
17
+ const reject = useCallback(() => onSettle(false), [onSettle]);
18
+ const close = acknowledge ? accept : reject;
19
+ return /* @__PURE__ */ jsx(
20
+ Dialog,
21
+ {
22
+ title: request.title,
23
+ onClose: close,
24
+ initialFocusRef: destructive ? cancelRef : confirmRef,
25
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
26
+ !acknowledge && /* @__PURE__ */ jsx("button", { ref: cancelRef, type: "button", className: "db-git-secondary-btn", onClick: reject, children: request.cancelLabel ?? "Cancel" }),
27
+ /* @__PURE__ */ jsx(
28
+ "button",
29
+ {
30
+ ref: confirmRef,
31
+ type: "button",
32
+ className: destructive ? "db-git-primary-btn db-git-primary-btn--danger" : "db-git-primary-btn",
33
+ onClick: accept,
34
+ children: request.confirmLabel ?? "OK"
35
+ }
36
+ )
37
+ ] }),
38
+ children: /* @__PURE__ */ jsx("p", { className: "db-dialog-message", children: request.message })
39
+ }
40
+ );
41
+ }
42
+
43
+ // src/components/useConfirmDialog.ts
44
+ function useConfirmDialog() {
45
+ const [pending, setPending] = useState(null);
46
+ const pendingRef = useRef2(null);
47
+ const nextIdRef = useRef2(0);
48
+ const settlePending = useCallback2((value) => {
49
+ const current = pendingRef.current;
50
+ if (!current) return;
51
+ pendingRef.current = null;
52
+ setPending((open2) => open2?.id === current.id ? null : open2);
53
+ current.settle(value);
54
+ }, []);
55
+ const open = useCallback2(
56
+ (request) => new Promise((resolve) => {
57
+ settlePending(false);
58
+ const next = { id: ++nextIdRef.current, request, settle: resolve };
59
+ pendingRef.current = next;
60
+ setPending(next);
61
+ }),
62
+ [settlePending]
63
+ );
64
+ const confirm = useCallback2(
65
+ (request) => open({ kind: "confirm", ...request }),
66
+ [open]
67
+ );
68
+ const acknowledge = useCallback2(
69
+ async (request) => {
70
+ await open({ kind: "acknowledge", ...request });
71
+ },
72
+ [open]
73
+ );
74
+ useEffect(() => {
75
+ return () => settlePending(false);
76
+ }, [settlePending]);
77
+ const confirmDialog = pending ? React2.createElement(ConfirmDialog, {
78
+ // Remount on a superseding request so focus re-seeds from it.
79
+ key: pending.id,
80
+ request: pending.request,
81
+ onSettle: settlePending
82
+ }) : null;
83
+ return { confirm, acknowledge, confirmDialog };
84
+ }
85
+
86
+ export {
87
+ useConfirmDialog
88
+ };
@@ -0,0 +1,40 @@
1
+ // src/FileExplorer/file-names.ts
2
+ var HIDDEN_EXTENSION = ".md";
3
+ var EXTENSION = /\.(?=[A-Za-z0-9]*[A-Za-z])[A-Za-z0-9]{1,10}$/;
4
+ function hidesExtension(name) {
5
+ return name.endsWith(HIDDEN_EXTENSION) && name.length > HIDDEN_EXTENSION.length;
6
+ }
7
+ function extensionStart(name) {
8
+ const match = EXTENSION.exec(name);
9
+ return match && match.index > 0 ? match.index : -1;
10
+ }
11
+ function displayFileName(name) {
12
+ return hidesExtension(name) ? name.slice(0, -HIDDEN_EXTENSION.length) : name;
13
+ }
14
+ function renameDraft(name, kind) {
15
+ if (kind === "file" && hidesExtension(name)) {
16
+ const value = displayFileName(name);
17
+ return { value, selectionEnd: value.length };
18
+ }
19
+ const start = kind === "file" ? extensionStart(name) : -1;
20
+ return { value: name, selectionEnd: start >= 0 ? start : name.length };
21
+ }
22
+ function renamedFileName(name, typed, kind) {
23
+ let next = typed.trim();
24
+ if (!next) return null;
25
+ if (kind === "file") {
26
+ if (hidesExtension(name)) {
27
+ if (!next.toLowerCase().endsWith(HIDDEN_EXTENSION)) next += HIDDEN_EXTENSION;
28
+ } else {
29
+ const start = extensionStart(name);
30
+ if (start >= 0 && extensionStart(next) < 0) next += name.slice(start);
31
+ }
32
+ }
33
+ return next === name ? null : next;
34
+ }
35
+
36
+ export {
37
+ displayFileName,
38
+ renameDraft,
39
+ renamedFileName
40
+ };
@@ -1,9 +1,22 @@
1
1
  import {
2
2
  FORMAT_EXTENSIONS
3
- } from "./chunk-EBWYGTN7.js";
3
+ } from "./chunk-X437UAF7.js";
4
4
 
5
5
  // src/Export/run-export.ts
6
6
  import { parseMarkdown } from "@bendyline/squisq/markdown";
7
+ async function pictureDiagrams(doc, overrides, kinds) {
8
+ try {
9
+ const [{ rasterizeDiagrams }, render] = await Promise.all([
10
+ import("@bendyline/squisq-formats/diagrams"),
11
+ overrides.diagramRenderer ?? import("@bendyline/squisq-react/diagram-pictures").then(
12
+ (module) => module.createDiagramPictureRenderer()
13
+ )
14
+ ]);
15
+ return await rasterizeDiagrams(doc, render, { kinds, urlPrefix: "docblocks-diagram" });
16
+ } catch {
17
+ return { markdownDoc: doc, images: /* @__PURE__ */ new Map(), mermaid: /* @__PURE__ */ new Map() };
18
+ }
19
+ }
7
20
  var MIME_TYPES = {
8
21
  docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
9
22
  pdf: "application/pdf",
@@ -45,24 +58,40 @@ async function runExport(markdown, selectedFile, options, mediaContainer, saveBl
45
58
  const doc = parseMarkdown(markdown);
46
59
  if (options.format === "docx") {
47
60
  const { markdownDocToDocx } = await import("@bendyline/squisq-formats/docx");
48
- const images = mediaContainer ? await resolveImages(doc, mediaContainer) : void 0;
49
- const buf = await markdownDocToDocx(doc, { themeId, images });
61
+ const pictured = await pictureDiagrams(doc, converterOverrides);
62
+ const images = new Map([
63
+ ...mediaContainer ? await resolveImages(doc, mediaContainer) : [],
64
+ ...pictured.images
65
+ ]);
66
+ const buf = await markdownDocToDocx(pictured.markdownDoc, { themeId, images });
50
67
  await saveExportBlob(new Blob([buf], { type: MIME_TYPES.docx }), filename, saveBlob);
51
68
  return;
52
69
  }
53
70
  if (options.format === "pdf") {
54
71
  const { markdownDocToPdf } = await import("@bendyline/squisq-formats/pdf");
55
- const buf = await markdownDocToPdf(doc, {
72
+ const pictured = await pictureDiagrams(doc, converterOverrides);
73
+ const images = new Map([
74
+ ...mediaContainer ? await resolveImages(doc, mediaContainer) : [],
75
+ ...pictured.images
76
+ ]);
77
+ const buf = await markdownDocToPdf(pictured.markdownDoc, {
56
78
  themeId,
57
- pageSize: options.pageSize
79
+ pageSize: options.pageSize,
80
+ images
58
81
  });
59
82
  await saveExportBlob(new Blob([buf], { type: MIME_TYPES.pdf }), filename, saveBlob);
60
83
  return;
61
84
  }
62
85
  if (options.format === "epub") {
63
86
  const { markdownDocToEpub } = await import("@bendyline/squisq-formats/epub");
64
- const images = mediaContainer ? await resolveImageData(doc, mediaContainer) : void 0;
65
- const buf = await markdownDocToEpub(doc, { themeId, images });
87
+ const pictured = await pictureDiagrams(doc, converterOverrides);
88
+ const images = new Map([
89
+ ...mediaContainer ? await resolveImageData(doc, mediaContainer) : [],
90
+ ...[...pictured.images].map(
91
+ ([url, picture]) => [url, picture.data.slice().buffer]
92
+ )
93
+ ]);
94
+ const buf = await markdownDocToEpub(pictured.markdownDoc, { themeId, images });
66
95
  await saveExportBlob(new Blob([buf], { type: MIME_TYPES.epub }), filename, saveBlob);
67
96
  return;
68
97
  }
@@ -81,11 +110,21 @@ async function runExport(markdown, selectedFile, options, mediaContainer, saveBl
81
110
  enrichedDoc.themeId = themeId;
82
111
  }
83
112
  const images = mediaContainer ? await resolveImageData(doc, mediaContainer) : void 0;
84
- const buf = await docToPptx(enrichedDoc, { themeId, images });
113
+ const { mermaid } = await pictureDiagrams(doc, converterOverrides, ["mermaid"]);
114
+ const buf = await docToPptx(enrichedDoc, { themeId, images, diagramImages: mermaid });
85
115
  await saveExportBlob(new Blob([buf], { type: MIME_TYPES.pptx }), filename, saveBlob);
86
116
  return;
87
117
  }
88
118
  }
119
+ var MERMAID_FENCE = /^ {0,3}(?:```|~~~)[ \t]*mermaid\b/imu;
120
+ async function playerScriptFor(markdown) {
121
+ if (MERMAID_FENCE.test(markdown)) {
122
+ const { PLAYER_BUNDLE_FULL } = await import("@bendyline/squisq-react/standalone-source/full");
123
+ return PLAYER_BUNDLE_FULL;
124
+ }
125
+ const { PLAYER_BUNDLE } = await import("@bendyline/squisq-react/standalone-source");
126
+ return PLAYER_BUNDLE;
127
+ }
89
128
  async function runHtmlExport(markdown, htmlFilename, options, mediaContainer, selectedFile, saveBlob) {
90
129
  const baseName = htmlFilename.replace(/\.html$/, "");
91
130
  const zipName = `${baseName}.zip`;
@@ -93,16 +132,17 @@ async function runHtmlExport(markdown, htmlFilename, options, mediaContainer, se
93
132
  const themeId = options.themeId !== "standard" ? options.themeId : void 0;
94
133
  if (options.includeLinkedDocs && mediaContainer && selectedFile) {
95
134
  const entryPath = basenameForBundle(selectedFile);
135
+ const readDocument = (path) => path === entryPath ? Promise.resolve(markdown) : readDocumentFromContainer(mediaContainer, path);
96
136
  if (options.htmlStyle === "rendered") {
97
- const [{ markdownDocsToHtmlBundle }, { PLAYER_BUNDLE }] = await Promise.all([
137
+ const [{ markdownDocsToHtmlBundle }, playerScript] = await Promise.all([
98
138
  import("@bendyline/squisq-formats/html"),
99
- import("@bendyline/squisq-react/standalone-source")
139
+ playerScriptFor(markdown)
100
140
  ]);
101
141
  const blob2 = await markdownDocsToHtmlBundle({
102
142
  entryPath,
103
- readDocument: (path) => readDocumentFromContainer(mediaContainer, path),
143
+ readDocument,
104
144
  readBinary: (path) => mediaContainer.readFile(path),
105
- playerScript: PLAYER_BUNDLE,
145
+ playerScript,
106
146
  title: baseName,
107
147
  themeId,
108
148
  mode: "static",
@@ -115,7 +155,7 @@ async function runHtmlExport(markdown, htmlFilename, options, mediaContainer, se
115
155
  const { markdownDocsToPlainHtmlBundle } = await import("@bendyline/squisq-formats/html");
116
156
  const blob = await markdownDocsToPlainHtmlBundle({
117
157
  entryPath,
118
- readDocument: (path) => readDocumentFromContainer(mediaContainer, path),
158
+ readDocument,
119
159
  readBinary: (path) => mediaContainer.readFile(path),
120
160
  title: baseName,
121
161
  themeId,
@@ -125,10 +165,10 @@ async function runHtmlExport(markdown, htmlFilename, options, mediaContainer, se
125
165
  return;
126
166
  }
127
167
  if (options.htmlStyle === "rendered") {
128
- const [{ markdownToDoc }, { docToHtml, docToHtmlZip, collectImagePaths }, { PLAYER_BUNDLE }] = await Promise.all([
168
+ const [{ markdownToDoc }, { docToHtml, docToHtmlZip, collectImagePaths }, playerScript] = await Promise.all([
129
169
  import("@bendyline/squisq/doc"),
130
170
  import("@bendyline/squisq-formats/html"),
131
- import("@bendyline/squisq-react/standalone-source")
171
+ playerScriptFor(markdown)
132
172
  ]);
133
173
  const mdDoc2 = parseMarkdown(markdown);
134
174
  const baseDoc = markdownToDoc(mdDoc2);
@@ -136,7 +176,7 @@ async function runHtmlExport(markdown, htmlFilename, options, mediaContainer, se
136
176
  const images = mediaContainer ? await resolveDocImages(baseDoc, mediaContainer, collectImagePaths) : void 0;
137
177
  if (options.htmlBundle === "zip") {
138
178
  const blob = await docToHtmlZip(baseDoc, {
139
- playerScript: PLAYER_BUNDLE,
179
+ playerScript,
140
180
  images,
141
181
  mode: "static",
142
182
  title: baseName,
@@ -146,7 +186,7 @@ async function runHtmlExport(markdown, htmlFilename, options, mediaContainer, se
146
186
  return;
147
187
  }
148
188
  const html2 = docToHtml(baseDoc, {
149
- playerScript: PLAYER_BUNDLE,
189
+ playerScript,
150
190
  images,
151
191
  mode: "static",
152
192
  title: baseName,
@@ -4,10 +4,10 @@ import {
4
4
  import {
5
5
  FORMAT_LABELS,
6
6
  saveExportOptions
7
- } from "./chunk-EBWYGTN7.js";
7
+ } from "./chunk-X437UAF7.js";
8
8
  import {
9
9
  Dialog
10
- } from "./chunk-LG6HAWCK.js";
10
+ } from "./chunk-56KO2LYN.js";
11
11
 
12
12
  // src/Export/ExportDialog.tsx
13
13
  import { useState, useCallback, useEffect, useMemo } from "react";
@@ -52,7 +52,7 @@ function ChipRadioGroup({
52
52
  options,
53
53
  onChange
54
54
  }) {
55
- return /* @__PURE__ */ jsx("div", { className: "db-export-chips", role: "radiogroup", "aria-label": name, children: options.map((opt) => {
55
+ return /* @__PURE__ */ jsx("div", { className: "db-export-chips", role: "radiogroup", "aria-label": name, children: options.map((opt, index) => {
56
56
  const active = opt.key === value;
57
57
  return /* @__PURE__ */ jsx(
58
58
  "button",
@@ -60,8 +60,17 @@ function ChipRadioGroup({
60
60
  type: "button",
61
61
  role: "radio",
62
62
  "aria-checked": active,
63
+ tabIndex: active ? 0 : -1,
63
64
  className: `db-export-chip${active ? " db-export-chip--active" : ""}`,
64
65
  onClick: () => onChange(opt.key),
66
+ onKeyDown: (event) => {
67
+ const delta = event.key === "ArrowRight" || event.key === "ArrowDown" ? 1 : event.key === "ArrowLeft" || event.key === "ArrowUp" ? -1 : 0;
68
+ if (!delta) return;
69
+ event.preventDefault();
70
+ const next = (index + delta + options.length) % options.length;
71
+ onChange(options[next].key);
72
+ event.currentTarget.parentElement?.querySelectorAll('[role="radio"]')[next]?.focus();
73
+ },
65
74
  title: opt.title,
66
75
  children: opt.label
67
76
  },
@@ -0,0 +1,73 @@
1
+ // src/icons.tsx
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ function FontAwesomeIcon({ icon }) {
4
+ return /* @__PURE__ */ jsx("i", { className: icon, "aria-hidden": "true" });
5
+ }
6
+ function NewFileIcon() {
7
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-file-circle-plus" });
8
+ }
9
+ function NewFolderIcon() {
10
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-folder-plus" });
11
+ }
12
+ function OpenFolderIcon() {
13
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-folder-open" });
14
+ }
15
+ function SortByNameIcon() {
16
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-arrow-down-a-z" });
17
+ }
18
+ function SortByLastModifiedIcon() {
19
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-clock" });
20
+ }
21
+ function FolderIcon() {
22
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-folder" });
23
+ }
24
+ function MoreIcon() {
25
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-ellipsis" });
26
+ }
27
+ function PinIcon() {
28
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-thumbtack" });
29
+ }
30
+ function WorkspaceIcon() {
31
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-gear" });
32
+ }
33
+ function SplitViewIcon() {
34
+ return /* @__PURE__ */ jsxs(
35
+ "svg",
36
+ {
37
+ width: "16",
38
+ height: "16",
39
+ viewBox: "0 0 16 16",
40
+ fill: "none",
41
+ stroke: "currentColor",
42
+ strokeWidth: "1.5",
43
+ strokeLinecap: "round",
44
+ strokeLinejoin: "round",
45
+ "aria-hidden": "true",
46
+ children: [
47
+ /* @__PURE__ */ jsx("rect", { x: "1.5", y: "2.5", width: "13", height: "11", rx: "1" }),
48
+ /* @__PURE__ */ jsx("line", { x1: "6", y1: "2.5", x2: "6", y2: "13.5" })
49
+ ]
50
+ }
51
+ );
52
+ }
53
+ function SearchIcon() {
54
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-magnifying-glass" });
55
+ }
56
+ function FilesIcon() {
57
+ return /* @__PURE__ */ jsx(FontAwesomeIcon, { icon: "fa-solid fa-folder-tree" });
58
+ }
59
+
60
+ export {
61
+ NewFileIcon,
62
+ NewFolderIcon,
63
+ OpenFolderIcon,
64
+ SortByNameIcon,
65
+ SortByLastModifiedIcon,
66
+ FolderIcon,
67
+ MoreIcon,
68
+ PinIcon,
69
+ WorkspaceIcon,
70
+ SplitViewIcon,
71
+ SearchIcon,
72
+ FilesIcon
73
+ };