@open-press/cli 0.8.0 → 1.1.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 (250) hide show
  1. package/README.md +33 -23
  2. package/dist/cli.js +320 -252
  3. package/package.json +9 -8
  4. package/template/core/AGENTS.md +0 -126
  5. package/template/core/CHANGELOG.md +0 -215
  6. package/template/core/README.md +0 -40
  7. package/template/core/engine/cli.mjs +0 -96
  8. package/template/core/engine/commands/_shared.mjs +0 -177
  9. package/template/core/engine/commands/deploy.mjs +0 -31
  10. package/template/core/engine/commands/dev.mjs +0 -49
  11. package/template/core/engine/commands/doctor.mjs +0 -229
  12. package/template/core/engine/commands/export.mjs +0 -8
  13. package/template/core/engine/commands/init.mjs +0 -24
  14. package/template/core/engine/commands/inspect.mjs +0 -35
  15. package/template/core/engine/commands/pdf.mjs +0 -26
  16. package/template/core/engine/commands/preview.mjs +0 -26
  17. package/template/core/engine/commands/render.mjs +0 -17
  18. package/template/core/engine/commands/replace.mjs +0 -41
  19. package/template/core/engine/commands/search.mjs +0 -33
  20. package/template/core/engine/commands/typecheck.mjs +0 -5
  21. package/template/core/engine/commands/upgrade.mjs +0 -159
  22. package/template/core/engine/commands/validate.mjs +0 -17
  23. package/template/core/engine/document-export.mjs +0 -15
  24. package/template/core/engine/init.mjs +0 -90
  25. package/template/core/engine/output/chrome-pdf.d.mts +0 -34
  26. package/template/core/engine/output/chrome-pdf.mjs +0 -358
  27. package/template/core/engine/output/deploy-sync.mjs +0 -15
  28. package/template/core/engine/output/fonts.mjs +0 -62
  29. package/template/core/engine/output/katex-assets.mjs +0 -45
  30. package/template/core/engine/output/page-block.mjs +0 -30
  31. package/template/core/engine/output/pdf-media.mjs +0 -45
  32. package/template/core/engine/output/public-assets.mjs +0 -19
  33. package/template/core/engine/output/static-server.mjs +0 -532
  34. package/template/core/engine/react/caption-numbering.mjs +0 -73
  35. package/template/core/engine/react/comment-endpoint.d.mts +0 -11
  36. package/template/core/engine/react/comment-endpoint.mjs +0 -102
  37. package/template/core/engine/react/comment-marker.mjs +0 -374
  38. package/template/core/engine/react/document-entry.mjs +0 -324
  39. package/template/core/engine/react/document-export.mjs +0 -373
  40. package/template/core/engine/react/http-json.mjs +0 -24
  41. package/template/core/engine/react/mdx-compile.mjs +0 -599
  42. package/template/core/engine/react/measurement-css.mjs +0 -136
  43. package/template/core/engine/react/object-entities.mjs +0 -119
  44. package/template/core/engine/react/pagination/allocator.mjs +0 -122
  45. package/template/core/engine/react/pagination/regions.mjs +0 -81
  46. package/template/core/engine/react/pagination-constants.mjs +0 -3
  47. package/template/core/engine/react/pagination.mjs +0 -9
  48. package/template/core/engine/react/pipeline/allocate.mjs +0 -251
  49. package/template/core/engine/react/pipeline/final-render.mjs +0 -94
  50. package/template/core/engine/react/pipeline/frame-measurement.mjs +0 -302
  51. package/template/core/engine/react/pipeline/press-tree.mjs +0 -135
  52. package/template/core/engine/react/project-asset-endpoint.d.mts +0 -10
  53. package/template/core/engine/react/project-asset-endpoint.mjs +0 -361
  54. package/template/core/engine/react/section-css.mjs +0 -56
  55. package/template/core/engine/react/source-edit-endpoint.d.mts +0 -10
  56. package/template/core/engine/react/source-edit-endpoint.mjs +0 -75
  57. package/template/core/engine/react/sources/heading-numbering.mjs +0 -132
  58. package/template/core/engine/react/sources/mdx-resolver.mjs +0 -439
  59. package/template/core/engine/react/style-discovery.mjs +0 -142
  60. package/template/core/engine/runtime/config.d.mts +0 -40
  61. package/template/core/engine/runtime/config.mjs +0 -175
  62. package/template/core/engine/runtime/file-utils.mjs +0 -106
  63. package/template/core/engine/runtime/file-walk.mjs +0 -22
  64. package/template/core/engine/runtime/inspection.mjs +0 -328
  65. package/template/core/engine/runtime/issue-report.mjs +0 -44
  66. package/template/core/engine/runtime/path-utils.mjs +0 -20
  67. package/template/core/engine/runtime/source-text-tools.d.mts +0 -102
  68. package/template/core/engine/runtime/source-text-tools.mjs +0 -832
  69. package/template/core/engine/runtime/source-workspace.mjs +0 -159
  70. package/template/core/engine/runtime/validation.mjs +0 -174
  71. package/template/core/index.html +0 -13
  72. package/template/core/openpress.config.mjs +0 -12
  73. package/template/core/package.json +0 -91
  74. package/template/core/src/main.tsx +0 -16
  75. package/template/core/src/openpress/app/OpenPressApp.tsx +0 -140
  76. package/template/core/src/openpress/app/OpenPressRuntime.tsx +0 -94
  77. package/template/core/src/openpress/app/index.ts +0 -2
  78. package/template/core/src/openpress/core/Frame.tsx +0 -78
  79. package/template/core/src/openpress/core/FrameContext.tsx +0 -24
  80. package/template/core/src/openpress/core/MdxArea.tsx +0 -34
  81. package/template/core/src/openpress/core/Press.tsx +0 -34
  82. package/template/core/src/openpress/core/cn.ts +0 -4
  83. package/template/core/src/openpress/core/index.tsx +0 -40
  84. package/template/core/src/openpress/core/primitives.tsx +0 -44
  85. package/template/core/src/openpress/core/types.ts +0 -191
  86. package/template/core/src/openpress/core/useSource.ts +0 -28
  87. package/template/core/src/openpress/document-model/anchorMapModel.ts +0 -27
  88. package/template/core/src/openpress/document-model/documentIndexes.ts +0 -329
  89. package/template/core/src/openpress/document-model/documentTypes.ts +0 -138
  90. package/template/core/src/openpress/document-model/index.ts +0 -6
  91. package/template/core/src/openpress/document-model/objectEntityModel.ts +0 -51
  92. package/template/core/src/openpress/document-model/projectIdentityModel.ts +0 -15
  93. package/template/core/src/openpress/document-model/reactDocumentMetadataModel.ts +0 -27
  94. package/template/core/src/openpress/manuscript/index.tsx +0 -238
  95. package/template/core/src/openpress/mdx/index.ts +0 -88
  96. package/template/core/src/openpress/numbering/index.ts +0 -294
  97. package/template/core/src/openpress/reader/PublicReaderPage.tsx +0 -267
  98. package/template/core/src/openpress/reader/ReaderNavigationPanel.tsx +0 -123
  99. package/template/core/src/openpress/reader/index.ts +0 -10
  100. package/template/core/src/openpress/reader/pageViewportScaleModel.ts +0 -73
  101. package/template/core/src/openpress/reader/readerPageRegistry.ts +0 -41
  102. package/template/core/src/openpress/reader/readerPageRoute.ts +0 -21
  103. package/template/core/src/openpress/reader/readerScroll.ts +0 -92
  104. package/template/core/src/openpress/reader/readerStateModel.ts +0 -15
  105. package/template/core/src/openpress/reader/readerTypes.ts +0 -4
  106. package/template/core/src/openpress/reader/usePageViewportScale.ts +0 -119
  107. package/template/core/src/openpress/reader/usePanelState.ts +0 -56
  108. package/template/core/src/openpress/reader/useReaderHashSync.ts +0 -61
  109. package/template/core/src/openpress/reader/useReaderKeyboardNav.ts +0 -48
  110. package/template/core/src/openpress/reader/useReaderRuntime.ts +0 -146
  111. package/template/core/src/openpress/reader/useReaderScrollAnchor.ts +0 -64
  112. package/template/core/src/openpress/shared/Panel.tsx +0 -77
  113. package/template/core/src/openpress/shared/frameScheduler.ts +0 -32
  114. package/template/core/src/openpress/shared/index.ts +0 -4
  115. package/template/core/src/openpress/shared/numberUtils.ts +0 -3
  116. package/template/core/src/openpress/shared/runtimeMode.ts +0 -11
  117. package/template/core/src/openpress/workbench/Workbench.tsx +0 -407
  118. package/template/core/src/openpress/workbench/actions/DeploymentControl.tsx +0 -157
  119. package/template/core/src/openpress/workbench/actions/PageZoomControl.tsx +0 -182
  120. package/template/core/src/openpress/workbench/actions/SearchControl.tsx +0 -345
  121. package/template/core/src/openpress/workbench/actions/deploymentStatusModel.ts +0 -112
  122. package/template/core/src/openpress/workbench/actions/index.ts +0 -5
  123. package/template/core/src/openpress/workbench/actions/useDeploymentWorkbench.ts +0 -136
  124. package/template/core/src/openpress/workbench/dialog/WorkbenchDialog.tsx +0 -72
  125. package/template/core/src/openpress/workbench/dialog/index.ts +0 -1
  126. package/template/core/src/openpress/workbench/document/components/DocumentPanel.tsx +0 -127
  127. package/template/core/src/openpress/workbench/document/components/InlineSourceEditorLayer.tsx +0 -207
  128. package/template/core/src/openpress/workbench/document/components/ReaderStage.tsx +0 -9
  129. package/template/core/src/openpress/workbench/document/hooks/useDocumentWorkbenchModel.ts +0 -34
  130. package/template/core/src/openpress/workbench/document/hooks/useInlineDocumentEditor.ts +0 -525
  131. package/template/core/src/openpress/workbench/document/index.ts +0 -10
  132. package/template/core/src/openpress/workbench/index.ts +0 -2
  133. package/template/core/src/openpress/workbench/inspector/InlineInspectorLayer.tsx +0 -459
  134. package/template/core/src/openpress/workbench/inspector/index.ts +0 -5
  135. package/template/core/src/openpress/workbench/inspector/inlineCommentModel.ts +0 -125
  136. package/template/core/src/openpress/workbench/inspector/inspectorGeometryModel.ts +0 -160
  137. package/template/core/src/openpress/workbench/inspector/inspectorModel.ts +0 -408
  138. package/template/core/src/openpress/workbench/inspector/useInspectorComments.ts +0 -248
  139. package/template/core/src/openpress/workbench/mentions/MentionSuggestionList.tsx +0 -41
  140. package/template/core/src/openpress/workbench/mentions/index.ts +0 -2
  141. package/template/core/src/openpress/workbench/mentions/useComposerMentions.ts +0 -185
  142. package/template/core/src/openpress/workbench/panels/Panel.tsx +0 -1
  143. package/template/core/src/openpress/workbench/panels/PendingCommentsPanel.tsx +0 -76
  144. package/template/core/src/openpress/workbench/panels/WorkbenchControlPanel.tsx +0 -29
  145. package/template/core/src/openpress/workbench/panels/index.ts +0 -3
  146. package/template/core/src/openpress/workbench/project/ProjectEntryPanel.tsx +0 -523
  147. package/template/core/src/openpress/workbench/project/ProjectPreviewDialog.tsx +0 -35
  148. package/template/core/src/openpress/workbench/project/index.ts +0 -2
  149. package/template/core/src/openpress/workbench/project/projectPreviewTypes.ts +0 -11
  150. package/template/core/src/openpress/workbench/project/projectSourceModel.ts +0 -24
  151. package/template/core/src/openpress/workbench/shell/WorkbenchShell.tsx +0 -167
  152. package/template/core/src/openpress/workbench/shell/index.ts +0 -1
  153. package/template/core/src/openpress/workbench/workbenchFormatters.ts +0 -120
  154. package/template/core/src/openpress/workbench/workbenchTypes.ts +0 -35
  155. package/template/core/src/styles/openpress/app-shell.css +0 -251
  156. package/template/core/src/styles/openpress/media-workspace.css +0 -230
  157. package/template/core/src/styles/openpress/print-route.css +0 -184
  158. package/template/core/src/styles/openpress/project-preview-panel.css +0 -924
  159. package/template/core/src/styles/openpress/public-viewer.css +0 -688
  160. package/template/core/src/styles/openpress/reader-runtime.css +0 -980
  161. package/template/core/src/styles/openpress/responsive.css +0 -245
  162. package/template/core/src/styles/openpress/workbench-panels.css +0 -594
  163. package/template/core/src/styles/openpress/workbench.css +0 -1255
  164. package/template/core/src/styles/openpress.css +0 -14
  165. package/template/core/src/vite-env.d.ts +0 -9
  166. package/template/core/tsconfig.json +0 -40
  167. package/template/core/vite.config.ts +0 -584
  168. package/template/packs/academic-paper/document/chapters/01-introduction/content/01-introduction.mdx +0 -35
  169. package/template/packs/academic-paper/document/chapters/02-methods/content/01-methods.mdx +0 -50
  170. package/template/packs/academic-paper/document/chapters/03-results-and-discussion/content/01-results.mdx +0 -47
  171. package/template/packs/academic-paper/document/chapters/04-acknowledgment/content/01-acknowledgment.mdx +0 -26
  172. package/template/packs/academic-paper/document/chapters/05-references/content/01-references.mdx +0 -32
  173. package/template/packs/academic-paper/document/components/ChapterOpenerVisual/index.tsx +0 -76
  174. package/template/packs/academic-paper/document/components/Page.tsx +0 -60
  175. package/template/packs/academic-paper/document/components/TokenSwatchGrid/index.tsx +0 -46
  176. package/template/packs/academic-paper/document/components/TokenSwatchGrid/style.css +0 -63
  177. package/template/packs/academic-paper/document/components/TypeSpecimen/index.tsx +0 -38
  178. package/template/packs/academic-paper/document/components/TypeSpecimen/style.css +0 -111
  179. package/template/packs/academic-paper/document/design.md +0 -279
  180. package/template/packs/academic-paper/document/index.tsx +0 -123
  181. package/template/packs/academic-paper/document/media/README.md +0 -13
  182. package/template/packs/academic-paper/document/media/figure-placeholder.svg +0 -9
  183. package/template/packs/academic-paper/document/openpress.config.mjs +0 -26
  184. package/template/packs/academic-paper/document/theme/README.md +0 -11
  185. package/template/packs/academic-paper/document/theme/base/page-contract.css +0 -522
  186. package/template/packs/academic-paper/document/theme/base/print.css +0 -93
  187. package/template/packs/academic-paper/document/theme/base/typography.css +0 -333
  188. package/template/packs/academic-paper/document/theme/fonts.css +0 -3
  189. package/template/packs/academic-paper/document/theme/page-surfaces/back-cover.css +0 -43
  190. package/template/packs/academic-paper/document/theme/page-surfaces/chapter-opener.css +0 -205
  191. package/template/packs/academic-paper/document/theme/page-surfaces/cover.css +0 -294
  192. package/template/packs/academic-paper/document/theme/page-surfaces/toc.css +0 -149
  193. package/template/packs/academic-paper/document/theme/patterns/_chart-frame.css +0 -49
  194. package/template/packs/academic-paper/document/theme/patterns/figure-grid.css +0 -68
  195. package/template/packs/academic-paper/document/theme/patterns/table-utilities.css +0 -66
  196. package/template/packs/academic-paper/document/theme/shell/reader-controls.css +0 -761
  197. package/template/packs/academic-paper/document/theme/tokens.css +0 -80
  198. package/template/packs/academic-paper/openpress.config.mjs +0 -5
  199. package/template/packs/claude-document/document/chapters/01-document-shape/content/01-document-shape.mdx +0 -51
  200. package/template/packs/claude-document/document/chapters/02-review-loop/content/01-review-loop.mdx +0 -31
  201. package/template/packs/claude-document/document/components/ChapterOpenerVisual.tsx +0 -96
  202. package/template/packs/claude-document/document/components/Page.tsx +0 -37
  203. package/template/packs/claude-document/document/design.md +0 -142
  204. package/template/packs/claude-document/document/index.tsx +0 -94
  205. package/template/packs/claude-document/document/media/README.md +0 -13
  206. package/template/packs/claude-document/document/openpress.config.mjs +0 -26
  207. package/template/packs/claude-document/document/theme/README.md +0 -15
  208. package/template/packs/claude-document/document/theme/base/page-contract.css +0 -525
  209. package/template/packs/claude-document/document/theme/base/print.css +0 -93
  210. package/template/packs/claude-document/document/theme/base/typography.css +0 -612
  211. package/template/packs/claude-document/document/theme/fonts.css +0 -4
  212. package/template/packs/claude-document/document/theme/page-surfaces/back-cover.css +0 -72
  213. package/template/packs/claude-document/document/theme/page-surfaces/chapter-opener.css +0 -236
  214. package/template/packs/claude-document/document/theme/page-surfaces/cover.css +0 -309
  215. package/template/packs/claude-document/document/theme/page-surfaces/toc.css +0 -225
  216. package/template/packs/claude-document/document/theme/patterns/_chart-frame.css +0 -53
  217. package/template/packs/claude-document/document/theme/patterns/figure-grid.css +0 -68
  218. package/template/packs/claude-document/document/theme/patterns/table-utilities.css +0 -66
  219. package/template/packs/claude-document/document/theme/shell/reader-controls.css +0 -789
  220. package/template/packs/claude-document/document/theme/tokens.css +0 -89
  221. package/template/packs/claude-document/openpress.config.mjs +0 -5
  222. package/template/packs/editorial-monograph/document/chapters/01-product-and-use-cases/content/01-product-and-use-cases.mdx +0 -31
  223. package/template/packs/editorial-monograph/document/chapters/02-workflow/content/01-workflow.mdx +0 -89
  224. package/template/packs/editorial-monograph/document/chapters/03-agent-skills-contributors/content/01-agent-skills-contributors.mdx +0 -51
  225. package/template/packs/editorial-monograph/document/chapters/04-validation-deploy/content/01-validation-deploy.mdx +0 -39
  226. package/template/packs/editorial-monograph/document/components/ChapterOpenerVisual/index.tsx +0 -76
  227. package/template/packs/editorial-monograph/document/components/Page.tsx +0 -37
  228. package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/index.tsx +0 -46
  229. package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/style.css +0 -63
  230. package/template/packs/editorial-monograph/document/components/TypeSpecimen/index.tsx +0 -38
  231. package/template/packs/editorial-monograph/document/components/TypeSpecimen/style.css +0 -111
  232. package/template/packs/editorial-monograph/document/design.md +0 -279
  233. package/template/packs/editorial-monograph/document/index.tsx +0 -97
  234. package/template/packs/editorial-monograph/document/media/README.md +0 -13
  235. package/template/packs/editorial-monograph/document/openpress.config.mjs +0 -26
  236. package/template/packs/editorial-monograph/document/theme/README.md +0 -11
  237. package/template/packs/editorial-monograph/document/theme/base/page-contract.css +0 -505
  238. package/template/packs/editorial-monograph/document/theme/base/print.css +0 -93
  239. package/template/packs/editorial-monograph/document/theme/base/typography.css +0 -336
  240. package/template/packs/editorial-monograph/document/theme/fonts.css +0 -3
  241. package/template/packs/editorial-monograph/document/theme/page-surfaces/back-cover.css +0 -43
  242. package/template/packs/editorial-monograph/document/theme/page-surfaces/chapter-opener.css +0 -205
  243. package/template/packs/editorial-monograph/document/theme/page-surfaces/cover.css +0 -147
  244. package/template/packs/editorial-monograph/document/theme/page-surfaces/toc.css +0 -149
  245. package/template/packs/editorial-monograph/document/theme/patterns/_chart-frame.css +0 -49
  246. package/template/packs/editorial-monograph/document/theme/patterns/figure-grid.css +0 -68
  247. package/template/packs/editorial-monograph/document/theme/patterns/table-utilities.css +0 -66
  248. package/template/packs/editorial-monograph/document/theme/shell/reader-controls.css +0 -761
  249. package/template/packs/editorial-monograph/document/theme/tokens.css +0 -80
  250. package/template/packs/editorial-monograph/openpress.config.mjs +0 -5
