@rightkit/document-workspace 0.0.0-stage → 0.1.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 (262) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE-APACHE +201 -0
  3. package/LICENSE-MIT +21 -0
  4. package/README.md +74 -2
  5. package/dist/app/App.d.ts +1 -0
  6. package/dist/app/App.js +6 -0
  7. package/dist/app/AppDialogs.d.ts +52 -0
  8. package/dist/app/AppDialogs.js +23 -0
  9. package/dist/app/AppDialogsHost.d.ts +31 -0
  10. package/dist/app/AppDialogsHost.js +30 -0
  11. package/dist/app/AppLifecycle.d.ts +19 -0
  12. package/dist/app/AppLifecycle.js +87 -0
  13. package/dist/app/AppProvider.d.ts +317 -0
  14. package/dist/app/AppProvider.js +217 -0
  15. package/dist/app/AppRoot.d.ts +8 -0
  16. package/dist/app/AppRoot.js +159 -0
  17. package/dist/app/AppShell.d.ts +2 -0
  18. package/dist/app/AppShell.js +81 -0
  19. package/dist/app/CommandPalette.d.ts +13 -0
  20. package/dist/app/CommandPalette.js +47 -0
  21. package/dist/app/DocActionBar.d.ts +36 -0
  22. package/dist/app/DocActionBar.js +300 -0
  23. package/dist/app/DocumentContextMenu.d.ts +29 -0
  24. package/dist/app/DocumentContextMenu.js +122 -0
  25. package/dist/app/DocumentPane.d.ts +52 -0
  26. package/dist/app/DocumentPane.js +30 -0
  27. package/dist/app/DocumentRouterTable.d.ts +58 -0
  28. package/dist/app/DocumentRouterTable.js +143 -0
  29. package/dist/app/ErrorBoundary.d.ts +12 -0
  30. package/dist/app/ErrorBoundary.js +16 -0
  31. package/dist/app/FindBar.d.ts +12 -0
  32. package/dist/app/FindBar.js +199 -0
  33. package/dist/app/LiveTitle.d.ts +14 -0
  34. package/dist/app/LiveTitle.js +14 -0
  35. package/dist/app/OpeningProgress.d.ts +13 -0
  36. package/dist/app/OpeningProgress.js +21 -0
  37. package/dist/app/PrintPreviewWindow.d.ts +2 -0
  38. package/dist/app/PrintPreviewWindow.js +57 -0
  39. package/dist/app/ShortcutHelp.d.ts +3 -0
  40. package/dist/app/ShortcutHelp.js +99 -0
  41. package/dist/app/Sidebar.d.ts +36 -0
  42. package/dist/app/Sidebar.js +121 -0
  43. package/dist/app/ToastViewport.d.ts +1 -0
  44. package/dist/app/ToastViewport.js +31 -0
  45. package/dist/app/Toolbar.d.ts +26 -0
  46. package/dist/app/Toolbar.js +63 -0
  47. package/dist/app/activeFormatSavers.d.ts +7 -0
  48. package/dist/app/activeFormatSavers.js +4 -0
  49. package/dist/app/clipboardPaths.d.ts +1 -0
  50. package/dist/app/clipboardPaths.js +31 -0
  51. package/dist/app/documentDrafts.d.ts +17 -0
  52. package/dist/app/documentDrafts.js +104 -0
  53. package/dist/app/draftResolution.d.ts +5 -0
  54. package/dist/app/draftResolution.js +25 -0
  55. package/dist/app/markdownPaletteActions.d.ts +8 -0
  56. package/dist/app/markdownPaletteActions.js +107 -0
  57. package/dist/app/resourceCensusDev.d.ts +41 -0
  58. package/dist/app/resourceCensusDev.js +518 -0
  59. package/dist/app/setupRecovery.d.ts +34 -0
  60. package/dist/app/setupRecovery.js +70 -0
  61. package/dist/app/shell/DocStatsPill.d.ts +18 -0
  62. package/dist/app/shell/DocStatsPill.js +32 -0
  63. package/dist/app/shell/DocumentTools.d.ts +9 -0
  64. package/dist/app/shell/DocumentTools.js +73 -0
  65. package/dist/app/shell/InfoInspector.d.ts +9 -0
  66. package/dist/app/shell/InfoInspector.js +67 -0
  67. package/dist/app/shell/StartPage.d.ts +9 -0
  68. package/dist/app/shell/StartPage.js +49 -0
  69. package/dist/app/shell/readEdit.d.ts +6 -0
  70. package/dist/app/shell/readEdit.js +6 -0
  71. package/dist/app/sidebar/SidebarDocumentMenu.d.ts +20 -0
  72. package/dist/app/sidebar/SidebarDocumentMenu.js +56 -0
  73. package/dist/app/sidebar/SidebarExpandedPanel.d.ts +9 -0
  74. package/dist/app/sidebar/SidebarExpandedPanel.js +78 -0
  75. package/dist/app/sidebar/SidebarIcons.d.ts +3 -0
  76. package/dist/app/sidebar/SidebarIcons.js +18 -0
  77. package/dist/app/sidebar/SidebarMenus.d.ts +19 -0
  78. package/dist/app/sidebar/SidebarMenus.js +64 -0
  79. package/dist/app/sidebar/SidebarPathUtils.d.ts +10 -0
  80. package/dist/app/sidebar/SidebarPathUtils.js +55 -0
  81. package/dist/app/sidebar/SidebarPrimitives.d.ts +12 -0
  82. package/dist/app/sidebar/SidebarPrimitives.js +45 -0
  83. package/dist/app/sidebar/SidebarRail.d.ts +5 -0
  84. package/dist/app/sidebar/SidebarRail.js +37 -0
  85. package/dist/app/sidebar/explorer/ExplorerRowMenu.d.ts +21 -0
  86. package/dist/app/sidebar/explorer/ExplorerRowMenu.js +37 -0
  87. package/dist/app/sidebar/explorer/ExplorerSections.d.ts +16 -0
  88. package/dist/app/sidebar/explorer/ExplorerSections.js +259 -0
  89. package/dist/app/sidebar/explorer/ExplorerTree.d.ts +46 -0
  90. package/dist/app/sidebar/explorer/ExplorerTree.js +387 -0
  91. package/dist/app/sidebar/explorer/explorerState.d.ts +37 -0
  92. package/dist/app/sidebar/explorer/explorerState.js +135 -0
  93. package/dist/app/tabMountPolicy.d.ts +45 -0
  94. package/dist/app/tabMountPolicy.js +104 -0
  95. package/dist/app/tabWarmOrder.d.ts +7 -0
  96. package/dist/app/tabWarmOrder.js +48 -0
  97. package/dist/app/tabs/TabFuseCurves.d.ts +3 -0
  98. package/dist/app/tabs/TabFuseCurves.js +15 -0
  99. package/dist/app/tabs/TabOverview.d.ts +24 -0
  100. package/dist/app/tabs/TabOverview.js +121 -0
  101. package/dist/app/tabs/TabStrip.d.ts +42 -0
  102. package/dist/app/tabs/TabStrip.js +380 -0
  103. package/dist/app/tabs/tabIds.d.ts +5 -0
  104. package/dist/app/tabs/tabIds.js +7 -0
  105. package/dist/app/tabs/useTabDirty.d.ts +3 -0
  106. package/dist/app/tabs/useTabDirty.js +11 -0
  107. package/dist/app/useAppChromeState.d.ts +21 -0
  108. package/dist/app/useAppChromeState.js +48 -0
  109. package/dist/app/useAppCommands.d.ts +66 -0
  110. package/dist/app/useAppCommands.js +71 -0
  111. package/dist/app/useAppDocumentCore.d.ts +210 -0
  112. package/dist/app/useAppDocumentCore.js +40 -0
  113. package/dist/app/useAppEffects.d.ts +18 -0
  114. package/dist/app/useAppEffects.js +52 -0
  115. package/dist/app/useAppPaneSearch.d.ts +37 -0
  116. package/dist/app/useAppPaneSearch.js +74 -0
  117. package/dist/app/useAppShellSetup.d.ts +40 -0
  118. package/dist/app/useAppShellSetup.js +52 -0
  119. package/dist/app/useAppSlots.d.ts +28 -0
  120. package/dist/app/useAppSlots.js +40 -0
  121. package/dist/app/useAppTabChrome.d.ts +51 -0
  122. package/dist/app/useAppTabChrome.js +66 -0
  123. package/dist/app/useAutoSave.d.ts +34 -0
  124. package/dist/app/useAutoSave.js +116 -0
  125. package/dist/app/useCloseAll.d.ts +52 -0
  126. package/dist/app/useCloseAll.js +295 -0
  127. package/dist/app/useClosedTabEviction.d.ts +10 -0
  128. package/dist/app/useClosedTabEviction.js +38 -0
  129. package/dist/app/useCommandPalette.d.ts +44 -0
  130. package/dist/app/useCommandPalette.js +254 -0
  131. package/dist/app/useCrossDocSearch.d.ts +7 -0
  132. package/dist/app/useCrossDocSearch.js +94 -0
  133. package/dist/app/useDistractionFree.d.ts +21 -0
  134. package/dist/app/useDistractionFree.js +73 -0
  135. package/dist/app/useDocumentCreation.d.ts +18 -0
  136. package/dist/app/useDocumentCreation.js +63 -0
  137. package/dist/app/useDocumentDirty.d.ts +31 -0
  138. package/dist/app/useDocumentDirty.js +46 -0
  139. package/dist/app/useDocumentLoader.d.ts +55 -0
  140. package/dist/app/useDocumentLoader.js +267 -0
  141. package/dist/app/useDocumentOutputActions.d.ts +6 -0
  142. package/dist/app/useDocumentOutputActions.js +45 -0
  143. package/dist/app/useDocumentRuntimeEffects.d.ts +36 -0
  144. package/dist/app/useDocumentRuntimeEffects.js +458 -0
  145. package/dist/app/useDocumentSaver.d.ts +58 -0
  146. package/dist/app/useDocumentSaver.js +511 -0
  147. package/dist/app/useDocumentTabs.d.ts +41 -0
  148. package/dist/app/useDocumentTabs.js +207 -0
  149. package/dist/app/useDocumentWatcher.d.ts +83 -0
  150. package/dist/app/useDocumentWatcher.js +393 -0
  151. package/dist/app/useDocumentZoom.d.ts +24 -0
  152. package/dist/app/useDocumentZoom.js +104 -0
  153. package/dist/app/useDocuments.d.ts +169 -0
  154. package/dist/app/useDocuments.js +455 -0
  155. package/dist/app/useDraftConfirmGate.d.ts +27 -0
  156. package/dist/app/useDraftConfirmGate.js +47 -0
  157. package/dist/app/useFileDragOverlay.d.ts +12 -0
  158. package/dist/app/useFileDragOverlay.js +49 -0
  159. package/dist/app/useFormatApis.d.ts +13 -0
  160. package/dist/app/useFormatApis.js +62 -0
  161. package/dist/app/useFormatDirtyState.d.ts +29 -0
  162. package/dist/app/useFormatDirtyState.js +81 -0
  163. package/dist/app/useGlobalShortcuts.d.ts +47 -0
  164. package/dist/app/useGlobalShortcuts.js +359 -0
  165. package/dist/app/useHtmlSession.d.ts +68 -0
  166. package/dist/app/useHtmlSession.js +463 -0
  167. package/dist/app/useHtmlSessionProps.d.ts +33 -0
  168. package/dist/app/useHtmlSessionProps.js +57 -0
  169. package/dist/app/useLibrary.d.ts +21 -0
  170. package/dist/app/useLibrary.js +81 -0
  171. package/dist/app/useOpenFromClipboard.d.ts +7 -0
  172. package/dist/app/useOpenFromClipboard.js +44 -0
  173. package/dist/app/usePaneLiveness.d.ts +29 -0
  174. package/dist/app/usePaneLiveness.js +199 -0
  175. package/dist/app/usePendingSavePaths.d.ts +19 -0
  176. package/dist/app/usePendingSavePaths.js +67 -0
  177. package/dist/app/useReadyShow.d.ts +12 -0
  178. package/dist/app/useReadyShow.js +142 -0
  179. package/dist/app/useSearchController.d.ts +22 -0
  180. package/dist/app/useSearchController.js +114 -0
  181. package/dist/app/useSetupRecovery.d.ts +41 -0
  182. package/dist/app/useSetupRecovery.js +153 -0
  183. package/dist/app/useTabChrome.d.ts +40 -0
  184. package/dist/app/useTabChrome.js +115 -0
  185. package/dist/app/useViewState.d.ts +27 -0
  186. package/dist/app/useViewState.js +160 -0
  187. package/dist/appName.d.ts +2 -0
  188. package/dist/appName.js +8 -0
  189. package/dist/documents/DocumentRouter.d.ts +102 -0
  190. package/dist/documents/DocumentRouter.js +153 -0
  191. package/dist/documents/FileTypeIcon.d.ts +6 -0
  192. package/dist/documents/FileTypeIcon.js +93 -0
  193. package/dist/documents/ImageDocument.d.ts +14 -0
  194. package/dist/documents/ImageDocument.js +61 -0
  195. package/dist/documents/capabilities.d.ts +17 -0
  196. package/dist/documents/capabilities.js +18 -0
  197. package/dist/documents/html/HtmlDocument.d.ts +15 -0
  198. package/dist/documents/html/HtmlDocument.js +584 -0
  199. package/dist/documents/html/HtmlDocumentLayout.d.ts +87 -0
  200. package/dist/documents/html/HtmlDocumentLayout.js +25 -0
  201. package/dist/documents/html/HtmlDocumentProps.d.ts +60 -0
  202. package/dist/documents/html/HtmlDocumentProps.js +1 -0
  203. package/dist/documents/html/HtmlDocumentSource.d.ts +34 -0
  204. package/dist/documents/html/HtmlDocumentSource.js +28 -0
  205. package/dist/documents/markdown/MarkdownSplitPane.d.ts +115 -0
  206. package/dist/documents/markdown/MarkdownSplitPane.js +352 -0
  207. package/dist/documents/mdx/MdxSplitPane.d.ts +32 -0
  208. package/dist/documents/mdx/MdxSplitPane.js +60 -0
  209. package/dist/documents/txt/LinkDialog.d.ts +8 -0
  210. package/dist/documents/txt/LinkDialog.js +34 -0
  211. package/dist/documents/txt/MarkdownSourceToolbar.d.ts +8 -0
  212. package/dist/documents/txt/MarkdownSourceToolbar.js +25 -0
  213. package/dist/documents/txt/SourceEditorToolbar.d.ts +12 -0
  214. package/dist/documents/txt/SourceEditorToolbar.js +4 -0
  215. package/dist/documents/txt/TxtEditor.d.ts +39 -0
  216. package/dist/documents/txt/TxtEditor.js +186 -0
  217. package/dist/documents/txt/sourceEditorTypes.d.ts +49 -0
  218. package/dist/documents/txt/sourceEditorTypes.js +1 -0
  219. package/dist/documents/txt/sourceExtensions.d.ts +38 -0
  220. package/dist/documents/txt/sourceExtensions.js +444 -0
  221. package/dist/documents/txt/sourceFormatting.d.ts +18 -0
  222. package/dist/documents/txt/sourceFormatting.js +183 -0
  223. package/dist/documents/txt/sourceTheme.d.ts +5 -0
  224. package/dist/documents/txt/sourceTheme.js +220 -0
  225. package/dist/documents/txt/useCodeMirrorSourceEditor.d.ts +69 -0
  226. package/dist/documents/txt/useCodeMirrorSourceEditor.js +546 -0
  227. package/dist/documents/txt/useSourceSearch.d.ts +39 -0
  228. package/dist/documents/txt/useSourceSearch.js +122 -0
  229. package/dist/documents/txt/useTextEditorCommands.d.ts +26 -0
  230. package/dist/documents/txt/useTextEditorCommands.js +151 -0
  231. package/dist/documents/web/LivePreviewPane.d.ts +11 -0
  232. package/dist/documents/web/LivePreviewPane.js +58 -0
  233. package/dist/env.d.ts +66 -0
  234. package/dist/index.d.ts +121 -0
  235. package/dist/index.js +123 -0
  236. package/dist/settings/AppearanceMenu.d.ts +9 -0
  237. package/dist/settings/AppearanceMenu.js +54 -0
  238. package/dist/settings/SettingsPanel.d.ts +7 -0
  239. package/dist/settings/SettingsPanel.js +104 -0
  240. package/dist/settings/publishedSections.d.ts +22 -0
  241. package/dist/settings/publishedSections.js +79 -0
  242. package/dist/settings/sections/AboutSection.d.ts +1 -0
  243. package/dist/settings/sections/AboutSection.js +13 -0
  244. package/dist/settings/sections/DiagnosticsSection.d.ts +1 -0
  245. package/dist/settings/sections/DiagnosticsSection.js +42 -0
  246. package/dist/settings/sections/PrivacySection.d.ts +3 -0
  247. package/dist/settings/sections/PrivacySection.js +51 -0
  248. package/dist/settings/sections/UpdateLicenseBlock.d.ts +10 -0
  249. package/dist/settings/sections/UpdateLicenseBlock.js +158 -0
  250. package/dist/state/explorer.d.ts +32 -0
  251. package/dist/state/explorer.js +111 -0
  252. package/dist/state/legal.d.ts +51 -0
  253. package/dist/state/legal.js +130 -0
  254. package/dist/state/library.d.ts +33 -0
  255. package/dist/state/library.js +110 -0
  256. package/dist/state/updateLicense.d.ts +31 -0
  257. package/dist/state/updateLicense.js +340 -0
  258. package/dist/styles/explorer.css +219 -0
  259. package/dist/styles/index.css +1477 -0
  260. package/dist/styles/tabs.css +467 -0
  261. package/dist/styles.css +6 -0
  262. package/package.json +88 -3
