@bendyline/squisq-editor-react 1.3.0 → 1.5.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 (461) hide show
  1. package/dist/DocumentSettingsDialog.d.ts +26 -0
  2. package/dist/DocumentSettingsDialog.d.ts.map +1 -0
  3. package/dist/DocumentSettingsDialog.js +115 -0
  4. package/dist/DocumentSettingsDialog.js.map +1 -0
  5. package/dist/EditorContext.d.ts +248 -4
  6. package/dist/EditorContext.d.ts.map +1 -1
  7. package/dist/EditorContext.js +248 -10
  8. package/dist/EditorContext.js.map +1 -1
  9. package/dist/EditorShell.d.ts +184 -4
  10. package/dist/EditorShell.d.ts.map +1 -1
  11. package/dist/EditorShell.js +184 -12
  12. package/dist/EditorShell.js.map +1 -1
  13. package/dist/EmojiPicker.d.ts +50 -0
  14. package/dist/EmojiPicker.d.ts.map +1 -0
  15. package/dist/EmojiPicker.js +182 -0
  16. package/dist/EmojiPicker.js.map +1 -0
  17. package/dist/ImageEditor.d.ts +68 -0
  18. package/dist/ImageEditor.d.ts.map +1 -0
  19. package/dist/ImageEditor.js +166 -0
  20. package/dist/ImageEditor.js.map +1 -0
  21. package/dist/ImageNodeView.d.ts +13 -1
  22. package/dist/ImageNodeView.d.ts.map +1 -1
  23. package/dist/ImageNodeView.js +172 -19
  24. package/dist/ImageNodeView.js.map +1 -1
  25. package/dist/ImageViewer.d.ts +26 -0
  26. package/dist/ImageViewer.d.ts.map +1 -0
  27. package/dist/ImageViewer.js +119 -0
  28. package/dist/ImageViewer.js.map +1 -0
  29. package/dist/InlineIcon.d.ts +17 -0
  30. package/dist/InlineIcon.d.ts.map +1 -0
  31. package/dist/InlineIcon.js +72 -0
  32. package/dist/InlineIcon.js.map +1 -0
  33. package/dist/InlinePreviewGutter.d.ts +52 -0
  34. package/dist/InlinePreviewGutter.d.ts.map +1 -0
  35. package/dist/InlinePreviewGutter.js +397 -0
  36. package/dist/InlinePreviewGutter.js.map +1 -0
  37. package/dist/LinkDialog.d.ts +43 -0
  38. package/dist/LinkDialog.d.ts.map +1 -0
  39. package/dist/LinkDialog.js +102 -0
  40. package/dist/LinkDialog.js.map +1 -0
  41. package/dist/MediaBin.d.ts +12 -1
  42. package/dist/MediaBin.d.ts.map +1 -1
  43. package/dist/MediaBin.js +13 -3
  44. package/dist/MediaBin.js.map +1 -1
  45. package/dist/MentionExtension.js +10 -7
  46. package/dist/MentionExtension.js.map +1 -1
  47. package/dist/OutlinePanel.d.ts +17 -0
  48. package/dist/OutlinePanel.d.ts.map +1 -0
  49. package/dist/OutlinePanel.js +167 -0
  50. package/dist/OutlinePanel.js.map +1 -0
  51. package/dist/PlainHtmlPreview.d.ts +50 -0
  52. package/dist/PlainHtmlPreview.d.ts.map +1 -0
  53. package/dist/PlainHtmlPreview.js +155 -0
  54. package/dist/PlainHtmlPreview.js.map +1 -0
  55. package/dist/PreviewControls.d.ts +15 -1
  56. package/dist/PreviewControls.d.ts.map +1 -1
  57. package/dist/PreviewControls.js +75 -18
  58. package/dist/PreviewControls.js.map +1 -1
  59. package/dist/PreviewPanel.d.ts +11 -10
  60. package/dist/PreviewPanel.d.ts.map +1 -1
  61. package/dist/PreviewPanel.js +20 -17
  62. package/dist/PreviewPanel.js.map +1 -1
  63. package/dist/RawEditor.d.ts.map +1 -1
  64. package/dist/RawEditor.js +198 -4
  65. package/dist/RawEditor.js.map +1 -1
  66. package/dist/RecorderEntry.d.ts +24 -0
  67. package/dist/RecorderEntry.d.ts.map +1 -0
  68. package/dist/RecorderEntry.js +139 -0
  69. package/dist/RecorderEntry.js.map +1 -0
  70. package/dist/TemplateAnnotation.d.ts.map +1 -1
  71. package/dist/TemplateAnnotation.js +32 -6
  72. package/dist/TemplateAnnotation.js.map +1 -1
  73. package/dist/TemplatePicker.d.ts +53 -0
  74. package/dist/TemplatePicker.d.ts.map +1 -0
  75. package/dist/TemplatePicker.js +388 -0
  76. package/dist/TemplatePicker.js.map +1 -0
  77. package/dist/ThemeCustomizerPanel.d.ts +32 -0
  78. package/dist/ThemeCustomizerPanel.d.ts.map +1 -0
  79. package/dist/ThemeCustomizerPanel.js +256 -0
  80. package/dist/ThemeCustomizerPanel.js.map +1 -0
  81. package/dist/ThemePicker.d.ts +33 -0
  82. package/dist/ThemePicker.d.ts.map +1 -0
  83. package/dist/ThemePicker.js +148 -0
  84. package/dist/ThemePicker.js.map +1 -0
  85. package/dist/Toolbar.d.ts.map +1 -1
  86. package/dist/Toolbar.js +508 -33
  87. package/dist/Toolbar.js.map +1 -1
  88. package/dist/VersionHistoryPanel.d.ts +14 -0
  89. package/dist/VersionHistoryPanel.d.ts.map +1 -0
  90. package/dist/VersionHistoryPanel.js +147 -0
  91. package/dist/VersionHistoryPanel.js.map +1 -0
  92. package/dist/ViewMenuPanel.d.ts +13 -0
  93. package/dist/ViewMenuPanel.d.ts.map +1 -0
  94. package/dist/ViewMenuPanel.js +58 -0
  95. package/dist/ViewMenuPanel.js.map +1 -0
  96. package/dist/WysiwygEditor.d.ts.map +1 -1
  97. package/dist/WysiwygEditor.js +198 -9
  98. package/dist/WysiwygEditor.js.map +1 -1
  99. package/dist/__tests__/detectMarkdown.test.js +0 -14
  100. package/dist/__tests__/detectMarkdown.test.js.map +1 -1
  101. package/dist/__tests__/documentSettingsDialog.test.d.ts +2 -0
  102. package/dist/__tests__/documentSettingsDialog.test.d.ts.map +1 -0
  103. package/dist/__tests__/documentSettingsDialog.test.js +132 -0
  104. package/dist/__tests__/documentSettingsDialog.test.js.map +1 -0
  105. package/dist/__tests__/emojiPicker.test.d.ts +2 -0
  106. package/dist/__tests__/emojiPicker.test.d.ts.map +1 -0
  107. package/dist/__tests__/emojiPicker.test.js +111 -0
  108. package/dist/__tests__/emojiPicker.test.js.map +1 -0
  109. package/dist/__tests__/fileKind.test.js +13 -0
  110. package/dist/__tests__/fileKind.test.js.map +1 -1
  111. package/dist/__tests__/imageEditAffordance.test.d.ts +2 -0
  112. package/dist/__tests__/imageEditAffordance.test.d.ts.map +1 -0
  113. package/dist/__tests__/imageEditAffordance.test.js +188 -0
  114. package/dist/__tests__/imageEditAffordance.test.js.map +1 -0
  115. package/dist/__tests__/imageEditorShell.test.d.ts +2 -0
  116. package/dist/__tests__/imageEditorShell.test.d.ts.map +1 -0
  117. package/dist/__tests__/imageEditorShell.test.js +52 -0
  118. package/dist/__tests__/imageEditorShell.test.js.map +1 -0
  119. package/dist/__tests__/imageEditorState.test.d.ts +3 -0
  120. package/dist/__tests__/imageEditorState.test.d.ts.map +1 -0
  121. package/dist/__tests__/imageEditorState.test.js +148 -0
  122. package/dist/__tests__/imageEditorState.test.js.map +1 -0
  123. package/dist/__tests__/inlinePreviewGutter.test.d.ts +2 -0
  124. package/dist/__tests__/inlinePreviewGutter.test.d.ts.map +1 -0
  125. package/dist/__tests__/inlinePreviewGutter.test.js +51 -0
  126. package/dist/__tests__/inlinePreviewGutter.test.js.map +1 -0
  127. package/dist/__tests__/inlinePreviewGutterAllBlocks.test.d.ts +2 -0
  128. package/dist/__tests__/inlinePreviewGutterAllBlocks.test.d.ts.map +1 -0
  129. package/dist/__tests__/inlinePreviewGutterAllBlocks.test.js +63 -0
  130. package/dist/__tests__/inlinePreviewGutterAllBlocks.test.js.map +1 -0
  131. package/dist/__tests__/jsonEditor.test.d.ts +2 -0
  132. package/dist/__tests__/jsonEditor.test.d.ts.map +1 -0
  133. package/dist/__tests__/jsonEditor.test.js +134 -0
  134. package/dist/__tests__/jsonEditor.test.js.map +1 -0
  135. package/dist/__tests__/layersPanel.test.d.ts +2 -0
  136. package/dist/__tests__/layersPanel.test.d.ts.map +1 -0
  137. package/dist/__tests__/layersPanel.test.js +84 -0
  138. package/dist/__tests__/layersPanel.test.js.map +1 -0
  139. package/dist/__tests__/linkDialogDocPicker.test.d.ts +7 -0
  140. package/dist/__tests__/linkDialogDocPicker.test.d.ts.map +1 -0
  141. package/dist/__tests__/linkDialogDocPicker.test.js +75 -0
  142. package/dist/__tests__/linkDialogDocPicker.test.js.map +1 -0
  143. package/dist/__tests__/mediaAttachmentFlow.test.d.ts +2 -0
  144. package/dist/__tests__/mediaAttachmentFlow.test.d.ts.map +1 -0
  145. package/dist/__tests__/mediaAttachmentFlow.test.js +99 -0
  146. package/dist/__tests__/mediaAttachmentFlow.test.js.map +1 -0
  147. package/dist/__tests__/outlinePanel.test.d.ts +2 -0
  148. package/dist/__tests__/outlinePanel.test.d.ts.map +1 -0
  149. package/dist/__tests__/outlinePanel.test.js +68 -0
  150. package/dist/__tests__/outlinePanel.test.js.map +1 -0
  151. package/dist/__tests__/plainHtmlPreview.test.d.ts +2 -0
  152. package/dist/__tests__/plainHtmlPreview.test.d.ts.map +1 -0
  153. package/dist/__tests__/plainHtmlPreview.test.js +87 -0
  154. package/dist/__tests__/plainHtmlPreview.test.js.map +1 -0
  155. package/dist/__tests__/propertiesPanel.test.d.ts +2 -0
  156. package/dist/__tests__/propertiesPanel.test.d.ts.map +1 -0
  157. package/dist/__tests__/propertiesPanel.test.js +64 -0
  158. package/dist/__tests__/propertiesPanel.test.js.map +1 -0
  159. package/dist/__tests__/recorderFormats.test.d.ts +2 -0
  160. package/dist/__tests__/recorderFormats.test.d.ts.map +1 -0
  161. package/dist/__tests__/recorderFormats.test.js +121 -0
  162. package/dist/__tests__/recorderFormats.test.js.map +1 -0
  163. package/dist/__tests__/recorderTimingJson.test.d.ts +2 -0
  164. package/dist/__tests__/recorderTimingJson.test.d.ts.map +1 -0
  165. package/dist/__tests__/recorderTimingJson.test.js +37 -0
  166. package/dist/__tests__/recorderTimingJson.test.js.map +1 -0
  167. package/dist/__tests__/templateAnnotationRoundTrip.test.d.ts +2 -0
  168. package/dist/__tests__/templateAnnotationRoundTrip.test.d.ts.map +1 -0
  169. package/dist/__tests__/templateAnnotationRoundTrip.test.js +31 -0
  170. package/dist/__tests__/templateAnnotationRoundTrip.test.js.map +1 -0
  171. package/dist/__tests__/tiptapBridge.test.js +26 -0
  172. package/dist/__tests__/tiptapBridge.test.js.map +1 -1
  173. package/dist/__tests__/tiptapImageRoundTrip.test.d.ts +2 -0
  174. package/dist/__tests__/tiptapImageRoundTrip.test.d.ts.map +1 -0
  175. package/dist/__tests__/tiptapImageRoundTrip.test.js +68 -0
  176. package/dist/__tests__/tiptapImageRoundTrip.test.js.map +1 -0
  177. package/dist/__tests__/useImageEditor.test.d.ts +2 -0
  178. package/dist/__tests__/useImageEditor.test.d.ts.map +1 -0
  179. package/dist/__tests__/useImageEditor.test.js +131 -0
  180. package/dist/__tests__/useImageEditor.test.js.map +1 -0
  181. package/dist/__tests__/useMediaRecorder.test.d.ts +2 -0
  182. package/dist/__tests__/useMediaRecorder.test.d.ts.map +1 -0
  183. package/dist/__tests__/useMediaRecorder.test.js +153 -0
  184. package/dist/__tests__/useMediaRecorder.test.js.map +1 -0
  185. package/dist/__tests__/versionHistory.test.d.ts +2 -0
  186. package/dist/__tests__/versionHistory.test.d.ts.map +1 -0
  187. package/dist/__tests__/versionHistory.test.js +124 -0
  188. package/dist/__tests__/versionHistory.test.js.map +1 -0
  189. package/dist/blockSlice.d.ts +24 -0
  190. package/dist/blockSlice.d.ts.map +1 -0
  191. package/dist/blockSlice.js +63 -0
  192. package/dist/blockSlice.js.map +1 -0
  193. package/dist/buildPreviewDoc.d.ts.map +1 -1
  194. package/dist/buildPreviewDoc.js +52 -2
  195. package/dist/buildPreviewDoc.js.map +1 -1
  196. package/dist/emojiData.d.ts +81 -0
  197. package/dist/emojiData.d.ts.map +1 -0
  198. package/dist/emojiData.js +1283 -0
  199. package/dist/emojiData.js.map +1 -0
  200. package/dist/fileKind.d.ts +6 -2
  201. package/dist/fileKind.d.ts.map +1 -1
  202. package/dist/fileKind.js +25 -4
  203. package/dist/fileKind.js.map +1 -1
  204. package/dist/hooks/useFileDrop.d.ts.map +1 -1
  205. package/dist/hooks/useFileDrop.js +40 -4
  206. package/dist/hooks/useFileDrop.js.map +1 -1
  207. package/dist/imageEditor/CanvasSurface.d.ts +31 -0
  208. package/dist/imageEditor/CanvasSurface.d.ts.map +1 -0
  209. package/dist/imageEditor/CanvasSurface.js +264 -0
  210. package/dist/imageEditor/CanvasSurface.js.map +1 -0
  211. package/dist/imageEditor/ImageVersionHistoryDropdown.d.ts +39 -0
  212. package/dist/imageEditor/ImageVersionHistoryDropdown.d.ts.map +1 -0
  213. package/dist/imageEditor/ImageVersionHistoryDropdown.js +283 -0
  214. package/dist/imageEditor/ImageVersionHistoryDropdown.js.map +1 -0
  215. package/dist/imageEditor/LayersPanel.d.ts +14 -0
  216. package/dist/imageEditor/LayersPanel.d.ts.map +1 -0
  217. package/dist/imageEditor/LayersPanel.js +43 -0
  218. package/dist/imageEditor/LayersPanel.js.map +1 -0
  219. package/dist/imageEditor/PropertiesPanel.d.ts +14 -0
  220. package/dist/imageEditor/PropertiesPanel.d.ts.map +1 -0
  221. package/dist/imageEditor/PropertiesPanel.js +97 -0
  222. package/dist/imageEditor/PropertiesPanel.js.map +1 -0
  223. package/dist/imageEditor/Toolbar.d.ts +30 -0
  224. package/dist/imageEditor/Toolbar.d.ts.map +1 -0
  225. package/dist/imageEditor/Toolbar.js +108 -0
  226. package/dist/imageEditor/Toolbar.js.map +1 -0
  227. package/dist/imageEditor/icons.d.ts +24 -0
  228. package/dist/imageEditor/icons.d.ts.map +1 -0
  229. package/dist/imageEditor/icons.js +45 -0
  230. package/dist/imageEditor/icons.js.map +1 -0
  231. package/dist/imageEditor/layers/EditorImageLayer.d.ts +16 -0
  232. package/dist/imageEditor/layers/EditorImageLayer.d.ts.map +1 -0
  233. package/dist/imageEditor/layers/EditorImageLayer.js +37 -0
  234. package/dist/imageEditor/layers/EditorImageLayer.js.map +1 -0
  235. package/dist/imageEditor/layers/EditorShapeLayer.d.ts +15 -0
  236. package/dist/imageEditor/layers/EditorShapeLayer.d.ts.map +1 -0
  237. package/dist/imageEditor/layers/EditorShapeLayer.js +20 -0
  238. package/dist/imageEditor/layers/EditorShapeLayer.js.map +1 -0
  239. package/dist/imageEditor/layers/EditorTextLayer.d.ts +18 -0
  240. package/dist/imageEditor/layers/EditorTextLayer.d.ts.map +1 -0
  241. package/dist/imageEditor/layers/EditorTextLayer.js +13 -0
  242. package/dist/imageEditor/layers/EditorTextLayer.js.map +1 -0
  243. package/dist/imageEditor/layers/SelectionHandles.d.ts +17 -0
  244. package/dist/imageEditor/layers/SelectionHandles.d.ts.map +1 -0
  245. package/dist/imageEditor/layers/SelectionHandles.js +19 -0
  246. package/dist/imageEditor/layers/SelectionHandles.js.map +1 -0
  247. package/dist/imageEditor/state.d.ts +76 -0
  248. package/dist/imageEditor/state.d.ts.map +1 -0
  249. package/dist/imageEditor/state.js +87 -0
  250. package/dist/imageEditor/state.js.map +1 -0
  251. package/dist/imageEditor/useImageEditor.d.ts +53 -0
  252. package/dist/imageEditor/useImageEditor.d.ts.map +1 -0
  253. package/dist/imageEditor/useImageEditor.js +244 -0
  254. package/dist/imageEditor/useImageEditor.js.map +1 -0
  255. package/dist/imageEditor/useImageEditorTokens.d.ts +16 -0
  256. package/dist/imageEditor/useImageEditorTokens.d.ts.map +1 -0
  257. package/dist/imageEditor/useImageEditorTokens.js +45 -0
  258. package/dist/imageEditor/useImageEditorTokens.js.map +1 -0
  259. package/dist/index.d.ts +48 -1
  260. package/dist/index.d.ts.map +1 -1
  261. package/dist/index.js +36 -0
  262. package/dist/index.js.map +1 -1
  263. package/dist/jsonEditor/EmbeddedRichTextField.d.ts +15 -0
  264. package/dist/jsonEditor/EmbeddedRichTextField.d.ts.map +1 -0
  265. package/dist/jsonEditor/EmbeddedRichTextField.js +74 -0
  266. package/dist/jsonEditor/EmbeddedRichTextField.js.map +1 -0
  267. package/dist/jsonEditor/JsonEditor.d.ts +36 -0
  268. package/dist/jsonEditor/JsonEditor.d.ts.map +1 -0
  269. package/dist/jsonEditor/JsonEditor.js +15 -0
  270. package/dist/jsonEditor/JsonEditor.js.map +1 -0
  271. package/dist/jsonEditor/JsonEditorContext.d.ts +28 -0
  272. package/dist/jsonEditor/JsonEditorContext.d.ts.map +1 -0
  273. package/dist/jsonEditor/JsonEditorContext.js +41 -0
  274. package/dist/jsonEditor/JsonEditorContext.js.map +1 -0
  275. package/dist/jsonEditor/RenderNode.d.ts +16 -0
  276. package/dist/jsonEditor/RenderNode.d.ts.map +1 -0
  277. package/dist/jsonEditor/RenderNode.js +32 -0
  278. package/dist/jsonEditor/RenderNode.js.map +1 -0
  279. package/dist/jsonEditor/editors.d.ts +36 -0
  280. package/dist/jsonEditor/editors.d.ts.map +1 -0
  281. package/dist/jsonEditor/editors.js +347 -0
  282. package/dist/jsonEditor/editors.js.map +1 -0
  283. package/dist/jsonEditor/index.d.ts +3 -0
  284. package/dist/jsonEditor/index.d.ts.map +1 -0
  285. package/dist/jsonEditor/index.js +2 -0
  286. package/dist/jsonEditor/index.js.map +1 -0
  287. package/dist/jsonEditor/useJsonEditorTokens.d.ts +13 -0
  288. package/dist/jsonEditor/useJsonEditorTokens.d.ts.map +1 -0
  289. package/dist/jsonEditor/useJsonEditorTokens.js +38 -0
  290. package/dist/jsonEditor/useJsonEditorTokens.js.map +1 -0
  291. package/dist/recorder/RecorderButton.d.ts +31 -0
  292. package/dist/recorder/RecorderButton.d.ts.map +1 -0
  293. package/dist/recorder/RecorderButton.js +24 -0
  294. package/dist/recorder/RecorderButton.js.map +1 -0
  295. package/dist/recorder/RecorderModal.d.ts +59 -0
  296. package/dist/recorder/RecorderModal.d.ts.map +1 -0
  297. package/dist/recorder/RecorderModal.js +333 -0
  298. package/dist/recorder/RecorderModal.js.map +1 -0
  299. package/dist/recorder/RecorderPanel.d.ts +25 -0
  300. package/dist/recorder/RecorderPanel.d.ts.map +1 -0
  301. package/dist/recorder/RecorderPanel.js +30 -0
  302. package/dist/recorder/RecorderPanel.js.map +1 -0
  303. package/dist/recorder/formats.d.ts +51 -0
  304. package/dist/recorder/formats.d.ts.map +1 -0
  305. package/dist/recorder/formats.js +144 -0
  306. package/dist/recorder/formats.js.map +1 -0
  307. package/dist/recorder/hooks/useMediaRecorder.d.ts +90 -0
  308. package/dist/recorder/hooks/useMediaRecorder.d.ts.map +1 -0
  309. package/dist/recorder/hooks/useMediaRecorder.js +277 -0
  310. package/dist/recorder/hooks/useMediaRecorder.js.map +1 -0
  311. package/dist/recorder/hooks/useStreamPreview.d.ts +22 -0
  312. package/dist/recorder/hooks/useStreamPreview.d.ts.map +1 -0
  313. package/dist/recorder/hooks/useStreamPreview.js +44 -0
  314. package/dist/recorder/hooks/useStreamPreview.js.map +1 -0
  315. package/dist/recorder/sources/cameraStream.d.ts +22 -0
  316. package/dist/recorder/sources/cameraStream.d.ts.map +1 -0
  317. package/dist/recorder/sources/cameraStream.js +24 -0
  318. package/dist/recorder/sources/cameraStream.js.map +1 -0
  319. package/dist/recorder/sources/micStream.d.ts +15 -0
  320. package/dist/recorder/sources/micStream.d.ts.map +1 -0
  321. package/dist/recorder/sources/micStream.js +24 -0
  322. package/dist/recorder/sources/micStream.js.map +1 -0
  323. package/dist/recorder/sources/screenStream.d.ts +53 -0
  324. package/dist/recorder/sources/screenStream.d.ts.map +1 -0
  325. package/dist/recorder/sources/screenStream.js +114 -0
  326. package/dist/recorder/sources/screenStream.js.map +1 -0
  327. package/dist/recorder/timingJson.d.ts +51 -0
  328. package/dist/recorder/timingJson.d.ts.map +1 -0
  329. package/dist/recorder/timingJson.js +42 -0
  330. package/dist/recorder/timingJson.js.map +1 -0
  331. package/dist/tiptap/TiptapAudio.d.ts +26 -0
  332. package/dist/tiptap/TiptapAudio.d.ts.map +1 -0
  333. package/dist/tiptap/TiptapAudio.js +58 -0
  334. package/dist/tiptap/TiptapAudio.js.map +1 -0
  335. package/dist/tiptap/TiptapVideo.d.ts +30 -0
  336. package/dist/tiptap/TiptapVideo.d.ts.map +1 -0
  337. package/dist/tiptap/TiptapVideo.js +66 -0
  338. package/dist/tiptap/TiptapVideo.js.map +1 -0
  339. package/dist/tiptap/useResolvedMediaSrc.d.ts +2 -0
  340. package/dist/tiptap/useResolvedMediaSrc.d.ts.map +1 -0
  341. package/dist/tiptap/useResolvedMediaSrc.js +42 -0
  342. package/dist/tiptap/useResolvedMediaSrc.js.map +1 -0
  343. package/dist/tiptapBridge.d.ts.map +1 -1
  344. package/dist/tiptapBridge.js +210 -16
  345. package/dist/tiptapBridge.js.map +1 -1
  346. package/dist/useHeadingLayout.d.ts +54 -0
  347. package/dist/useHeadingLayout.d.ts.map +1 -0
  348. package/dist/useHeadingLayout.js +260 -0
  349. package/dist/useHeadingLayout.js.map +1 -0
  350. package/dist/utils/collectInlineFontAwesomeCss.d.ts +21 -0
  351. package/dist/utils/collectInlineFontAwesomeCss.d.ts.map +1 -0
  352. package/dist/utils/collectInlineFontAwesomeCss.js +68 -0
  353. package/dist/utils/collectInlineFontAwesomeCss.js.map +1 -0
  354. package/dist/utils/dropUtils.d.ts +21 -2
  355. package/dist/utils/dropUtils.d.ts.map +1 -1
  356. package/dist/utils/dropUtils.js +43 -4
  357. package/dist/utils/dropUtils.js.map +1 -1
  358. package/dist/utils/normalizeMalformedAssetUrl.d.ts +15 -0
  359. package/dist/utils/normalizeMalformedAssetUrl.d.ts.map +1 -0
  360. package/dist/utils/normalizeMalformedAssetUrl.js +27 -0
  361. package/dist/utils/normalizeMalformedAssetUrl.js.map +1 -0
  362. package/package.json +8 -5
  363. package/src/DocumentSettingsDialog.tsx +266 -0
  364. package/src/EditorContext.tsx +534 -10
  365. package/src/EditorShell.tsx +691 -63
  366. package/src/EmojiPicker.tsx +332 -0
  367. package/src/ImageEditor.tsx +327 -0
  368. package/src/ImageNodeView.tsx +222 -21
  369. package/src/ImageViewer.tsx +221 -0
  370. package/src/InlineIcon.ts +84 -0
  371. package/src/InlinePreviewGutter.tsx +582 -0
  372. package/src/LinkDialog.tsx +276 -0
  373. package/src/MediaBin.tsx +22 -3
  374. package/src/MentionExtension.tsx +10 -7
  375. package/src/OutlinePanel.tsx +295 -0
  376. package/src/PlainHtmlPreview.tsx +211 -0
  377. package/src/PreviewControls.tsx +130 -24
  378. package/src/PreviewPanel.tsx +38 -21
  379. package/src/RawEditor.tsx +215 -4
  380. package/src/RecorderEntry.tsx +164 -0
  381. package/src/TemplateAnnotation.ts +32 -6
  382. package/src/TemplatePicker.tsx +818 -0
  383. package/src/ThemeCustomizerPanel.tsx +595 -0
  384. package/src/ThemePicker.tsx +319 -0
  385. package/src/Toolbar.tsx +708 -111
  386. package/src/VersionHistoryPanel.tsx +329 -0
  387. package/src/ViewMenuPanel.tsx +188 -0
  388. package/src/WysiwygEditor.tsx +229 -9
  389. package/src/__tests__/detectMarkdown.test.ts +0 -15
  390. package/src/__tests__/documentSettingsDialog.test.tsx +147 -0
  391. package/src/__tests__/emojiPicker.test.tsx +133 -0
  392. package/src/__tests__/fileKind.test.ts +16 -0
  393. package/src/__tests__/imageEditAffordance.test.tsx +268 -0
  394. package/src/__tests__/imageEditorShell.test.tsx +57 -0
  395. package/src/__tests__/imageEditorState.test.ts +171 -0
  396. package/src/__tests__/inlinePreviewGutter.test.tsx +62 -0
  397. package/src/__tests__/inlinePreviewGutterAllBlocks.test.tsx +103 -0
  398. package/src/__tests__/jsonEditor.test.tsx +168 -0
  399. package/src/__tests__/layersPanel.test.tsx +97 -0
  400. package/src/__tests__/linkDialogDocPicker.test.tsx +137 -0
  401. package/src/__tests__/mediaAttachmentFlow.test.ts +110 -0
  402. package/src/__tests__/outlinePanel.test.tsx +79 -0
  403. package/src/__tests__/plainHtmlPreview.test.tsx +107 -0
  404. package/src/__tests__/propertiesPanel.test.tsx +69 -0
  405. package/src/__tests__/recorderFormats.test.ts +146 -0
  406. package/src/__tests__/recorderTimingJson.test.ts +41 -0
  407. package/src/__tests__/templateAnnotationRoundTrip.test.ts +34 -0
  408. package/src/__tests__/tiptapBridge.test.ts +29 -0
  409. package/src/__tests__/tiptapImageRoundTrip.test.ts +73 -0
  410. package/src/__tests__/useImageEditor.test.tsx +159 -0
  411. package/src/__tests__/useMediaRecorder.test.ts +186 -0
  412. package/src/__tests__/versionHistory.test.tsx +197 -0
  413. package/src/blockSlice.ts +75 -0
  414. package/src/buildPreviewDoc.ts +61 -6
  415. package/src/emojiData.ts +1337 -0
  416. package/src/fileKind.ts +30 -6
  417. package/src/hooks/useFileDrop.ts +40 -4
  418. package/src/imageEditor/CanvasSurface.tsx +402 -0
  419. package/src/imageEditor/ImageVersionHistoryDropdown.tsx +396 -0
  420. package/src/imageEditor/LayersPanel.tsx +143 -0
  421. package/src/imageEditor/PropertiesPanel.tsx +428 -0
  422. package/src/imageEditor/Toolbar.tsx +242 -0
  423. package/src/imageEditor/icons.tsx +144 -0
  424. package/src/imageEditor/image-editor.css +450 -0
  425. package/src/imageEditor/layers/EditorImageLayer.tsx +45 -0
  426. package/src/imageEditor/layers/EditorShapeLayer.tsx +62 -0
  427. package/src/imageEditor/layers/EditorTextLayer.tsx +45 -0
  428. package/src/imageEditor/layers/SelectionHandles.tsx +86 -0
  429. package/src/imageEditor/state.ts +153 -0
  430. package/src/imageEditor/useImageEditor.ts +328 -0
  431. package/src/imageEditor/useImageEditorTokens.ts +70 -0
  432. package/src/index.ts +82 -0
  433. package/src/jsonEditor/EmbeddedRichTextField.tsx +81 -0
  434. package/src/jsonEditor/JsonEditor.tsx +81 -0
  435. package/src/jsonEditor/JsonEditorContext.tsx +75 -0
  436. package/src/jsonEditor/RenderNode.tsx +66 -0
  437. package/src/jsonEditor/editors.tsx +678 -0
  438. package/src/jsonEditor/index.ts +2 -0
  439. package/src/jsonEditor/json-editor.css +463 -0
  440. package/src/jsonEditor/useJsonEditorTokens.ts +63 -0
  441. package/src/recorder/RecorderButton.tsx +72 -0
  442. package/src/recorder/RecorderModal.tsx +596 -0
  443. package/src/recorder/RecorderPanel.tsx +93 -0
  444. package/src/recorder/formats.ts +159 -0
  445. package/src/recorder/hooks/useMediaRecorder.ts +378 -0
  446. package/src/recorder/hooks/useStreamPreview.ts +47 -0
  447. package/src/recorder/sources/cameraStream.ts +32 -0
  448. package/src/recorder/sources/micStream.ts +25 -0
  449. package/src/recorder/sources/screenStream.ts +162 -0
  450. package/src/recorder/timingJson.ts +66 -0
  451. package/src/styles/editor.css +2490 -51
  452. package/src/styles/image-edit-affordance.css +201 -0
  453. package/src/styles/index.css +10 -0
  454. package/src/tiptap/TiptapAudio.tsx +86 -0
  455. package/src/tiptap/TiptapVideo.tsx +119 -0
  456. package/src/tiptap/useResolvedMediaSrc.ts +47 -0
  457. package/src/tiptapBridge.ts +227 -22
  458. package/src/useHeadingLayout.ts +294 -0
  459. package/src/utils/collectInlineFontAwesomeCss.ts +69 -0
  460. package/src/utils/dropUtils.ts +54 -6
  461. package/src/utils/normalizeMalformedAssetUrl.ts +22 -0