@@ -1,407 +0,0 @@
1
- import {
2
- useMemo,
3
- useRef,
4
- useState,
5
- type CSSProperties,
6
- } from "react";
7
- import { ExternalLink, MousePointer2, Ruler } from "lucide-react";
8
- import {
9
- getProjectIdentity,
10
- resolveAnchorPageIndex,
11
- type DeploymentInfo,
12
- type HtmlPageBlock,
13
- type ReaderDocument,
14
- } from "../document-model";
15
- import { InlineInspectorLayer, useInspector, useInspectorComments } from "./inspector";
16
- import { ProjectEntryPanel } from "./project";
17
- import {
18
- Bookmarks,
19
- CurrentPagePanel,
20
- PUBLIC_DRAWER_BREAKPOINT,
21
- PublicPage,
22
- useReaderRuntime,
23
- usePageViewportScale,
24
- useViewMode,
25
- type PageLayoutMode,
26
- } from "../reader";
27
- import {
28
- ReaderStage,
29
- InlineSourceEditorLayer,
30
- useDocumentWorkbenchModel,
31
- useInlineDocumentEditor,
32
- type InlineDocumentEditStatus,
33
- type InlineDocumentSourceTarget,
34
- } from "./document";
35
- import {
36
- DeploymentControl,
37
- PageZoomControl,
38
- SearchControl,
39
- useDeploymentWorkbench,
40
- } from "./actions";
41
- import { PendingCommentsPanel, WorkbenchControlPanel, type WorkbenchPanel } from "./panels";
42
- import { WorkbenchShell } from "./shell";
43
- import {
44
- formatPageGeometrySpec,
45
- formatInspectorSelection,
46
- } from "./workbenchFormatters";
47
-
48
- export function HtmlWorkbench({
49
- document,
50
- pages,
51
- style,
52
- devMode,
53
- deploymentInfo,
54
- onDocumentRefresh,
55
- extraControlPanels,
56
- }: {
57
- document: ReaderDocument;
58
- pages: Array<HtmlPageBlock>;
59
- style: CSSProperties;
60
- devMode: boolean;
61
- deploymentInfo: DeploymentInfo;
62
- onDocumentRefresh?: () => void | Promise<void>;
63
- // Append extra panels into the right-side control panel. Built-in panels
64
- // (pending comments + project entry) render first; extra panels render
65
- // after them in the supplied order.
66
- extraControlPanels?: WorkbenchPanel[];
67
- }) {
68
- const sourceContainerRef = useRef<HTMLDivElement | null>(null);
69
- const displayPages = pages;
70
- const { viewMode } = useViewMode();
71
- const {
72
- mediaAssets,
73
- anchorPageMap,
74
- projectComponentUsages,
75
- bookmarks,
76
- sourceBlockMap,
77
- sourceBlocksByPath,
78
- projectMentionItems,
79
- } = useDocumentWorkbenchModel(document, displayPages);
80
- const inspector = useInspector(document, { enabled: devMode });
81
- const reader = useReaderRuntime({
82
- pageCount: Math.max(displayPages.length, 1),
83
- leftPanelBreakpoint: PUBLIC_DRAWER_BREAKPOINT,
84
- rightPanelBreakpoint: PUBLIC_DRAWER_BREAKPOINT,
85
- });
86
- const [pageLayoutMode, setPageLayoutMode] = useState<PageLayoutMode>("single");
87
- const pageViewport = usePageViewportScale({
88
- stageRef: reader.stageRef,
89
- pageContainerRef: sourceContainerRef,
90
- pageCount: displayPages.length,
91
- layoutMode: pageLayoutMode,
92
- });
93
- const deployment = useDeploymentWorkbench({ deploymentInfo });
94
- const [inlineEditStatus, setInlineEditStatus] = useState<InlineDocumentEditStatus>({ state: "idle" });
95
- const [sourceEditorTarget, setSourceEditorTarget] = useState<InlineDocumentSourceTarget | null>(null);
96
-
97
- const projectIdentity = getProjectIdentity(document.meta);
98
- const pageGeometry = formatPageGeometrySpec(document.theme);
99
- const inspectorSelectionLabel = formatInspectorSelection(
100
- inspector.selectedBlock,
101
- inspector.selectedObjectEntity,
102
- );
103
- const inspectorToolbarExpanded = inspector.inspectorMode;
104
- const editStatusMessage = formatInlineEditStatus(inlineEditStatus);
105
-
106
- useInlineDocumentEditor({
107
- enabled: devMode,
108
- sourceContainerRef,
109
- sourceBlockMap,
110
- onStatusChange: setInlineEditStatus,
111
- onOpenSourceBlock: setSourceEditorTarget,
112
- onDocumentEdited: onDocumentRefresh,
113
- });
114
-
115
- const selectWorkspacePage = (pageIndex: number, options?: { behavior?: ScrollBehavior }) => {
116
- reader.setPage(pageIndex, options);
117
- if (
118
- typeof window !== "undefined"
119
- && window.innerWidth < PUBLIC_DRAWER_BREAKPOINT
120
- && reader.rightPanelOpen
121
- ) {
122
- reader.toggleRightPanel();
123
- }
124
- };
125
-
126
- const selectWorkspaceAnchor = (anchorId: string, pageIndex?: number) => {
127
- const targetPageIndex = resolveAnchorPageIndex(anchorPageMap, displayPages.length, anchorId, pageIndex);
128
- if (targetPageIndex === null) return false;
129
- selectWorkspacePage(targetPageIndex, { behavior: "smooth" });
130
- return true;
131
- };
132
-
133
- const comments = useInspectorComments({
134
- devMode,
135
- inspector,
136
- sourceBlockMap,
137
- sourceBlocksByPath,
138
- sourceContainerRef,
139
- onSelectWorkspacePage: selectWorkspacePage,
140
- });
141
-
142
- // Stabilize the controller objects so memoized InlineInspectorLayer can skip
143
- // re-rendering when nothing observable changed.
144
- const inspectorLayerComments = useMemo(() => ({
145
- saved: comments.inlineSavedComments,
146
- active: comments.activeInlineSavedComment ?? null,
147
- status: comments.inspectorCommentStatus,
148
- statusMessage: comments.inspectorCommentStatusMessage,
149
- totalCount: comments.pendingComments.length,
150
- onOpenSaved: comments.handleOpenInlineSavedComment,
151
- onRemoveSaved: comments.handleRemoveInlineSavedComment,
152
- }), [
153
- comments.activeInlineSavedComment,
154
- comments.handleOpenInlineSavedComment,
155
- comments.handleRemoveInlineSavedComment,
156
- comments.inlineSavedComments,
157
- comments.inspectorCommentStatus,
158
- comments.inspectorCommentStatusMessage,
159
- comments.pendingComments.length,
160
- ]);
161
- const inspectorLayerComposer = useMemo(() => ({
162
- text: comments.inspectorCommentText,
163
- submitDisabled: comments.inspectorCommentDisabled,
164
- mentionItems: projectMentionItems,
165
- onTextChange: comments.setInspectorCommentText,
166
- onSubmit: comments.handleSubmitInspectorComment,
167
- }), [
168
- comments.handleSubmitInspectorComment,
169
- comments.inspectorCommentDisabled,
170
- comments.inspectorCommentText,
171
- comments.setInspectorCommentText,
172
- projectMentionItems,
173
- ]);
174
-
175
- const currentSourcePath = displayPages[reader.currentPageIndex]?.source;
176
- const builtInControlPanels: WorkbenchPanel[] = [
177
- {
178
- id: "pending-comments",
179
- render: () => (
180
- <PendingCommentsPanel
181
- comments={comments.pendingComments}
182
- status={comments.commentsStatus}
183
- error={comments.commentsError}
184
- onClear={comments.clearPendingComment}
185
- onSelect={comments.handleSelectPendingComment}
186
- />
187
- ),
188
- },
189
- {
190
- id: "project-entry",
191
- render: () => (
192
- <ProjectEntryPanel
193
- mediaAssets={mediaAssets}
194
- componentUsages={projectComponentUsages}
195
- mentionItems={projectMentionItems}
196
- currentSource={currentSourcePath}
197
- onCommentSubmitted={comments.refreshPendingComments}
198
- />
199
- ),
200
- },
201
- ];
202
- const controlPanels = extraControlPanels
203
- ? [...builtInControlPanels, ...extraControlPanels]
204
- : builtInControlPanels;
205
-
206
- const toolbarActions = (
207
- <>
208
- <div className="openpress-workbench-toolbar__group" aria-label="輸出">
209
- <button
210
- type="button"
211
- className="openpress-workbench-toolbar-action"
212
- data-openpress-public-export
213
- data-openpress-toolbar-expanded={deployment.pdfToolbarExpanded ? "true" : "false"}
214
- data-openpress-toolbar-active={deployment.pdfToolbarExpanded ? "true" : "false"}
215
- disabled={deployment.pdfButtonDisabled}
216
- onClick={deployment.handleOpenWorkbenchPdf}
217
- title={deployment.pdfButtonText}
218
- aria-label={deployment.pdfButtonText}
219
- >
220
- <ExternalLink aria-hidden="true" />
221
- <span className="openpress-workbench-toolbar-action__label">{deployment.pdfButtonText}</span>
222
- {deployment.pdfStatusMessage ? (
223
- <span
224
- className="openpress-dev-pdf-status"
225
- data-openpress-pdf-status={deployment.pdfActionStatus}
226
- role="status"
227
- aria-live="polite"
228
- >
229
- <span className="openpress-dev-pdf-status__spinner" aria-hidden="true" />
230
- <span>{deployment.pdfStatusMessage}</span>
231
- </span>
232
- ) : null}
233
- </button>
234
- </div>
235
- <div className="openpress-workbench-toolbar__group openpress-workbench-toolbar__group--page" aria-label="頁面規格">
236
- <button
237
- type="button"
238
- className="openpress-workbench-page-geometry"
239
- data-openpress-page-geometry
240
- title={pageGeometry.title}
241
- aria-label={`頁面規格 ${pageGeometry.title}`}
242
- >
243
- <Ruler aria-hidden="true" />
244
- <span className="openpress-workbench-page-geometry__label">{pageGeometry.label}</span>
245
- <span className="openpress-workbench-page-geometry__dimensions">{pageGeometry.dimensions}</span>
246
- </button>
247
- <PageZoomControl
248
- scaleMode={pageViewport.scaleMode}
249
- scaleLabel={pageViewport.scaleLabel}
250
- pageLayoutMode={pageLayoutMode}
251
- onScaleModeChange={pageViewport.setScaleMode}
252
- onPageLayoutModeChange={setPageLayoutMode}
253
- />
254
- </div>
255
- <div className="openpress-workbench-toolbar__group openpress-workbench-toolbar__group--right" aria-label="工作台狀態與發布">
256
- {devMode ? (
257
- <SearchControl
258
- sourceBlocksByPath={sourceBlocksByPath}
259
- onSelectPage={selectWorkspacePage}
260
- />
261
- ) : null}
262
- {devMode && editStatusMessage ? (
263
- <span
264
- className="openpress-dev-edit-status openpress-dev-edit-status--toolbar"
265
- data-openpress-edit-status={inlineEditStatus.state}
266
- role="status"
267
- aria-live="polite"
268
- >
269
- {inlineEditStatus.state === "saving" ? <span className="openpress-dev-edit-status__spinner" aria-hidden="true" /> : null}
270
- <span>{editStatusMessage}</span>
271
- </span>
272
- ) : null}
273
- {devMode ? (
274
- <button
275
- type="button"
276
- className="openpress-workbench-toolbar-action"
277
- data-openpress-inspector-toggle
278
- data-openpress-inspector-active={inspector.inspectorMode ? "true" : "false"}
279
- data-openpress-toolbar-expanded={inspectorToolbarExpanded ? "true" : "false"}
280
- data-openpress-toolbar-active={inspectorToolbarExpanded ? "true" : "false"}
281
- onClick={() => inspector.setInspectorMode(!inspector.inspectorMode)}
282
- aria-pressed={inspector.inspectorMode}
283
- title={inspector.inspectorMode ? "關閉註解" : "開啟註解"}
284
- aria-label={inspector.inspectorMode ? "關閉註解" : "開啟註解"}
285
- >
286
- <MousePointer2 aria-hidden="true" />
287
- <span className="openpress-workbench-toolbar-action__label">{inspector.inspectorMode ? "註解中" : "註解"}</span>
288
- <span className="openpress-dev-inspector-status">{inspectorSelectionLabel}</span>
289
- </button>
290
- ) : null}
291
- {devMode && inspector.inspectorMode ? (
292
- <span
293
- className="openpress-dev-inspector-status"
294
- role="status"
295
- aria-live="polite"
296
- data-openpress-inspector-comment-status={comments.inspectorCommentStatus}
297
- >
298
- {comments.inspectorCommentStatusMessage}
299
- </span>
300
- ) : null}
301
- {deployment.localDeployEnabled ? (
302
- <DeploymentControl
303
- info={deployment.currentDeploymentInfo}
304
- status={deployment.status}
305
- onDeploy={deployment.handleDeploy}
306
- />
307
- ) : null}
308
- </div>
309
- </>
310
- );
311
-
312
- return (
313
- <WorkbenchShell
314
- style={style}
315
- devMode={devMode}
316
- viewMode={viewMode}
317
- inspectorMode={inspector.inspectorMode}
318
- editMode={devMode}
319
- leftPanelOpen={reader.leftPanelOpen}
320
- rightPanelOpen={reader.rightPanelOpen}
321
- onToggleLeftPanel={reader.toggleLeftPanel}
322
- onToggleRightPanel={reader.toggleRightPanel}
323
- >
324
- <WorkbenchShell.Toolbar>
325
- {toolbarActions}
326
- </WorkbenchShell.Toolbar>
327
-
328
- <WorkbenchShell.LeftPanel>
329
- <section className="openpress-public-identity" aria-label="文件資訊">
330
- <strong>
331
- <span className="openpress-public-title-main">{projectIdentity.name}</span>
332
- {projectIdentity.subtitle ? <span className="openpress-public-title-sub">{projectIdentity.subtitle}</span> : null}
333
- </strong>
334
- {projectIdentity.label ? <span>{projectIdentity.label}</span> : null}
335
- </section>
336
-
337
- <section
338
- id="openpress-bookmarks"
339
- className="openpress-panel-section openpress-panel-section--bookmarks"
340
- aria-label="章節書籤"
341
- >
342
- <nav className="reader-bookmarks" aria-label="章節導覽" data-openpress-react-bookmarks="true">
343
- <div className="reader-bookmarks-rail" aria-hidden="true" />
344
- <Bookmarks
345
- items={bookmarks}
346
- currentPageIndex={reader.currentPageIndex}
347
- onSelectPage={selectWorkspacePage}
348
- />
349
- </nav>
350
- </section>
351
- <CurrentPagePanel
352
- currentPageLabel={reader.currentPageLabel}
353
- totalPageLabel={reader.totalPageLabel}
354
- progressPercent={reader.progressPercent}
355
- title={displayPages[reader.currentPageIndex]?.title || document.meta.title}
356
- pageLabelPrefix="頁"
357
- showHeading={false}
358
- showTitle={false}
359
- />
360
- </WorkbenchShell.LeftPanel>
361
-
362
- <WorkbenchShell.RightPanel>
363
- <WorkbenchControlPanel panels={controlPanels} />
364
- </WorkbenchShell.RightPanel>
365
-
366
- <WorkbenchShell.MainContent>
367
- <ReaderStage ref={reader.stageRef}>
368
- <PublicPage
369
- pages={displayPages}
370
- currentPageIndex={reader.currentPageIndex}
371
- devMode={devMode}
372
- sourceContainerRef={sourceContainerRef}
373
- registerPage={reader.registerPage}
374
- exposeSourceData={devMode}
375
- inspector={inspector}
376
- onInternalAnchorNavigate={selectWorkspaceAnchor}
377
- pageLayoutMode={pageLayoutMode}
378
- />
379
- {devMode ? (
380
- <InlineInspectorLayer
381
- sourceContainerRef={sourceContainerRef}
382
- inspector={inspector}
383
- comments={inspectorLayerComments}
384
- composer={inspectorLayerComposer}
385
- geometryVersion={`${pageViewport.scaleMode}:${pageViewport.scale}:${pageLayoutMode}`}
386
- />
387
- ) : null}
388
- {devMode ? (
389
- <InlineSourceEditorLayer
390
- target={sourceEditorTarget}
391
- onClose={() => setSourceEditorTarget(null)}
392
- onStatusChange={setInlineEditStatus}
393
- geometryVersion={`${pageViewport.scaleMode}:${pageViewport.scale}:${pageLayoutMode}`}
394
- />
395
- ) : null}
396
- </ReaderStage>
397
- </WorkbenchShell.MainContent>
398
- </WorkbenchShell>
399
- );
400
- }
401
-
402
- function formatInlineEditStatus(status: InlineDocumentEditStatus) {
403
- if (status.state === "saving") return "儲存中";
404
- if (status.state === "saved") return "已儲存";
405
- if (status.state === "failed") return "儲存失敗";
406
- return "";
407
- }
@@ -1,157 +0,0 @@
1
- import { useId, useState } from "react";
2
- import { Check, Rocket } from "lucide-react";
3
- import type { DeploymentInfo } from "../../document-model";
4
- import { WorkbenchDialog } from "../dialog";
5
- import type { DeployStatus } from "../workbenchTypes";
6
- import {
7
- deployButtonText,
8
- deploymentStatusKind,
9
- deploymentStatusSummary,
10
- deploymentStatusText,
11
- } from "./deploymentStatusModel";
12
-
13
- export function DeploymentControl({
14
- info,
15
- status,
16
- onDeploy,
17
- }: {
18
- info: DeploymentInfo;
19
- status: DeployStatus;
20
- onDeploy: () => void | Promise<void>;
21
- }) {
22
- const titleId = useId();
23
- const [dialogOpen, setDialogOpen] = useState(false);
24
- const kind = deploymentStatusKind(info, status);
25
- const buttonText = deployButtonText(info, status);
26
- const description = deploymentStatusText(info, status);
27
- const summary = deploymentStatusSummary(info, status);
28
- const sourceLabel = deploymentSourceLabel(info);
29
- const busy = status === "deploying";
30
- const confirmDisabled = busy || status === "unavailable" || info.configured === false;
31
-
32
- const confirmDeploy = () => {
33
- if (confirmDisabled) return;
34
- setDialogOpen(false);
35
- void onDeploy();
36
- };
37
-
38
- const dialog = dialogOpen ? (
39
- <WorkbenchDialog
40
- titleId={titleId}
41
- title="部署資訊"
42
- eyebrow="Deployment"
43
- titleMeta={<span className="openpress-deploy-dialog__source">{sourceLabel}</span>}
44
- className="openpress-deploy-dialog"
45
- backdropClassName="openpress-deploy-dialog-backdrop"
46
- closeLabel="關閉部署資訊"
47
- onClose={() => setDialogOpen(false)}
48
- footer={(
49
- <>
50
- <button type="button" onClick={() => setDialogOpen(false)}>取消</button>
51
- <button type="button" disabled={confirmDisabled} onClick={confirmDeploy}>
52
- <Check aria-hidden="true" />
53
- <span>{busy ? "部署中" : "確認部署"}</span>
54
- </button>
55
- </>
56
- )}
57
- >
58
- <dl data-openpress-deploy-align="left-values">
59
- <DeployStatusRow label="狀態" value={summary} kind={kind} />
60
- <DeployLinkRow label="公開頁面" url={info.publicUrl} />
61
- <DeployLinkRow label="PDF" url={info.pdf} />
62
- </dl>
63
- {info.configured === false ? (
64
- <p className="openpress-deploy-dialog__message" role="status">
65
- {info.setupMessage ?? "部署設定尚未完成。"}
66
- </p>
67
- ) : null}
68
- </WorkbenchDialog>
69
- ) : null;
70
-
71
- return (
72
- <>
73
- <button
74
- type="button"
75
- className="openpress-workbench-toolbar-action"
76
- data-openpress-deploy
77
- data-openpress-deploy-status={kind}
78
- data-openpress-toolbar-expanded="false"
79
- data-openpress-toolbar-active="false"
80
- data-deploy-status={status}
81
- aria-busy={busy ? "true" : "false"}
82
- aria-label={buttonText}
83
- title={description}
84
- onClick={() => setDialogOpen(true)}
85
- >
86
- <Rocket aria-hidden="true" />
87
- </button>
88
- {busy ? (
89
- <span
90
- className="openpress-dev-deploy-status openpress-dev-deploy-status--toolbar"
91
- data-openpress-deploy-status={kind}
92
- role="status"
93
- aria-live="polite"
94
- >
95
- <span className="openpress-dev-deploy-status__dot" aria-hidden="true" />
96
- <span>部署中</span>
97
- </span>
98
- ) : null}
99
- {dialog}
100
- </>
101
- );
102
- }
103
-
104
- function DeployStatusRow({ label, value, kind }: { label: string; value: string; kind: string }) {
105
- return (
106
- <div>
107
- <dt>{label}</dt>
108
- <dd>
109
- <span className="openpress-deploy-dialog__status" data-openpress-deploy-status={kind}>
110
- {value}
111
- </span>
112
- </dd>
113
- </div>
114
- );
115
- }
116
-
117
- function DeployLinkRow({ label, url }: { label: string; url?: string }) {
118
- return (
119
- <div>
120
- <dt>{label}</dt>
121
- <dd>
122
- {url ? (
123
- <a href={url} target="_blank" rel="noreferrer">
124
- {formatDeployUrl(url)}
125
- </a>
126
- ) : (
127
- "尚未產生"
128
- )}
129
- </dd>
130
- </div>
131
- );
132
- }
133
-
134
- function deploymentSourceLabel(info: DeploymentInfo) {
135
- const adapter = info.adapter?.trim().toLowerCase();
136
-
137
- if (adapter === "cloudflare-pages" || adapter === "cloudflare") return "Cloudflare Pages";
138
- if (adapter === "github-pages" || adapter === "github") return "GitHub Pages";
139
- if (adapter === "zeabur" || adapter === "zebur") return "Zeabur";
140
-
141
- return info.projectName?.trim() || info.source?.trim() || info.adapter?.trim() || "本機工作區";
142
- }
143
-
144
- function formatDeployUrl(value: string) {
145
- try {
146
- const url = new URL(value);
147
- const pathname = url.pathname === "/" ? "" : url.pathname.replace(/\/$/, "");
148
- return shortenDeployUrl(`${url.host}${pathname}`);
149
- } catch {
150
- return shortenDeployUrl(value);
151
- }
152
- }
153
-
154
- function shortenDeployUrl(value: string) {
155
- if (value.length <= 48) return value;
156
- return `${value.slice(0, 30)}...${value.slice(-14)}`;
157
- }