@@ -0,0 +1,47 @@
1
+ import { useCallback, useState } from "react";
2
+ import { resolveDocumentDrafts } from "./draftResolution.js";
3
+ /**
4
+ * The draft-confirm chooser state + its gate. `requestDraftAwareViewChange` wraps a view change so
5
+ * a modified block draft first opens the Done/Discard/Cancel chooser (Done commits, Discard drops,
6
+ * Cancel stays on the current view with the editor open); a draft-free document proceeds
7
+ * immediately. Extracted verbatim from useDocuments; bodies are unchanged.
8
+ */
9
+ export function useDraftConfirmGate({ blockDrafts }) {
10
+ const [draftConfirm, setDraftConfirm] = useState(null);
11
+ const confirmDraftDone = useCallback(async () => {
12
+ const c = draftConfirm;
13
+ if (!c)
14
+ return;
15
+ setDraftConfirm(null);
16
+ const outcome = await resolveDocumentDrafts(blockDrafts, c.documentPath, c.intent, "done");
17
+ if (outcome === "resolved")
18
+ c.onResolved();
19
+ }, [draftConfirm, blockDrafts]);
20
+ const confirmDraftDiscard = useCallback(async () => {
21
+ const c = draftConfirm;
22
+ if (!c)
23
+ return;
24
+ setDraftConfirm(null);
25
+ const outcome = await resolveDocumentDrafts(blockDrafts, c.documentPath, c.intent, "discard");
26
+ if (outcome === "resolved")
27
+ c.onResolved();
28
+ }, [draftConfirm, blockDrafts]);
29
+ const confirmDraftCancel = useCallback(() => setDraftConfirm(null), []);
30
+ // Gate a view change on the active document's modified drafts: open the Done/Discard/Cancel
31
+ // chooser when a draft exists, else proceed immediately.
32
+ const requestDraftAwareViewChange = useCallback((path, proceed) => {
33
+ if (blockDrafts.snapshotModified(path).length > 0) {
34
+ setDraftConfirm({ documentPath: path, intent: "view-change", onResolved: proceed });
35
+ return;
36
+ }
37
+ proceed();
38
+ }, [blockDrafts]);
39
+ return {
40
+ draftConfirm,
41
+ setDraftConfirm,
42
+ confirmDraftDone,
43
+ confirmDraftDiscard,
44
+ confirmDraftCancel,
45
+ requestDraftAwareViewChange,
46
+ };
47
+ }
@@ -0,0 +1,12 @@
1
+ import { type DragEvent } from "react";
2
+ /** Root-level file-drag "Drop to open" overlay state + handlers, extracted from App.tsx. */
3
+ export declare function useFileDragOverlay(): {
4
+ dragOver: boolean;
5
+ rootDragProps: {
6
+ onDragEnter: (e: DragEvent) => void;
7
+ onDragOver: (e: DragEvent) => void;
8
+ onDragLeave: (e: DragEvent) => void;
9
+ onDrop: () => void;
10
+ };
11
+ };
12
+ export declare function DropOverlay(): import("react").JSX.Element;
@@ -0,0 +1,49 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useRef, useState } from "react";
3
+ const hasFileDrag = (types) => {
4
+ if (!types)
5
+ return false;
6
+ if (typeof types.includes === "function")
7
+ return types.includes("Files");
8
+ const domStringList = types;
9
+ return typeof domStringList.contains === "function" && domStringList.contains("Files");
10
+ };
11
+ /** Root-level file-drag "Drop to open" overlay state + handlers, extracted from App.tsx. */
12
+ export function useFileDragOverlay() {
13
+ const [dragOver, setDragOver] = useState(false);
14
+ const dragCounter = useRef(0);
15
+ const rootDragProps = {
16
+ onDragEnter: (e) => {
17
+ if (hasFileDrag(e.dataTransfer?.types)) {
18
+ e.preventDefault();
19
+ dragCounter.current++;
20
+ setDragOver(true);
21
+ }
22
+ },
23
+ onDragOver: (e) => {
24
+ if (hasFileDrag(e.dataTransfer?.types)) {
25
+ e.preventDefault();
26
+ if (e.dataTransfer)
27
+ e.dataTransfer.dropEffect = "copy";
28
+ }
29
+ },
30
+ onDragLeave: (e) => {
31
+ if (dragOver || hasFileDrag(e.dataTransfer?.types)) {
32
+ e.preventDefault();
33
+ dragCounter.current--;
34
+ if (dragCounter.current <= 0) {
35
+ dragCounter.current = 0;
36
+ setDragOver(false);
37
+ }
38
+ }
39
+ },
40
+ onDrop: () => {
41
+ dragCounter.current = 0;
42
+ setDragOver(false);
43
+ },
44
+ };
45
+ return { dragOver, rootDragProps };
46
+ }
47
+ export function DropOverlay() {
48
+ return (_jsx("div", { className: "fixed inset-0 z-[100] pointer-events-none flex items-center justify-center bg-copper/10 border-2 border-dashed border-copper/50", children: _jsx("div", { className: "rounded-lg bg-panel-2 px-6 py-4 shadow-2xl border border-copper/30 font-sans text-sm text-copper-hi", children: "Drop to open" }) }));
49
+ }
@@ -0,0 +1,13 @@
1
+ import type { DocxMenuApi } from "@rightkit/docx-editor/documents/docx/menuApi";
2
+ import type { LoadedDocument } from "@rightkit/document-core/documents/types";
3
+ import type { MarkdownExportApi } from "@rightkit/markdown-editor/documents/markdown/export/markdownExportTypes";
4
+ /** Single-active-slot APIs the mounted format panes register (DOCX menu, PDF print, Markdown export)
5
+ * plus the print router that prefers them. Extracted verbatim from App.tsx. */
6
+ export declare function useFormatApis(onPrint: (doc: LoadedDocument | null) => void): {
7
+ docxMenu: DocxMenuApi | null;
8
+ setDocxMenu: import("react").Dispatch<import("react").SetStateAction<DocxMenuApi | null>>;
9
+ markdownExport: MarkdownExportApi | null;
10
+ registerPdfPrint: (fn: (() => Promise<boolean>) | null) => void;
11
+ registerMarkdownExport: (api: MarkdownExportApi | null) => void;
12
+ handlePrint: (doc: LoadedDocument | null) => void;
13
+ };
@@ -0,0 +1,62 @@
1
+ import { useCallback, useState } from "react";
2
+ import { toast } from "@rightkit/platform-ui/headless";
3
+ import { logError } from "@rightkit/document-core/state/diagnostics";
4
+ import { printHtmlMarkup } from "@rightkit/document-core/app/documentPrinting";
5
+ /** Single-active-slot APIs the mounted format panes register (DOCX menu, PDF print, Markdown export)
6
+ * plus the print router that prefers them. Extracted verbatim from App.tsx. */
7
+ export function useFormatApis(onPrint) {
8
+ const [docxMenu, setDocxMenu] = useState(null);
9
+ // The active PDF pane's own print function, using the PDFDocumentProxy it already has loaded/
10
+ // rendering on screen — NOT a fresh fetch of the same viewright-stream:// URL, which hung
11
+ // indefinitely with no error (see documentPrinting.ts printPdf's fallback for the no-registration
12
+ // case). Mirrors the docxMenu single-active-slot pattern above.
13
+ const [pdfPrint, setPdfPrint] = useState(null);
14
+ const [markdownExport, setMarkdownExport] = useState(null);
15
+ // MUST wrap in an extra arrow: React useState setters treat a bare function argument as an updater
16
+ // `(prev) => next`, so `setPdfPrint(fn)` would INVOKE the print function at registration time and
17
+ // store its Promise instead of the function. That made every later `pdfPrint()` call throw
18
+ // synchronously — no dialog, no toast, no timeout, which is exactly how PDF print "did nothing".
19
+ const registerPdfPrint = useCallback((fn) => setPdfPrint(() => fn), []);
20
+ const registerMarkdownExport = useCallback((api) => setMarkdownExport(api), []);
21
+ // Route PDF print through the active pane's registered function when available; every other
22
+ // format keeps using useDocuments' onPrint unchanged.
23
+ const handlePrint = useCallback((doc) => {
24
+ if (doc?.format === "pdf" && pdfPrint) {
25
+ void pdfPrint()
26
+ .then((printed) => {
27
+ if (printed)
28
+ return;
29
+ logError("print:failed:pdf");
30
+ toast("Couldn't open print dialog", "error");
31
+ })
32
+ .catch(() => {
33
+ logError("print:failed:pdf");
34
+ toast("Couldn't open print dialog", "error");
35
+ });
36
+ return;
37
+ }
38
+ if (doc?.format === "md" && markdownExport?.documentPath === doc.path) {
39
+ void markdownExport
40
+ .createSnapshot()
41
+ .then(async (snapshot) => {
42
+ const printed = await printHtmlMarkup(snapshot.htmlFragment);
43
+ if (!printed)
44
+ throw new Error("Print dialog did not open");
45
+ if (snapshot.warnings.length) {
46
+ toast(`Printed with ${snapshot.warnings.length} warning${snapshot.warnings.length === 1 ? "" : "s"}`, "info");
47
+ }
48
+ })
49
+ .catch(() => {
50
+ logError("print:failed:md");
51
+ toast("Couldn't open print dialog", "error");
52
+ });
53
+ return;
54
+ }
55
+ if (doc?.format === "md") {
56
+ toast("Markdown renderer is still loading", "info");
57
+ return;
58
+ }
59
+ onPrint(doc);
60
+ }, [markdownExport, pdfPrint, onPrint]);
61
+ return { docxMenu, setDocxMenu, markdownExport, registerPdfPrint, registerMarkdownExport, handlePrint };
62
+ }
@@ -0,0 +1,29 @@
1
+ import { type Dispatch, type SetStateAction } from "react";
2
+ import type { ImageSaveFunction, ImageSavePayload } from "@rightkit/media-ui";
3
+ import type { PdfSaveFunction } from "@rightkit/document-core/documents/pdf/pdfEditor";
4
+ import type { PdfSavePlan } from "@rightkit/document-core/documents/pdf/pdfEditModel";
5
+ interface FormatDirtyStateDeps {
6
+ setError: Dispatch<SetStateAction<string | null>>;
7
+ setDocxDirty: Dispatch<SetStateAction<Set<string>>>;
8
+ setPdfDirty: Dispatch<SetStateAction<Set<string>>>;
9
+ setImageDirty: Dispatch<SetStateAction<Set<string>>>;
10
+ markSelfSaved: (path: string) => void;
11
+ refreshFingerprint: (path: string) => void;
12
+ onDirty?: (path: string) => void;
13
+ }
14
+ export declare function useFormatDirtyState({ setError, setDocxDirty, setPdfDirty, setImageDirty, markSelfSaved, refreshFingerprint, onDirty, }: FormatDirtyStateDeps): {
15
+ docxSaver: import("react").RefObject<(() => Promise<ArrayBuffer | null>) | null>;
16
+ imageSaver: import("react").RefObject<ImageSaveFunction | null>;
17
+ docxSaversRef: import("react").RefObject<Map<string, () => Promise<ArrayBuffer | null>>>;
18
+ pdfSaversRef: import("react").RefObject<Map<string, PdfSaveFunction>>;
19
+ pdfSavePlansRef: import("react").RefObject<Map<string, () => Promise<PdfSavePlan>>>;
20
+ imageSaversRef: import("react").RefObject<Map<string, ImageSaveFunction>>;
21
+ onDocxSave: (path: string, buffer: ArrayBuffer) => Promise<void>;
22
+ onDocxChange: (path: string) => void;
23
+ onPdfDirtyChange: (path: string, dirty: boolean) => void;
24
+ onImageChange: (path: string) => void;
25
+ clearImageDirty: (path: string) => void;
26
+ restoreImageDirty: (path: string) => void;
27
+ writeImagePayload: (path: string, payload: ImageSavePayload) => Promise<void>;
28
+ };
29
+ export {};
@@ -0,0 +1,81 @@
1
+ import { useCallback, useRef } from "react";
2
+ import { writeDocumentBytes } from "@rightkit/document-core/state/tauriBridge";
3
+ import { errorMessage } from "@rightkit/document-core/state/errors";
4
+ export function useFormatDirtyState({ setError, setDocxDirty, setPdfDirty, setImageDirty, markSelfSaved, refreshFingerprint, onDirty, }) {
5
+ const docxSaver = useRef(null);
6
+ const pdfSaversRef = useRef(new Map());
7
+ const pdfSavePlansRef = useRef(new Map());
8
+ const imageSaver = useRef(null);
9
+ const docxSaversRef = useRef(new Map());
10
+ const imageSaversRef = useRef(new Map());
11
+ // One dirty-set pattern for DOCX and image: a path is added or removed through these helpers,
12
+ // each a no-op when the set already matches (so repeated edits never churn state).
13
+ const addDirtyPath = useCallback((setter, path) => {
14
+ setter((s) => (s.has(path) ? s : new Set(s).add(path)));
15
+ }, []);
16
+ const removeDirtyPath = useCallback((setter, path) => {
17
+ setter((s) => {
18
+ if (!s.has(path))
19
+ return s;
20
+ const n = new Set(s);
21
+ n.delete(path);
22
+ return n;
23
+ });
24
+ }, []);
25
+ const onDocxSave = useCallback(async (path, buffer) => {
26
+ try {
27
+ await writeDocumentBytes(path, buffer);
28
+ markSelfSaved(path);
29
+ refreshFingerprint(path);
30
+ removeDirtyPath(setDocxDirty, path);
31
+ }
32
+ catch (e) {
33
+ setError(errorMessage(e));
34
+ }
35
+ }, [markSelfSaved, refreshFingerprint, removeDirtyPath, setDocxDirty, setError]);
36
+ const onDocxChange = useCallback((path) => {
37
+ addDirtyPath(setDocxDirty, path);
38
+ onDirty?.(path);
39
+ }, [addDirtyPath, onDirty, setDocxDirty]);
40
+ const onPdfDirtyChange = useCallback((path, dirty) => {
41
+ setPdfDirty((paths) => {
42
+ if (dirty === paths.has(path))
43
+ return paths;
44
+ const next = new Set(paths);
45
+ if (dirty)
46
+ next.add(path);
47
+ else
48
+ next.delete(path);
49
+ return next;
50
+ });
51
+ if (dirty)
52
+ onDirty?.(path);
53
+ }, [onDirty, setPdfDirty]);
54
+ const onImageChange = useCallback((path) => {
55
+ addDirtyPath(setImageDirty, path);
56
+ onDirty?.(path);
57
+ }, [addDirtyPath, onDirty, setImageDirty]);
58
+ const clearImageDirty = useCallback((path) => removeDirtyPath(setImageDirty, path), [removeDirtyPath, setImageDirty]);
59
+ const restoreImageDirty = useCallback((path) => addDirtyPath(setImageDirty, path), [addDirtyPath, setImageDirty]);
60
+ const writeImagePayload = useCallback(async (path, payload) => {
61
+ await writeDocumentBytes(path, payload.buffer);
62
+ markSelfSaved(path);
63
+ refreshFingerprint(path);
64
+ removeDirtyPath(setImageDirty, path);
65
+ }, [markSelfSaved, refreshFingerprint, removeDirtyPath, setImageDirty]);
66
+ return {
67
+ docxSaver,
68
+ imageSaver,
69
+ docxSaversRef,
70
+ pdfSaversRef,
71
+ pdfSavePlansRef,
72
+ imageSaversRef,
73
+ onDocxSave,
74
+ onDocxChange,
75
+ onPdfDirtyChange,
76
+ onImageChange,
77
+ clearImageDirty,
78
+ restoreImageDirty,
79
+ writeImagePayload,
80
+ };
81
+ }
@@ -0,0 +1,47 @@
1
+ import type { LoadedDocument, SearchProvider } from "@rightkit/document-core/documents/types";
2
+ import type { DocxMenuApi } from "@rightkit/docx-editor/documents/docx/menuApi";
3
+ interface Options {
4
+ active: LoadedDocument | null;
5
+ activeEditable: boolean;
6
+ searchProvider: SearchProvider | null;
7
+ canOpenFind?: boolean;
8
+ docxMenu: DocxMenuApi | null;
9
+ newDocument: () => void;
10
+ onOpenDialog: () => void;
11
+ onPrint: (doc: LoadedDocument | null) => void;
12
+ onSave: (doc: LoadedDocument) => void;
13
+ onSaveAs: (doc: LoadedDocument) => void;
14
+ requestClose: (path: string) => void;
15
+ togglePalette: () => void;
16
+ openFind: (replace: boolean) => void;
17
+ /** HTML Ctrl+S: one dirty page saves directly; several open the page-aware chooser. */
18
+ onHtmlSaveShortcut: (entryPath: string) => void;
19
+ /** Re-read the active doc from disk (browser-style refresh) — for non-HTML formats. HTML refresh is
20
+ * routed through a window event so the HtmlDocument reloads its current page + rebuilds the preview. */
21
+ reloadActiveFromDisk: (doc: LoadedDocument) => void;
22
+ /** Open whatever's on the clipboard (Ctrl+V / Ctrl+Shift+V): text → new draft, image → temp .bmp,
23
+ * files → open like drag-drop. Only fires outside a text field so editors keep their own paste. */
24
+ openFromClipboard: () => void;
25
+ /** Tab navigation: cycle next (+1) / previous (-1) through the open tabs. */
26
+ cycleTab: (dir: 1 | -1) => void;
27
+ /** Jump to the Nth open tab (0-based; the help overlay maps Ctrl+1..9). */
28
+ jumpToTab: (index: number) => void;
29
+ /** Reopen the most-recently-closed file/web tab (Ctrl+Shift+T). */
30
+ reopenClosed: () => void;
31
+ /** Reset the active surface's zoom/font size to its default (Ctrl+0). */
32
+ resetZoom: () => void;
33
+ /** Toggle source/text word wrap (Alt+Z). */
34
+ toggleWordWrap: () => void;
35
+ /** Toggle the sidebar (Ctrl+E / Ctrl+\). */
36
+ toggleSidebar: () => void;
37
+ /** Toggle the tab-overview card grid (Ctrl/Cmd+Shift+A). */
38
+ toggleTabOverview: () => void;
39
+ /** Show the keyboard-shortcut help overlay (?). */
40
+ showHelp: () => void;
41
+ /** Whether the find bar is currently open (drives F3 step-vs-open). */
42
+ findOpen: boolean;
43
+ /** Toggle distraction-free reading (Ctrl+Shift+F) — hides sidebar + toolbars. */
44
+ toggleDistractionFree: () => void;
45
+ }
46
+ export declare function useGlobalShortcuts({ active, activeEditable, searchProvider, canOpenFind, docxMenu, newDocument, onOpenDialog, onPrint, onSave, onSaveAs, requestClose, togglePalette, openFind, onHtmlSaveShortcut, reloadActiveFromDisk, openFromClipboard, cycleTab, jumpToTab, reopenClosed, resetZoom, toggleWordWrap, toggleSidebar, toggleTabOverview, showHelp, findOpen, toggleDistractionFree, }: Options): void;
47
+ export {};