@@ -0,0 +1,333 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * RecorderModal — configure-and-capture dialog for browser-based audio,
4
+ * camera, and screen recording.
5
+ *
6
+ * States: configure (pick mode + optional script) → previewing (acquired
7
+ * stream, not yet recording) → recording → review (blob in hand) → saved
8
+ * | error. The user can cancel from any state.
9
+ *
10
+ * Persists the captured `Blob` into the supplied `MediaProvider` and,
11
+ * for narration mode, writes a `.timing.json` sidecar so
12
+ * `resolveAudioMapping()` in `@bendyline/squisq` picks it up at the next
13
+ * doc parse.
14
+ *
15
+ * Visual conventions match `VideoExportModal` from `@bendyline/squisq-
16
+ * video-react` (cream / gold palette, inline styles, no external CSS).
17
+ */
18
+ import { useCallback, useEffect, useRef, useState } from 'react';
19
+ import { useMediaRecorder } from './hooks/useMediaRecorder.js';
20
+ import { useStreamPreview } from './hooks/useStreamPreview.js';
21
+ import { buildFilename } from './formats.js';
22
+ import { buildTimingJson, encodeTimingJson, timingPathFor } from './timingJson.js';
23
+ // ── Styles ─────────────────────────────────────────────────────────
24
+ const overlayStyle = {
25
+ position: 'fixed',
26
+ inset: 0,
27
+ background: 'rgba(0, 0, 0, 0.5)',
28
+ display: 'flex',
29
+ alignItems: 'center',
30
+ justifyContent: 'center',
31
+ zIndex: 10000,
32
+ };
33
+ const modalStyle = {
34
+ background: '#FFFDF7',
35
+ border: '1px solid #c9b98a',
36
+ borderRadius: 0,
37
+ padding: '24px 28px',
38
+ width: 'min(560px, calc(100vw - 48px))',
39
+ maxHeight: 'calc(100vh - 48px)',
40
+ overflowY: 'auto',
41
+ boxShadow: '0 8px 32px rgba(0,0,0,0.18)',
42
+ fontFamily: 'system-ui, -apple-system, sans-serif',
43
+ color: '#4a3c1f',
44
+ };
45
+ const titleStyle = {
46
+ margin: '0 0 16px 0',
47
+ fontSize: 18,
48
+ fontWeight: 600,
49
+ color: '#2d2310',
50
+ };
51
+ const labelStyle = {
52
+ display: 'block',
53
+ fontSize: 13,
54
+ fontWeight: 500,
55
+ marginBottom: 4,
56
+ color: '#5a4a2a',
57
+ };
58
+ const inputStyle = {
59
+ width: '100%',
60
+ padding: '6px 8px',
61
+ fontSize: 13,
62
+ fontFamily: 'inherit',
63
+ border: '1px solid #c9b98a',
64
+ borderRadius: 0,
65
+ background: '#fff',
66
+ color: '#4a3c1f',
67
+ marginBottom: 12,
68
+ boxSizing: 'border-box',
69
+ };
70
+ const textareaStyle = {
71
+ ...inputStyle,
72
+ resize: 'vertical',
73
+ minHeight: 72,
74
+ };
75
+ const btnPrimary = {
76
+ padding: '8px 20px',
77
+ fontSize: 14,
78
+ fontFamily: 'inherit',
79
+ fontWeight: 500,
80
+ cursor: 'pointer',
81
+ background: '#8B6914',
82
+ color: '#fff',
83
+ border: '1px solid #7a5c10',
84
+ borderRadius: 0,
85
+ };
86
+ const btnSecondary = {
87
+ padding: '8px 20px',
88
+ fontSize: 14,
89
+ fontFamily: 'inherit',
90
+ fontWeight: 500,
91
+ cursor: 'pointer',
92
+ background: '#E8DFC6',
93
+ color: '#4a3c1f',
94
+ border: '1px solid #c9b98a',
95
+ borderRadius: 0,
96
+ };
97
+ const btnDanger = {
98
+ ...btnPrimary,
99
+ background: '#B33A3A',
100
+ borderColor: '#902929',
101
+ };
102
+ const tabRowStyle = {
103
+ display: 'flex',
104
+ gap: 4,
105
+ marginBottom: 16,
106
+ borderBottom: '1px solid #c9b98a',
107
+ };
108
+ const tabBase = {
109
+ padding: '6px 12px',
110
+ fontSize: 13,
111
+ fontFamily: 'inherit',
112
+ cursor: 'pointer',
113
+ background: 'transparent',
114
+ color: '#5a4a2a',
115
+ border: 'none',
116
+ borderBottom: '2px solid transparent',
117
+ marginBottom: -1,
118
+ };
119
+ const tabActive = {
120
+ ...tabBase,
121
+ color: '#2d2310',
122
+ fontWeight: 600,
123
+ // Use the `borderBottom` shorthand (not `borderBottomColor` longhand)
124
+ // so React's style diff cleanly resets the underline when this tab
125
+ // goes inactive — mixing shorthand + longhand can leave the old
126
+ // color stuck on a previously-active tab between renders.
127
+ borderBottom: '2px solid #8B6914',
128
+ };
129
+ const previewBoxStyle = {
130
+ width: '100%',
131
+ background: '#000',
132
+ borderRadius: 0,
133
+ marginBottom: 12,
134
+ overflow: 'hidden',
135
+ aspectRatio: '16 / 9',
136
+ display: 'flex',
137
+ alignItems: 'center',
138
+ justifyContent: 'center',
139
+ color: '#888',
140
+ fontSize: 13,
141
+ };
142
+ const audioMeterStyle = {
143
+ width: '100%',
144
+ height: 56,
145
+ background: '#F2EBD9',
146
+ border: '1px solid #c9b98a',
147
+ marginBottom: 12,
148
+ display: 'flex',
149
+ alignItems: 'center',
150
+ justifyContent: 'center',
151
+ color: '#5a4a2a',
152
+ fontSize: 13,
153
+ fontVariantNumeric: 'tabular-nums',
154
+ };
155
+ const errorStyle = {
156
+ background: '#FCEEEE',
157
+ border: '1px solid #D88A8A',
158
+ color: '#8C2A2A',
159
+ padding: '8px 10px',
160
+ fontSize: 13,
161
+ marginBottom: 12,
162
+ };
163
+ const buttonRowStyle = {
164
+ display: 'flex',
165
+ gap: 8,
166
+ justifyContent: 'flex-end',
167
+ marginTop: 8,
168
+ };
169
+ // ── Helpers ────────────────────────────────────────────────────────
170
+ function formatDurationMs(ms) {
171
+ const totalSec = Math.floor(ms / 1000);
172
+ const m = Math.floor(totalSec / 60);
173
+ const s = totalSec % 60;
174
+ return `${m}:${s.toString().padStart(2, '0')}`;
175
+ }
176
+ const TABS = [
177
+ {
178
+ id: 'mic',
179
+ label: 'Narration',
180
+ description: 'Voice-only audio. Pairs with a written script for auto-mapping to blocks.',
181
+ },
182
+ { id: 'camera', label: 'Camera', description: 'Camera + microphone. Saved as a video clip.' },
183
+ { id: 'screen', label: 'Screen', description: 'Screen capture. System audio when available.' },
184
+ { id: 'screen+mic', label: 'Screen + Mic', description: 'Screen with your microphone mixed in.' },
185
+ ];
186
+ // ── Component ──────────────────────────────────────────────────────
187
+ export function RecorderModal({ mediaProvider, container = null, initialMode = 'mic', onClose, onSave, }) {
188
+ const [source, setSource] = useState(initialMode);
189
+ const [sourceText, setSourceText] = useState('');
190
+ const [basename, setBasename] = useState('');
191
+ const [includeSystemAudio, setIncludeSystemAudio] = useState(false);
192
+ const [isSaving, setIsSaving] = useState(false);
193
+ const [saveError, setSaveError] = useState(null);
194
+ const [playbackUrl, setPlaybackUrl] = useState(null);
195
+ const previewRef = useRef(null);
196
+ const recorder = useMediaRecorder({
197
+ source,
198
+ systemAudio: source === 'screen' || source === 'screen+mic' ? includeSystemAudio : false,
199
+ });
200
+ useStreamPreview(previewRef, recorder.state === 'stopped' ? null : recorder.stream);
201
+ // Generate (and later revoke) a blob URL for the recorded clip so the
202
+ // playback element has something to point at. The dependency on the
203
+ // blob identity means a new URL is created every time a fresh
204
+ // recording lands, and the cleanup callback revokes the previous one.
205
+ useEffect(() => {
206
+ if (!recorder.blob) {
207
+ setPlaybackUrl(null);
208
+ return;
209
+ }
210
+ const url = URL.createObjectURL(recorder.blob);
211
+ setPlaybackUrl(url);
212
+ return () => {
213
+ URL.revokeObjectURL(url);
214
+ };
215
+ }, [recorder.blob]);
216
+ // Switching capture source mid-session: tear down whatever stream/
217
+ // recorder we had so the new mode acquires a fresh one. The hook
218
+ // already handles its own internal teardown on unmount; cancel()
219
+ // here covers in-place source changes.
220
+ const previousSourceRef = useRef(source);
221
+ useEffect(() => {
222
+ if (previousSourceRef.current !== source) {
223
+ previousSourceRef.current = source;
224
+ recorder.cancel();
225
+ }
226
+ }, [source, recorder]);
227
+ // Make sure tearing down the modal always releases the camera /
228
+ // screen-capture indicator. The hook's own unmount effect handles
229
+ // this, but we also kill the stream eagerly on close so a slow
230
+ // unmount doesn't leave the indicator lit between renders.
231
+ const handleClose = useCallback(() => {
232
+ recorder.cancel();
233
+ onClose();
234
+ }, [recorder, onClose]);
235
+ const handleRequest = useCallback(async () => {
236
+ setSaveError(null);
237
+ try {
238
+ await recorder.request();
239
+ }
240
+ catch {
241
+ // Already surfaced via recorder.error.
242
+ }
243
+ }, [recorder]);
244
+ const handleStart = useCallback(() => {
245
+ setSaveError(null);
246
+ recorder.start();
247
+ }, [recorder]);
248
+ const handleStop = useCallback(async () => {
249
+ setSaveError(null);
250
+ await recorder.stop();
251
+ }, [recorder]);
252
+ const handleSave = useCallback(async () => {
253
+ if (!recorder.blob || !recorder.mimeType || !recorder.extension || !recorder.directory) {
254
+ setSaveError('Nothing to save yet — record something first.');
255
+ return;
256
+ }
257
+ setIsSaving(true);
258
+ setSaveError(null);
259
+ try {
260
+ const filename = buildFilename(source === 'mic' ? 'audio' : 'video', recorder.extension, basename);
261
+ const relativeName = `${recorder.directory}/${filename}`;
262
+ const relativePath = await mediaProvider.addMedia(relativeName, recorder.blob, recorder.mimeType);
263
+ let hasTimingSidecar = false;
264
+ if (source === 'mic') {
265
+ const timing = buildTimingJson(sourceText, recorder.durationMs / 1000);
266
+ const encoded = encodeTimingJson(timing);
267
+ const sidecarPath = timingPathFor(relativePath);
268
+ // Prefer direct container write so the sidecar lands at the
269
+ // exact path the audio-mapping pipeline expects. Fall back to
270
+ // addMedia(), which may rename — log if so.
271
+ if (container) {
272
+ await container.writeFile(sidecarPath, encoded, 'application/json');
273
+ hasTimingSidecar = true;
274
+ }
275
+ else {
276
+ const written = await mediaProvider.addMedia(sidecarPath, encoded, 'application/json');
277
+ hasTimingSidecar = written === sidecarPath;
278
+ if (!hasTimingSidecar) {
279
+ console.warn(`[squisq-recorder] timing.json was saved as "${written}" instead of "${sidecarPath}" — auto-mapping may not pick it up.`);
280
+ }
281
+ }
282
+ }
283
+ const result = {
284
+ relativePath,
285
+ filename,
286
+ source,
287
+ mimeType: recorder.mimeType,
288
+ duration: recorder.durationMs / 1000,
289
+ hasTimingSidecar,
290
+ };
291
+ if (source === 'mic') {
292
+ result.sourceText = sourceText;
293
+ }
294
+ onSave?.(result);
295
+ handleClose();
296
+ }
297
+ catch (err) {
298
+ setSaveError(err instanceof Error ? err.message : 'Failed to save recording');
299
+ }
300
+ finally {
301
+ setIsSaving(false);
302
+ }
303
+ }, [recorder, source, basename, sourceText, mediaProvider, container, onSave, handleClose]);
304
+ const handleDiscard = useCallback(() => {
305
+ recorder.reset();
306
+ }, [recorder]);
307
+ const isAudioOnly = source === 'mic';
308
+ const showPreview = recorder.state !== 'idle' && recorder.state !== 'error';
309
+ const canRecord = recorder.state === 'ready';
310
+ const canStop = recorder.state === 'recording';
311
+ const canSave = recorder.state === 'stopped' && recorder.blob !== null;
312
+ const isBusy = recorder.state === 'requesting' || recorder.state === 'stopping' || isSaving;
313
+ const activeTabDescription = TABS.find((t) => t.id === source)?.description;
314
+ return (_jsx("div", { style: overlayStyle, role: "dialog", "aria-modal": "true", "aria-label": "Record media", children: _jsxs("div", { style: modalStyle, onClick: (e) => e.stopPropagation(), children: [_jsx("h2", { style: titleStyle, children: "Record media" }), _jsx("div", { style: tabRowStyle, role: "tablist", children: TABS.map((tab) => {
315
+ const active = tab.id === source;
316
+ return (_jsx("button", { role: "tab", "aria-selected": active, type: "button", style: active ? tabActive : tabBase, onClick: () => setSource(tab.id), disabled: recorder.state === 'recording' || recorder.state === 'requesting', children: tab.label }, tab.id));
317
+ }) }), activeTabDescription && (_jsx("p", { style: { margin: '0 0 12px 0', fontSize: 12, color: '#5a4a2a' }, children: activeTabDescription })), recorder.error && _jsx("div", { style: errorStyle, children: recorder.error.message }), saveError && _jsx("div", { style: errorStyle, children: saveError }), !showPreview && (_jsx("div", { style: previewBoxStyle, children: _jsx("span", { children: "Click Start Preview to start a recording." }) })), showPreview && recorder.state !== 'stopped' && !isAudioOnly && (_jsx("div", { style: previewBoxStyle, children: _jsx("video", { ref: previewRef, autoPlay: true, muted: true, playsInline: true, style: { width: '100%', height: '100%', objectFit: 'contain' } }) })), showPreview && recorder.state !== 'stopped' && isAudioOnly && (_jsx("div", { style: audioMeterStyle, children: recorder.state === 'recording' ? (_jsxs(_Fragment, { children: ["\u25CF Recording ", formatDurationMs(recorder.durationMs)] })) : (_jsx(_Fragment, { children: "Microphone ready" })) })), recorder.state === 'stopped' && playbackUrl && !isAudioOnly && (_jsx("div", { style: previewBoxStyle, children: _jsx("video", { src: playbackUrl, controls: true, playsInline: true, style: { width: '100%', height: '100%', objectFit: 'contain' } }) })), recorder.state === 'stopped' && playbackUrl && isAudioOnly && (_jsxs("div", { style: { marginBottom: 12 }, children: [_jsxs("div", { style: { ...audioMeterStyle, marginBottom: 8 }, children: ["\u2713 Recorded ", formatDurationMs(recorder.durationMs)] }), _jsx("audio", { src: playbackUrl, controls: true, style: { width: '100%' } })] })), source === 'mic' && (_jsxs(_Fragment, { children: [_jsx("label", { style: labelStyle, htmlFor: "recorder-source-text", children: "Script (used to auto-match this narration to a block)" }), _jsx("textarea", { id: "recorder-source-text", style: textareaStyle, placeholder: "Type the text you're going to read aloud.", value: sourceText, onChange: (e) => setSourceText(e.target.value), disabled: recorder.state === 'recording' })] })), (source === 'screen' || source === 'screen+mic') && (_jsxs("label", { style: {
318
+ display: 'flex',
319
+ alignItems: 'center',
320
+ gap: 6,
321
+ marginBottom: 12,
322
+ fontSize: 13,
323
+ }, children: [_jsx("input", { type: "checkbox", checked: includeSystemAudio, onChange: (e) => setIncludeSystemAudio(e.target.checked), disabled: recorder.state === 'recording' || recorder.state === 'requesting' }), "Include system audio (Chrome only)"] })), _jsx("label", { style: labelStyle, htmlFor: "recorder-basename", children: "Filename (optional)" }), _jsx("input", { id: "recorder-basename", type: "text", style: inputStyle, placeholder: source === 'mic' ? 'narration' : 'recording', value: basename, onChange: (e) => setBasename(e.target.value), disabled: recorder.state === 'recording' }), recorder.state === 'recording' && !isAudioOnly && (_jsxs("div", { style: {
324
+ fontSize: 13,
325
+ fontVariantNumeric: 'tabular-nums',
326
+ marginBottom: 12,
327
+ color: '#8B6914',
328
+ fontWeight: 600,
329
+ }, children: ["\u25CF Recording ", formatDurationMs(recorder.durationMs)] })), _jsxs("div", { style: buttonRowStyle, children: [_jsx("button", { type: "button", style: btnSecondary, onClick: handleClose, disabled: isBusy, children: "Close" }), (recorder.state === 'idle' ||
330
+ recorder.state === 'error' ||
331
+ recorder.state === 'requesting') && (_jsx("button", { type: "button", style: btnPrimary, onClick: handleRequest, disabled: isBusy, children: recorder.state === 'requesting' ? 'Requesting…' : 'Start preview' })), canRecord && (_jsx("button", { type: "button", style: btnPrimary, onClick: handleStart, disabled: isBusy, children: "Record" })), canStop && (_jsx("button", { type: "button", style: btnDanger, onClick: handleStop, disabled: isBusy, children: "Stop" })), canSave && (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", style: btnSecondary, onClick: handleDiscard, disabled: isBusy, children: "Discard & re-record" }), _jsx("button", { type: "button", style: btnPrimary, onClick: handleSave, disabled: isBusy, children: isSaving ? 'Saving…' : 'Save to document' })] }))] })] }) }));
332
+ }
333
+ //# sourceMappingURL=RecorderModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecorderModal.js","sourceRoot":"","sources":["../../src/recorder/RecorderModal.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * RecorderPanel — toolbar-anchored trigger that opens the
3
+ * {@link RecorderModal} in a portal. Shaped to slot into an editor
4
+ * toolbar alongside other panels (e.g. `VersionHistoryPanel`); ships a
5
+ * compact mic/record icon and no label by default.
6
+ *
7
+ * For a button that owns its own visual label, use {@link RecorderButton}
8
+ * instead.
9
+ */
10
+ import type { MediaProvider } from '@bendyline/squisq/schemas';
11
+ import type { ContentContainer } from '@bendyline/squisq/storage';
12
+ import { type RecorderSaveResult } from './RecorderModal.js';
13
+ import type { RecorderSource } from './hooks/useMediaRecorder.js';
14
+ export interface RecorderPanelProps {
15
+ mediaProvider: MediaProvider;
16
+ container?: ContentContainer | null;
17
+ initialMode?: RecorderSource;
18
+ onSave?: (result: RecorderSaveResult) => void;
19
+ /** ARIA / tooltip label. Defaults to `'Record media'`. */
20
+ tooltip?: string;
21
+ /** Optional className for the trigger button. */
22
+ className?: string;
23
+ }
24
+ export declare function RecorderPanel({ mediaProvider, container, initialMode, onSave, tooltip, className, }: RecorderPanelProps): import("react/jsx-runtime").JSX.Element;
25
+ //# sourceMappingURL=RecorderPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecorderPanel.d.ts","sourceRoot":"","sources":["../../src/recorder/RecorderPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,aAAa,CAAC;IAC7B,SAAS,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,cAAc,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC9C,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD,wBAAgB,aAAa,CAAC,EAC5B,aAAa,EACb,SAAgB,EAChB,WAAmB,EACnB,MAAM,EACN,OAAwB,EACxB,SAAS,GACV,EAAE,kBAAkB,2CAgCpB"}
@@ -0,0 +1,30 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * RecorderPanel — toolbar-anchored trigger that opens the
4
+ * {@link RecorderModal} in a portal. Shaped to slot into an editor
5
+ * toolbar alongside other panels (e.g. `VersionHistoryPanel`); ships a
6
+ * compact mic/record icon and no label by default.
7
+ *
8
+ * For a button that owns its own visual label, use {@link RecorderButton}
9
+ * instead.
10
+ */
11
+ import { useCallback, useState } from 'react';
12
+ import { createPortal } from 'react-dom';
13
+ import { RecorderModal } from './RecorderModal.js';
14
+ /**
15
+ * Inline 16×16 SVG mic icon — currentColor-driven so it inherits the
16
+ * toolbar's icon color regardless of theme.
17
+ */
18
+ function MicIcon() {
19
+ return (_jsxs("svg", { width: 16, height: 16, viewBox: "0 0 16 16", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("rect", { x: 5.5, y: 2, width: 5, height: 8, rx: 2.5 }), _jsx("path", { d: "M3.5 7.5v1a4.5 4.5 0 0 0 9 0v-1" }), _jsx("line", { x1: 8, y1: 13, x2: 8, y2: 15 }), _jsx("line", { x1: 5.5, y1: 15, x2: 10.5, y2: 15 })] }));
20
+ }
21
+ export function RecorderPanel({ mediaProvider, container = null, initialMode = 'mic', onSave, tooltip = 'Record media', className, }) {
22
+ const [open, setOpen] = useState(false);
23
+ const handleClose = useCallback(() => setOpen(false), []);
24
+ return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: className, "data-tooltip": tooltip, "aria-label": tooltip, "aria-expanded": open, onClick: () => setOpen((v) => !v), children: _jsx(MicIcon, {}) }), open &&
25
+ typeof document !== 'undefined' &&
26
+ createPortal(_jsx(RecorderModal, { mediaProvider: mediaProvider, container: container, initialMode: initialMode, onClose: handleClose, onSave: (result) => {
27
+ onSave?.(result);
28
+ } }), document.body)] }));
29
+ }
30
+ //# sourceMappingURL=RecorderPanel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RecorderPanel.js","sourceRoot":"","sources":["../../src/recorder/RecorderPanel.tsx"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,EAAE,aAAa,EAA2B,MAAM,oBAAoB,CAAC;AAc5E;;;GAGG;AACH,SAAS,OAAO;IACd,OAAO,CACL,eACE,KAAK,EAAE,EAAE,EACT,MAAM,EAAE,EAAE,EACV,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAE,GAAG,EAChB,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,iBACV,MAAM,aAElB,eAAM,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,GAAG,GAAI,EACpD,eAAM,CAAC,EAAC,iCAAiC,GAAG,EAC5C,eAAM,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,GAAI,EACtC,eAAM,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,GAAI,IACvC,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAC5B,aAAa,EACb,SAAS,GAAG,IAAI,EAChB,WAAW,GAAG,KAAK,EACnB,MAAM,EACN,OAAO,GAAG,cAAc,EACxB,SAAS,GACU;IACnB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;IAE1D,OAAO,CACL,8BACE,iBACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,SAAS,kBACN,OAAO,gBACT,OAAO,mBACJ,IAAI,EACnB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,YAEjC,KAAC,OAAO,KAAG,GACJ,EACR,IAAI;gBACH,OAAO,QAAQ,KAAK,WAAW;gBAC/B,YAAY,CACV,KAAC,aAAa,IACZ,aAAa,EAAE,aAAa,EAC5B,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,WAAW,EACxB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE;wBACjB,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;oBACnB,CAAC,GACD,EACF,QAAQ,CAAC,IAAI,CACd,IACF,CACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Format probing for MediaRecorder.
3
+ *
4
+ * Different browsers expose different container/codec combinations. Chrome
5
+ * and Firefox produce WebM (VP8/VP9 + Opus); Safari produces MP4 (H.264 +
6
+ * AAC). We probe at runtime via `MediaRecorder.isTypeSupported()` and pick
7
+ * the best supported option, falling back to whatever the browser hands
8
+ * back when no probe succeeds.
9
+ */
10
+ /** What the recorded stream is intended to capture. */
11
+ export type CaptureKind = 'audio' | 'video';
12
+ /** A probed format choice — what to pass to `MediaRecorder` and where to write it. */
13
+ export interface ResolvedFormat {
14
+ /** MIME type to pass to `new MediaRecorder(stream, { mimeType })`. Empty string means "let the browser pick". */
15
+ mimeType: string;
16
+ /** File extension to use when writing to the container, including the leading dot. */
17
+ extension: string;
18
+ /** Container directory inside the `ContentContainer` (no trailing slash). */
19
+ directory: 'audio' | 'video';
20
+ }
21
+ /**
22
+ * Resolve the format the recorder will use for a given capture kind. If a
23
+ * `preferred` MIME type is supported, it wins; otherwise we fall through
24
+ * the priority list. When nothing matches (extremely old browser), we
25
+ * return an empty `mimeType` — `MediaRecorder` will pick a default and we
26
+ * tag the file with `.webm` as a best guess.
27
+ */
28
+ export declare function resolveFormat(kind: CaptureKind, preferred?: string): ResolvedFormat;
29
+ /**
30
+ * `MediaRecorder` support probe. Returns false when running in a
31
+ * non-browser environment (e.g. SSR) or on a browser that doesn't
32
+ * implement the API at all.
33
+ */
34
+ export declare function supportsMediaRecorder(): boolean;
35
+ /**
36
+ * `getUserMedia` support probe (for mic / camera capture).
37
+ */
38
+ export declare function supportsUserMedia(): boolean;
39
+ /**
40
+ * `getDisplayMedia` support probe (for screen capture). Browsers may
41
+ * implement `mediaDevices` without `getDisplayMedia` (Firefox on Android
42
+ * being the long-standing example), so this is its own probe.
43
+ */
44
+ export declare function supportsDisplayMedia(): boolean;
45
+ /**
46
+ * Build a default filename for a recording. `basename` is a hint
47
+ * (e.g. user-typed name); when omitted, a sortable timestamp is used so
48
+ * concurrent recordings don't collide.
49
+ */
50
+ export declare function buildFilename(kind: CaptureKind, extension: string, basename?: string): string;
51
+ //# sourceMappingURL=formats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formats.d.ts","sourceRoot":"","sources":["../../src/recorder/formats.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,uDAAuD;AACvD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,CAAC;AAE5C,sFAAsF;AACtF,MAAM,WAAW,cAAc;IAC7B,iHAAiH;IACjH,QAAQ,EAAE,MAAM,CAAC;IACjB,sFAAsF;IACtF,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;CAC9B;AAiED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,cAAc,CAMnF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAM3C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAM9C;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAmB7F"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Format probing for MediaRecorder.
3
+ *
4
+ * Different browsers expose different container/codec combinations. Chrome
5
+ * and Firefox produce WebM (VP8/VP9 + Opus); Safari produces MP4 (H.264 +
6
+ * AAC). We probe at runtime via `MediaRecorder.isTypeSupported()` and pick
7
+ * the best supported option, falling back to whatever the browser hands
8
+ * back when no probe succeeds.
9
+ */
10
+ /**
11
+ * Preferred MIME types for audio-only recording, in priority order. The
12
+ * first one `MediaRecorder.isTypeSupported()` accepts wins.
13
+ *
14
+ * Opus in a WebM container is the modern default (Chrome, Firefox, Edge).
15
+ * MP4/AAC covers Safari. Bare strings are kept as a final fallback for
16
+ * older browsers that don't accept codec hints.
17
+ */
18
+ const AUDIO_CANDIDATES = [
19
+ 'audio/webm;codecs=opus',
20
+ 'audio/webm',
21
+ 'audio/mp4;codecs=mp4a.40.2',
22
+ 'audio/mp4',
23
+ 'audio/ogg;codecs=opus',
24
+ ];
25
+ /**
26
+ * Preferred MIME types for video recording. VP9/Opus on top because it
27
+ * yields good quality at modest bitrate in Chrome/Firefox. VP8 follows for
28
+ * older Chromium. MP4/H.264 covers Safari.
29
+ */
30
+ const VIDEO_CANDIDATES = [
31
+ 'video/webm;codecs=vp9,opus',
32
+ 'video/webm;codecs=vp8,opus',
33
+ 'video/webm',
34
+ 'video/mp4;codecs=avc1.42E01E,mp4a.40.2',
35
+ 'video/mp4',
36
+ ];
37
+ /**
38
+ * Map a chosen MIME type to a file extension. Best-effort — if we can't
39
+ * tell, default to `.bin` so the file is at least retrievable.
40
+ */
41
+ function extensionForMime(mimeType) {
42
+ const m = mimeType.toLowerCase();
43
+ if (m.startsWith('audio/webm'))
44
+ return '.webm';
45
+ if (m.startsWith('audio/ogg'))
46
+ return '.ogg';
47
+ if (m.startsWith('audio/mp4'))
48
+ return '.m4a';
49
+ if (m.startsWith('audio/mpeg'))
50
+ return '.mp3';
51
+ if (m.startsWith('audio/wav'))
52
+ return '.wav';
53
+ if (m.startsWith('video/webm'))
54
+ return '.webm';
55
+ if (m.startsWith('video/mp4'))
56
+ return '.mp4';
57
+ return '.bin';
58
+ }
59
+ /**
60
+ * Probe `MediaRecorder.isTypeSupported()` and return the first supported
61
+ * MIME type from the candidate list. Returns `null` when the
62
+ * MediaRecorder API itself is unavailable or none of the candidates pass.
63
+ */
64
+ function probeMimeType(candidates) {
65
+ if (typeof MediaRecorder === 'undefined')
66
+ return null;
67
+ for (const candidate of candidates) {
68
+ try {
69
+ if (MediaRecorder.isTypeSupported(candidate))
70
+ return candidate;
71
+ }
72
+ catch {
73
+ // isTypeSupported isn't supposed to throw, but Safari has historically
74
+ // misbehaved on unknown codec strings. Keep probing.
75
+ }
76
+ }
77
+ return null;
78
+ }
79
+ /**
80
+ * Resolve the format the recorder will use for a given capture kind. If a
81
+ * `preferred` MIME type is supported, it wins; otherwise we fall through
82
+ * the priority list. When nothing matches (extremely old browser), we
83
+ * return an empty `mimeType` — `MediaRecorder` will pick a default and we
84
+ * tag the file with `.webm` as a best guess.
85
+ */
86
+ export function resolveFormat(kind, preferred) {
87
+ const candidates = kind === 'audio' ? AUDIO_CANDIDATES : VIDEO_CANDIDATES;
88
+ const probed = (preferred && probeMimeType([preferred])) ?? probeMimeType(candidates) ?? '';
89
+ const directory = kind === 'audio' ? 'audio' : 'video';
90
+ const extension = probed ? extensionForMime(probed) : '.webm';
91
+ return { mimeType: probed, extension, directory };
92
+ }
93
+ /**
94
+ * `MediaRecorder` support probe. Returns false when running in a
95
+ * non-browser environment (e.g. SSR) or on a browser that doesn't
96
+ * implement the API at all.
97
+ */
98
+ export function supportsMediaRecorder() {
99
+ return typeof MediaRecorder !== 'undefined';
100
+ }
101
+ /**
102
+ * `getUserMedia` support probe (for mic / camera capture).
103
+ */
104
+ export function supportsUserMedia() {
105
+ return (typeof navigator !== 'undefined' &&
106
+ typeof navigator.mediaDevices !== 'undefined' &&
107
+ typeof navigator.mediaDevices.getUserMedia === 'function');
108
+ }
109
+ /**
110
+ * `getDisplayMedia` support probe (for screen capture). Browsers may
111
+ * implement `mediaDevices` without `getDisplayMedia` (Firefox on Android
112
+ * being the long-standing example), so this is its own probe.
113
+ */
114
+ export function supportsDisplayMedia() {
115
+ return (typeof navigator !== 'undefined' &&
116
+ typeof navigator.mediaDevices !== 'undefined' &&
117
+ typeof navigator.mediaDevices.getDisplayMedia === 'function');
118
+ }
119
+ /**
120
+ * Build a default filename for a recording. `basename` is a hint
121
+ * (e.g. user-typed name); when omitted, a sortable timestamp is used so
122
+ * concurrent recordings don't collide.
123
+ */
124
+ export function buildFilename(kind, extension, basename) {
125
+ const safe = basename
126
+ ? basename
127
+ .trim()
128
+ .replace(/[\\/:*?"<>|]+/g, '-')
129
+ .replace(/\s+/g, '-')
130
+ : '';
131
+ if (safe)
132
+ return `${safe}${extension}`;
133
+ const now = new Date();
134
+ const stamp = now.getFullYear().toString().padStart(4, '0') +
135
+ (now.getMonth() + 1).toString().padStart(2, '0') +
136
+ now.getDate().toString().padStart(2, '0') +
137
+ '-' +
138
+ now.getHours().toString().padStart(2, '0') +
139
+ now.getMinutes().toString().padStart(2, '0') +
140
+ now.getSeconds().toString().padStart(2, '0');
141
+ const prefix = kind === 'audio' ? 'narration' : 'recording';
142
+ return `${prefix}-${stamp}${extension}`;
143
+ }
144
+ //# sourceMappingURL=formats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formats.js","sourceRoot":"","sources":["../../src/recorder/formats.ts"],"names":[],"mappings":"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"}