@signalcore/ui 0.1.0 → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (611) hide show
  1. package/README.md +896 -513
  2. package/dist/AgentAbout.d.ts +186 -0
  3. package/dist/AgentAbout.js +1020 -0
  4. package/dist/AgentAbout.js.map +1 -0
  5. package/dist/AgentCard.d.ts +49 -0
  6. package/dist/AgentCard.js +77 -0
  7. package/dist/AgentCard.js.map +1 -0
  8. package/dist/AgentChat.d.ts +233 -0
  9. package/dist/AgentChat.js +1127 -0
  10. package/dist/AgentChat.js.map +1 -0
  11. package/dist/AgentSpace.d.ts +112 -0
  12. package/dist/AgentSpace.js +339 -0
  13. package/dist/AgentSpace.js.map +1 -0
  14. package/dist/AgentTasks.d.ts +48 -0
  15. package/dist/AgentTasks.js +120 -0
  16. package/dist/AgentTasks.js.map +1 -0
  17. package/dist/BrowserView.d.ts +52 -0
  18. package/dist/BrowserView.js +328 -0
  19. package/dist/BrowserView.js.map +1 -0
  20. package/dist/FileView.d.ts +63 -0
  21. package/dist/FileView.js +449 -0
  22. package/dist/FileView.js.map +1 -0
  23. package/dist/Modes.d.ts +13 -0
  24. package/dist/Modes.js +75 -0
  25. package/dist/Modes.js.map +1 -0
  26. package/dist/VoiceCall.d.ts +91 -0
  27. package/dist/VoiceCall.js +302 -0
  28. package/dist/VoiceCall.js.map +1 -0
  29. package/dist/about.d.ts +212 -0
  30. package/dist/about.js +136 -0
  31. package/dist/about.js.map +1 -0
  32. package/dist/agentIcons.d.ts +33 -0
  33. package/dist/agentIcons.js +36 -0
  34. package/dist/agentIcons.js.map +1 -0
  35. package/dist/automation/Automation.d.ts +35 -0
  36. package/dist/automation/Automation.js +268 -0
  37. package/dist/automation/Automation.js.map +1 -0
  38. package/dist/automation/RunView.d.ts +25 -0
  39. package/dist/automation/RunView.js +187 -0
  40. package/dist/automation/RunView.js.map +1 -0
  41. package/dist/automation/cron.d.ts +41 -0
  42. package/dist/automation/cron.js +169 -0
  43. package/dist/automation/cron.js.map +1 -0
  44. package/dist/automation/marks.js +121 -0
  45. package/dist/automation/marks.js.map +1 -0
  46. package/dist/automation/messages.d.ts +113 -0
  47. package/dist/automation/messages.js +113 -0
  48. package/dist/automation/messages.js.map +1 -0
  49. package/dist/automation/record.d.ts +47 -0
  50. package/dist/automation/record.js +177 -0
  51. package/dist/automation/record.js.map +1 -0
  52. package/dist/automation/types.d.ts +143 -0
  53. package/dist/automation/when.d.ts +36 -0
  54. package/dist/automation/when.js +168 -0
  55. package/dist/automation/when.js.map +1 -0
  56. package/dist/blocks.d.ts +185 -0
  57. package/dist/browser.js +292 -0
  58. package/dist/browser.js.map +1 -0
  59. package/dist/call.d.ts +89 -0
  60. package/dist/call.js +218 -0
  61. package/dist/call.js.map +1 -0
  62. package/dist/channelParts.js +26 -0
  63. package/dist/channelParts.js.map +1 -0
  64. package/dist/classes.js +8 -3
  65. package/dist/classes.js.map +1 -0
  66. package/dist/client.d.ts +146 -54
  67. package/dist/client.js +204 -1
  68. package/dist/client.js.map +1 -0
  69. package/dist/conversationFiles.js +46 -0
  70. package/dist/conversationFiles.js.map +1 -0
  71. package/dist/credentials.d.ts +45 -0
  72. package/dist/credentials.js +98 -0
  73. package/dist/credentials.js.map +1 -0
  74. package/dist/dev.js +17 -0
  75. package/dist/dev.js.map +1 -0
  76. package/dist/es.d.ts +17 -0
  77. package/dist/es.js +382 -0
  78. package/dist/es.js.map +1 -0
  79. package/dist/files.d.ts +21 -0
  80. package/dist/files.js +214 -0
  81. package/dist/files.js.map +1 -0
  82. package/dist/frames.d.ts +115 -0
  83. package/dist/frames.js +219 -0
  84. package/dist/frames.js.map +1 -0
  85. package/dist/icons.js +29 -0
  86. package/dist/icons.js.map +1 -0
  87. package/dist/index.d.ts +63 -60
  88. package/dist/index.js +59 -45
  89. package/dist/kit/AudioPlayer.d.ts +20 -0
  90. package/dist/kit/AudioPlayer.js +116 -0
  91. package/dist/kit/AudioPlayer.js.map +1 -0
  92. package/dist/kit/Button.d.ts +29 -0
  93. package/dist/kit/Button.js +59 -0
  94. package/dist/kit/Button.js.map +1 -0
  95. package/dist/kit/Card.d.ts +16 -0
  96. package/dist/kit/Card.js +36 -0
  97. package/dist/kit/Card.js.map +1 -0
  98. package/dist/kit/Chart.js +152 -0
  99. package/dist/kit/Chart.js.map +1 -0
  100. package/dist/kit/Choices.d.ts +21 -0
  101. package/dist/kit/Choices.js +99 -0
  102. package/dist/kit/Choices.js.map +1 -0
  103. package/dist/kit/Combobox.d.ts +26 -0
  104. package/dist/kit/Combobox.js +190 -0
  105. package/dist/kit/Combobox.js.map +1 -0
  106. package/dist/kit/DateField.d.ts +17 -0
  107. package/dist/kit/DateField.js +133 -0
  108. package/dist/kit/DateField.js.map +1 -0
  109. package/dist/kit/Field.d.ts +40 -0
  110. package/dist/kit/Field.js +98 -0
  111. package/dist/kit/Field.js.map +1 -0
  112. package/dist/kit/FileField.d.ts +113 -0
  113. package/dist/kit/FileField.js +341 -0
  114. package/dist/kit/FileField.js.map +1 -0
  115. package/dist/kit/FileMark.d.ts +15 -0
  116. package/dist/kit/FileMark.js +39 -0
  117. package/dist/kit/FileMark.js.map +1 -0
  118. package/dist/kit/Inputs.d.ts +59 -0
  119. package/dist/kit/Inputs.js +205 -0
  120. package/dist/kit/Inputs.js.map +1 -0
  121. package/dist/kit/List.d.ts +47 -0
  122. package/dist/kit/List.js +85 -0
  123. package/dist/kit/List.js.map +1 -0
  124. package/dist/kit/Mark.d.ts +30 -0
  125. package/dist/kit/Mark.js +27 -0
  126. package/dist/kit/Mark.js.map +1 -0
  127. package/dist/kit/MarkStack.d.ts +15 -0
  128. package/dist/kit/MarkStack.js +26 -0
  129. package/dist/kit/MarkStack.js.map +1 -0
  130. package/dist/kit/Note.d.ts +11 -0
  131. package/dist/kit/Note.js +31 -0
  132. package/dist/kit/Note.js.map +1 -0
  133. package/dist/kit/Popover.js +90 -0
  134. package/dist/kit/Popover.js.map +1 -0
  135. package/dist/kit/RangeField.d.ts +14 -0
  136. package/dist/kit/RangeField.js +47 -0
  137. package/dist/kit/RangeField.js.map +1 -0
  138. package/dist/kit/RatingField.d.ts +14 -0
  139. package/dist/kit/RatingField.js +50 -0
  140. package/dist/kit/RatingField.js.map +1 -0
  141. package/dist/kit/Stat.d.ts +26 -0
  142. package/dist/kit/Stat.js +46 -0
  143. package/dist/kit/Stat.js.map +1 -0
  144. package/dist/kit/Switch.d.ts +14 -0
  145. package/dist/kit/Switch.js +21 -0
  146. package/dist/kit/Switch.js.map +1 -0
  147. package/dist/kit/Tag.d.ts +16 -0
  148. package/dist/kit/Tag.js +20 -0
  149. package/dist/kit/Tag.js.map +1 -0
  150. package/dist/kit/Tile.d.ts +34 -0
  151. package/dist/kit/Tile.js +52 -0
  152. package/dist/kit/Tile.js.map +1 -0
  153. package/dist/kit/TimeField.d.ts +31 -0
  154. package/dist/kit/TimeField.js +109 -0
  155. package/dist/kit/TimeField.js.map +1 -0
  156. package/dist/kit/context.d.ts +22 -0
  157. package/dist/kit/context.js +46 -0
  158. package/dist/kit/context.js.map +1 -0
  159. package/dist/kit/dates.d.ts +14 -0
  160. package/dist/kit/dates.js +129 -0
  161. package/dist/kit/dates.js.map +1 -0
  162. package/dist/kit/messages.d.ts +99 -0
  163. package/dist/kit/messages.js +66 -0
  164. package/dist/kit/messages.js.map +1 -0
  165. package/dist/kit/numbers.d.ts +12 -0
  166. package/dist/kit/numbers.js +40 -0
  167. package/dist/kit/numbers.js.map +1 -0
  168. package/dist/kit/options.d.ts +10 -0
  169. package/dist/kit/options.js +23 -0
  170. package/dist/kit/options.js.map +1 -0
  171. package/dist/kit/uploads.d.ts +42 -0
  172. package/dist/kit/uploads.js +165 -0
  173. package/dist/kit/uploads.js.map +1 -0
  174. package/dist/kit/waveform.js +76 -0
  175. package/dist/kit/waveform.js.map +1 -0
  176. package/dist/locale.d.ts +1 -0
  177. package/dist/locale.js +1 -0
  178. package/dist/markdown.js +84 -0
  179. package/dist/markdown.js.map +1 -0
  180. package/dist/marks.js +217 -0
  181. package/dist/marks.js.map +1 -0
  182. package/dist/reveal.js +48 -0
  183. package/dist/reveal.js.map +1 -0
  184. package/dist/stepGlyphs.js +62 -0
  185. package/dist/stepGlyphs.js.map +1 -0
  186. package/dist/surface/Form.js +264 -0
  187. package/dist/surface/Form.js.map +1 -0
  188. package/dist/surface/Markdown.js +42 -0
  189. package/dist/surface/Markdown.js.map +1 -0
  190. package/dist/surface/Surface.d.ts +31 -17
  191. package/dist/surface/Surface.js +480 -57
  192. package/dist/surface/Surface.js.map +1 -0
  193. package/dist/surface/scope.d.ts +32 -0
  194. package/dist/surface/scope.js +23 -0
  195. package/dist/surface/scope.js.map +1 -0
  196. package/dist/surface/values.d.ts +44 -0
  197. package/dist/surface/values.js +237 -0
  198. package/dist/surface/values.js.map +1 -0
  199. package/dist/tint.d.ts +10 -0
  200. package/dist/tint.js +19 -0
  201. package/dist/tint.js.map +1 -0
  202. package/dist/types.d.ts +541 -0
  203. package/dist/types.js +16 -0
  204. package/dist/types.js.map +1 -0
  205. package/dist/useAgentFace.d.ts +18 -0
  206. package/dist/useAgentFace.js +45 -0
  207. package/dist/useAgentFace.js.map +1 -0
  208. package/dist/useCall.d.ts +39 -0
  209. package/dist/useCall.js +273 -0
  210. package/dist/useCall.js.map +1 -0
  211. package/dist/useConversation.d.ts +77 -0
  212. package/dist/useConversation.js +523 -0
  213. package/dist/useConversation.js.map +1 -0
  214. package/dist/useDictation.d.ts +17 -0
  215. package/dist/useDictation.js +68 -0
  216. package/dist/useDictation.js.map +1 -0
  217. package/dist/useLive.d.ts +26 -0
  218. package/dist/useLive.js +88 -0
  219. package/dist/useLive.js.map +1 -0
  220. package/dist/usePolled.js +68 -0
  221. package/dist/usePolled.js.map +1 -0
  222. package/dist/voice/Orb.d.ts +10 -9
  223. package/dist/voice/Orb.js +43 -39
  224. package/dist/voice/Orb.js.map +1 -0
  225. package/dist/voice/StillOrb.js +33 -0
  226. package/dist/voice/StillOrb.js.map +1 -0
  227. package/dist/voice/WebGLOrb.js +98 -0
  228. package/dist/voice/WebGLOrb.js.map +1 -0
  229. package/dist/voice/fluidDots.js +161 -0
  230. package/dist/voice/fluidDots.js.map +1 -0
  231. package/dist/voice/motion.js +84 -0
  232. package/dist/voice/motion.js.map +1 -0
  233. package/dist/voice/orbs.d.ts +32 -0
  234. package/dist/voice/orbs.js +16 -0
  235. package/dist/voice/orbs.js.map +1 -0
  236. package/dist/voice/useReducedMotion.js +16 -16
  237. package/dist/voice/useReducedMotion.js.map +1 -0
  238. package/dist/voice/wave.js +116 -0
  239. package/dist/voice/wave.js.map +1 -0
  240. package/dist/voice/webgl.js +177 -0
  241. package/dist/voice/webgl.js.map +1 -0
  242. package/dist/widget.js +284 -8
  243. package/package.json +49 -39
  244. package/src/AgentAbout.tsx +1621 -0
  245. package/src/AgentCard.tsx +123 -0
  246. package/src/AgentChat.tsx +1812 -0
  247. package/src/AgentSpace.tsx +540 -0
  248. package/src/AgentTasks.tsx +163 -0
  249. package/src/BrowserView.tsx +442 -0
  250. package/src/FileView.tsx +620 -0
  251. package/src/Modes.tsx +112 -0
  252. package/src/VoiceCall.tsx +411 -0
  253. package/src/about.ts +355 -0
  254. package/src/agentIcons.ts +56 -0
  255. package/src/automation/Automation.tsx +308 -0
  256. package/src/automation/RunView.tsx +213 -0
  257. package/src/automation/cron.ts +196 -0
  258. package/src/automation/marks.tsx +144 -0
  259. package/src/automation/messages.ts +231 -0
  260. package/src/automation/record.ts +206 -0
  261. package/src/automation/types.ts +146 -0
  262. package/src/automation/when.ts +195 -0
  263. package/src/blocks.ts +249 -0
  264. package/src/browser.ts +334 -0
  265. package/src/call.ts +300 -0
  266. package/src/channelParts.ts +17 -0
  267. package/src/classes.ts +10 -0
  268. package/src/client.ts +397 -0
  269. package/src/conversationFiles.ts +54 -0
  270. package/src/credentials.ts +158 -0
  271. package/src/dev.ts +20 -0
  272. package/src/es.ts +423 -0
  273. package/src/files.ts +238 -0
  274. package/src/frames.ts +291 -0
  275. package/src/icons.tsx +49 -0
  276. package/src/index.ts +271 -0
  277. package/src/kit/AudioPlayer.tsx +129 -0
  278. package/src/kit/Button.tsx +97 -0
  279. package/src/kit/Card.tsx +47 -0
  280. package/src/kit/Chart.tsx +129 -0
  281. package/src/kit/Choices.tsx +131 -0
  282. package/src/kit/Combobox.tsx +247 -0
  283. package/src/kit/DateField.tsx +156 -0
  284. package/src/kit/Field.tsx +137 -0
  285. package/src/kit/FileField.tsx +492 -0
  286. package/src/kit/FileMark.tsx +56 -0
  287. package/src/kit/Inputs.tsx +250 -0
  288. package/src/kit/List.tsx +135 -0
  289. package/src/kit/Mark.tsx +64 -0
  290. package/src/kit/MarkStack.tsx +29 -0
  291. package/src/kit/Note.tsx +42 -0
  292. package/src/kit/Popover.tsx +121 -0
  293. package/src/kit/RangeField.tsx +53 -0
  294. package/src/kit/RatingField.tsx +62 -0
  295. package/src/kit/Stat.tsx +60 -0
  296. package/src/kit/Switch.tsx +28 -0
  297. package/src/kit/Tag.tsx +32 -0
  298. package/src/kit/Tile.tsx +74 -0
  299. package/src/kit/TimeField.tsx +157 -0
  300. package/src/kit/context.tsx +246 -0
  301. package/src/kit/dates.ts +150 -0
  302. package/src/kit/messages.ts +160 -0
  303. package/src/kit/numbers.ts +44 -0
  304. package/src/kit/options.ts +30 -0
  305. package/src/kit/uploads.ts +244 -0
  306. package/src/kit/waveform.ts +84 -0
  307. package/src/locale.ts +6 -0
  308. package/src/markdown.ts +69 -0
  309. package/src/marks.tsx +328 -0
  310. package/src/reveal.ts +52 -0
  311. package/src/stepGlyphs.ts +83 -0
  312. package/src/styles.css +6970 -0
  313. package/src/surface/Form.tsx +299 -0
  314. package/src/surface/Markdown.tsx +55 -0
  315. package/src/surface/Surface.tsx +605 -0
  316. package/src/surface/scope.ts +82 -0
  317. package/src/surface/values.ts +361 -0
  318. package/src/tint.ts +14 -0
  319. package/src/types.ts +604 -0
  320. package/src/useAgentFace.ts +47 -0
  321. package/src/useCall.ts +292 -0
  322. package/src/useConversation.ts +627 -0
  323. package/src/useDictation.ts +83 -0
  324. package/src/useLive.ts +115 -0
  325. package/src/usePolled.ts +60 -0
  326. package/src/voice/Orb.tsx +45 -0
  327. package/src/voice/StillOrb.tsx +29 -0
  328. package/src/voice/WebGLOrb.tsx +98 -0
  329. package/src/voice/fluidDots.tsx +171 -0
  330. package/src/voice/motion.ts +112 -0
  331. package/src/voice/orbs.ts +39 -0
  332. package/src/voice/useReducedMotion.ts +24 -0
  333. package/src/voice/wave.tsx +129 -0
  334. package/src/voice/webgl.ts +209 -0
  335. package/src/widget/css.d.ts +5 -0
  336. package/src/widget/element.tsx +535 -0
  337. package/src/widget/index.ts +10 -0
  338. package/src/widget/mount.ts +27 -0
  339. package/src/widget/widget.css +253 -0
  340. package/dist/SignalcoreProvider.d.ts +0 -113
  341. package/dist/SignalcoreProvider.js +0 -84
  342. package/dist/automations/AppMarks.d.ts +0 -11
  343. package/dist/automations/AppMarks.js +0 -18
  344. package/dist/automations/AutomationCard.d.ts +0 -27
  345. package/dist/automations/AutomationCard.js +0 -53
  346. package/dist/automations/AutomationsWindow.d.ts +0 -38
  347. package/dist/automations/AutomationsWindow.js +0 -57
  348. package/dist/automations/Card.d.ts +0 -46
  349. package/dist/automations/Card.js +0 -45
  350. package/dist/automations/ScheduleMarks.d.ts +0 -13
  351. package/dist/automations/ScheduleMarks.js +0 -24
  352. package/dist/automations/presentationIcons.d.ts +0 -7
  353. package/dist/automations/presentationIcons.js +0 -67
  354. package/dist/automations/schedule.d.ts +0 -25
  355. package/dist/automations/schedule.js +0 -59
  356. package/dist/automations/time.d.ts +0 -3
  357. package/dist/automations/time.js +0 -25
  358. package/dist/browser/BrowserView.d.ts +0 -43
  359. package/dist/browser/BrowserView.js +0 -94
  360. package/dist/browser/room.d.ts +0 -21
  361. package/dist/browser/room.js +0 -33
  362. package/dist/browser/useBrowserSession.d.ts +0 -17
  363. package/dist/browser/useBrowserSession.js +0 -67
  364. package/dist/builder/BuilderChat.d.ts +0 -32
  365. package/dist/builder/BuilderChat.js +0 -41
  366. package/dist/builder/BuilderTranscript.d.ts +0 -49
  367. package/dist/builder/BuilderTranscript.js +0 -62
  368. package/dist/builder/StatusLine.d.ts +0 -8
  369. package/dist/builder/StatusLine.js +0 -17
  370. package/dist/builder/answer.d.ts +0 -7
  371. package/dist/builder/answer.js +0 -8
  372. package/dist/builder/blocks.d.ts +0 -31
  373. package/dist/builder/blocks.js +0 -74
  374. package/dist/builder/items.d.ts +0 -15
  375. package/dist/builder/items.js +0 -21
  376. package/dist/builder/steps.d.ts +0 -20
  377. package/dist/builder/steps.js +0 -120
  378. package/dist/builder/time.d.ts +0 -4
  379. package/dist/builder/time.js +0 -24
  380. package/dist/builder/useBuildSession.d.ts +0 -36
  381. package/dist/builder/useBuildSession.js +0 -130
  382. package/dist/builder/workingOn.d.ts +0 -7
  383. package/dist/builder/workingOn.js +0 -15
  384. package/dist/chat/AgentChat.d.ts +0 -37
  385. package/dist/chat/AgentChat.js +0 -21
  386. package/dist/chat/ChatView.d.ts +0 -25
  387. package/dist/chat/ChatView.js +0 -34
  388. package/dist/chat/Composer.d.ts +0 -20
  389. package/dist/chat/Composer.js +0 -22
  390. package/dist/chat/MessageRow.d.ts +0 -22
  391. package/dist/chat/MessageRow.js +0 -32
  392. package/dist/chat/arrival.d.ts +0 -15
  393. package/dist/chat/arrival.js +0 -25
  394. package/dist/chat/history.d.ts +0 -24
  395. package/dist/chat/history.js +0 -45
  396. package/dist/chat/moments.d.ts +0 -25
  397. package/dist/chat/moments.js +0 -72
  398. package/dist/chat/types.d.ts +0 -12
  399. package/dist/chat/types.js +0 -1
  400. package/dist/chat/useComposer.d.ts +0 -46
  401. package/dist/chat/useComposer.js +0 -62
  402. package/dist/chat/useConversation.d.ts +0 -35
  403. package/dist/chat/useConversation.js +0 -71
  404. package/dist/chat/useStickToBottom.d.ts +0 -9
  405. package/dist/chat/useStickToBottom.js +0 -33
  406. package/dist/chat/useTurns.d.ts +0 -49
  407. package/dist/chat/useTurns.js +0 -111
  408. package/dist/classes.d.ts +0 -2
  409. package/dist/development.d.ts +0 -5
  410. package/dist/development.js +0 -8
  411. package/dist/flow/FlowWindow.d.ts +0 -42
  412. package/dist/flow/FlowWindow.js +0 -126
  413. package/dist/flow/index.d.ts +0 -16
  414. package/dist/flow/index.js +0 -16
  415. package/dist/flow/kinds.d.ts +0 -23
  416. package/dist/flow/kinds.js +0 -48
  417. package/dist/flow/map.d.ts +0 -44
  418. package/dist/flow/map.js +0 -225
  419. package/dist/flow/nodePaths.d.ts +0 -7
  420. package/dist/flow/nodePaths.js +0 -17
  421. package/dist/flow/relations.d.ts +0 -42
  422. package/dist/flow/relations.js +0 -174
  423. package/dist/host.d.ts +0 -124
  424. package/dist/host.js +0 -1
  425. package/dist/live/LiveView.d.ts +0 -28
  426. package/dist/live/LiveView.js +0 -55
  427. package/dist/live/capture.d.ts +0 -20
  428. package/dist/live/capture.js +0 -100
  429. package/dist/live/follow.d.ts +0 -26
  430. package/dist/live/follow.js +0 -72
  431. package/dist/live/paint.d.ts +0 -13
  432. package/dist/live/paint.js +0 -77
  433. package/dist/live/useLiveStream.d.ts +0 -16
  434. package/dist/live/useLiveStream.js +0 -57
  435. package/dist/look.d.ts +0 -33
  436. package/dist/look.js +0 -241
  437. package/dist/messages/en.d.ts +0 -3
  438. package/dist/messages/en.js +0 -251
  439. package/dist/messages/es.d.ts +0 -3
  440. package/dist/messages/es.js +0 -251
  441. package/dist/messages/index.d.ts +0 -16
  442. package/dist/messages/index.js +0 -33
  443. package/dist/messages/types.d.ts +0 -246
  444. package/dist/messages/types.js +0 -1
  445. package/dist/parts/Button.d.ts +0 -18
  446. package/dist/parts/Button.js +0 -17
  447. package/dist/parts/Icon.d.ts +0 -39
  448. package/dist/parts/Icon.js +0 -37
  449. package/dist/parts/Input.d.ts +0 -6
  450. package/dist/parts/Input.js +0 -11
  451. package/dist/parts/Spinner.d.ts +0 -2
  452. package/dist/parts/Spinner.js +0 -7
  453. package/dist/patterns.d.ts +0 -15
  454. package/dist/patterns.js +0 -5
  455. package/dist/presets.d.ts +0 -82
  456. package/dist/presets.js +0 -81
  457. package/dist/primitives.d.ts +0 -22
  458. package/dist/primitives.js +0 -58
  459. package/dist/request/RequestCard.d.ts +0 -34
  460. package/dist/request/RequestCard.js +0 -101
  461. package/dist/request/approval/ApprovalPreview.d.ts +0 -5
  462. package/dist/request/approval/ApprovalPreview.js +0 -27
  463. package/dist/request/approval/shapes.d.ts +0 -32
  464. package/dist/request/approval/shapes.js +0 -68
  465. package/dist/request/apps.d.ts +0 -11
  466. package/dist/request/apps.js +0 -27
  467. package/dist/request/cards.d.ts +0 -12
  468. package/dist/request/cards.js +0 -24
  469. package/dist/request/deliver.d.ts +0 -12
  470. package/dist/request/deliver.js +0 -21
  471. package/dist/request/handOver.d.ts +0 -18
  472. package/dist/request/handOver.js +0 -33
  473. package/dist/request/kinds/Approval.d.ts +0 -3
  474. package/dist/request/kinds/Approval.js +0 -9
  475. package/dist/request/kinds/Choice.d.ts +0 -3
  476. package/dist/request/kinds/Choice.js +0 -8
  477. package/dist/request/kinds/Connect.d.ts +0 -9
  478. package/dist/request/kinds/Connect.js +0 -119
  479. package/dist/request/kinds/FreeText.d.ts +0 -3
  480. package/dist/request/kinds/FreeText.js +0 -20
  481. package/dist/request/kinds/HandOver.d.ts +0 -13
  482. package/dist/request/kinds/HandOver.js +0 -20
  483. package/dist/request/kinds/Secret.d.ts +0 -7
  484. package/dist/request/kinds/Secret.js +0 -49
  485. package/dist/request/kinds/Upload.d.ts +0 -6
  486. package/dist/request/kinds/Upload.js +0 -47
  487. package/dist/request/types.d.ts +0 -83
  488. package/dist/request/types.js +0 -1
  489. package/dist/safeUrl.d.ts +0 -6
  490. package/dist/safeUrl.js +0 -8
  491. package/dist/stream/builder.d.ts +0 -176
  492. package/dist/stream/builder.js +0 -202
  493. package/dist/stream/reduce.d.ts +0 -51
  494. package/dist/stream/reduce.js +0 -58
  495. package/dist/stream/untilAborted.d.ts +0 -7
  496. package/dist/stream/untilAborted.js +0 -32
  497. package/dist/stream/useRunStream.d.ts +0 -26
  498. package/dist/stream/useRunStream.js +0 -137
  499. package/dist/styles.css +0 -2318
  500. package/dist/surface/HostNode.d.ts +0 -14
  501. package/dist/surface/HostNode.js +0 -30
  502. package/dist/surface/Node.d.ts +0 -7
  503. package/dist/surface/Node.js +0 -49
  504. package/dist/surface/SurfaceBoundary.d.ts +0 -26
  505. package/dist/surface/SurfaceBoundary.js +0 -20
  506. package/dist/surface/bindings.d.ts +0 -14
  507. package/dist/surface/bindings.js +0 -37
  508. package/dist/surface/check.d.ts +0 -27
  509. package/dist/surface/check.js +0 -102
  510. package/dist/surface/format.d.ts +0 -10
  511. package/dist/surface/format.js +0 -32
  512. package/dist/surface/hosts.d.ts +0 -6
  513. package/dist/surface/hosts.js +0 -11
  514. package/dist/surface/scene.d.ts +0 -21
  515. package/dist/surface/scene.js +0 -8
  516. package/dist/surface/templates/Browser.d.ts +0 -6
  517. package/dist/surface/templates/Browser.js +0 -11
  518. package/dist/surface/templates/Chart.d.ts +0 -6
  519. package/dist/surface/templates/Chart.js +0 -13
  520. package/dist/surface/templates/Choices.d.ts +0 -3
  521. package/dist/surface/templates/Choices.js +0 -12
  522. package/dist/surface/templates/Form.d.ts +0 -3
  523. package/dist/surface/templates/Form.js +0 -44
  524. package/dist/surface/templates/KeyValue.d.ts +0 -3
  525. package/dist/surface/templates/KeyValue.js +0 -7
  526. package/dist/surface/templates/Layout.d.ts +0 -5
  527. package/dist/surface/templates/Layout.js +0 -16
  528. package/dist/surface/templates/Live.d.ts +0 -6
  529. package/dist/surface/templates/Live.js +0 -9
  530. package/dist/surface/templates/Media.d.ts +0 -5
  531. package/dist/surface/templates/Media.js +0 -13
  532. package/dist/surface/templates/Slots.d.ts +0 -3
  533. package/dist/surface/templates/Slots.js +0 -19
  534. package/dist/surface/templates/Table.d.ts +0 -3
  535. package/dist/surface/templates/Table.js +0 -12
  536. package/dist/surface/templates/Text.d.ts +0 -4
  537. package/dist/surface/templates/Text.js +0 -15
  538. package/dist/surface/templates/index.d.ts +0 -7
  539. package/dist/surface/templates/index.js +0 -32
  540. package/dist/surface/types.d.ts +0 -68
  541. package/dist/surface/types.js +0 -6
  542. package/dist/theme.d.ts +0 -62
  543. package/dist/theme.js +0 -9
  544. package/dist/useTokens.d.ts +0 -7
  545. package/dist/useTokens.js +0 -41
  546. package/dist/voice/VoiceWindow.d.ts +0 -18
  547. package/dist/voice/VoiceWindow.js +0 -35
  548. package/dist/voice/index.d.ts +0 -13
  549. package/dist/voice/index.js +0 -12
  550. package/dist/voice/meter.d.ts +0 -16
  551. package/dist/voice/meter.js +0 -52
  552. package/dist/voice/orbColors.d.ts +0 -16
  553. package/dist/voice/orbColors.js +0 -75
  554. package/dist/voice/pushable.d.ts +0 -16
  555. package/dist/voice/pushable.js +0 -56
  556. package/dist/voice/useDictation.d.ts +0 -24
  557. package/dist/voice/useDictation.js +0 -60
  558. package/dist/voice/useReducedMotion.d.ts +0 -5
  559. package/dist/voice/useVoice.d.ts +0 -70
  560. package/dist/voice/useVoice.js +0 -197
  561. package/dist/voice/useVoicePrimitives.d.ts +0 -7
  562. package/dist/voice/useVoicePrimitives.js +0 -11
  563. package/dist/voice/voice.d.ts +0 -55
  564. package/dist/voice/voice.js +0 -9
  565. package/dist/voice/webSpeech.d.ts +0 -33
  566. package/dist/voice/webSpeech.js +0 -258
  567. package/dist/widget.js.map +0 -1
  568. package/dist/windows/AgentSpace.d.ts +0 -78
  569. package/dist/windows/AgentSpace.js +0 -135
  570. package/dist/windows/Captions.d.ts +0 -13
  571. package/dist/windows/Captions.js +0 -22
  572. package/dist/windows/Dock.d.ts +0 -37
  573. package/dist/windows/Dock.js +0 -22
  574. package/dist/windows/Journal.d.ts +0 -15
  575. package/dist/windows/Journal.js +0 -19
  576. package/dist/windows/KindMark.d.ts +0 -7
  577. package/dist/windows/KindMark.js +0 -31
  578. package/dist/windows/Pending.d.ts +0 -8
  579. package/dist/windows/Pending.js +0 -17
  580. package/dist/windows/Stage.d.ts +0 -18
  581. package/dist/windows/Stage.js +0 -21
  582. package/dist/windows/StatusLabel.d.ts +0 -9
  583. package/dist/windows/StatusLabel.js +0 -7
  584. package/dist/windows/Strip.d.ts +0 -17
  585. package/dist/windows/Strip.js +0 -42
  586. package/dist/windows/SurfaceWindow.d.ts +0 -20
  587. package/dist/windows/SurfaceWindow.js +0 -12
  588. package/dist/windows/WindowFrame.d.ts +0 -23
  589. package/dist/windows/WindowFrame.js +0 -22
  590. package/dist/windows/hearing.d.ts +0 -11
  591. package/dist/windows/hearing.js +0 -26
  592. package/dist/windows/kinds.d.ts +0 -47
  593. package/dist/windows/kinds.js +0 -28
  594. package/dist/windows/reduce.d.ts +0 -98
  595. package/dist/windows/reduce.js +0 -151
  596. package/dist/windows/registry.d.ts +0 -18
  597. package/dist/windows/registry.js +0 -61
  598. package/dist/windows/reveal.d.ts +0 -9
  599. package/dist/windows/reveal.js +0 -6
  600. package/dist/windows/space.d.ts +0 -21
  601. package/dist/windows/space.js +0 -6
  602. package/dist/windows/status.d.ts +0 -11
  603. package/dist/windows/status.js +0 -30
  604. package/dist/windows/types.d.ts +0 -15
  605. package/dist/windows/types.js +0 -1
  606. package/dist/windows/useLoaded.d.ts +0 -44
  607. package/dist/windows/useLoaded.js +0 -58
  608. package/dist/windows/useUnread.d.ts +0 -7
  609. package/dist/windows/useUnread.js +0 -21
  610. package/dist/windows/useWindows.d.ts +0 -70
  611. package/dist/windows/useWindows.js +0 -60
@@ -0,0 +1,620 @@
1
+ import { DownloadSimpleIcon } from "@phosphor-icons/react";
2
+ import { useEffect, useMemo, useState, type ReactNode } from "react";
3
+
4
+ import { formatSize } from "./about";
5
+ import { classes } from "./classes";
6
+ import {
7
+ baseName,
8
+ cleanDocument,
9
+ extensionOf,
10
+ pretty,
11
+ previewOf,
12
+ tableOf,
13
+ typedFor,
14
+ type Preview,
15
+ } from "./files";
16
+ import { AudioPlayer } from "./kit/AudioPlayer";
17
+ import { Button } from "./kit/Button";
18
+ import { KitProvider, type KitClassNames, type KitPart } from "./kit/context";
19
+ import { FileMark } from "./kit/FileMark";
20
+ import { Markdown } from "./surface/Markdown";
21
+ import type { FilePreview, PreviewSheet, PreviewSlide } from "./types";
22
+
23
+ /** The words a file's view says; a host gives its own, in its language. */
24
+ export interface FileMessages {
25
+ /** The button that saves the file under its name. */
26
+ download: string;
27
+ /** In the preview's place, for a kind that can't be shown here. */
28
+ noPreview: string;
29
+ /** Under it: what to do instead. */
30
+ noPreviewHint: string;
31
+ /** Under a long file shown only in part. */
32
+ truncated: string;
33
+ /** In the bar, for a file whose name has no extension. */
34
+ file: string;
35
+ /** A file's size, as the host's people read it. */
36
+ size: (bytes: number) => string;
37
+ /** A PDF's pages, in the bar. */
38
+ pages: (count: number) => string;
39
+ /** The tabs of a spreadsheet's sheets, for screen readers. */
40
+ sheets: string;
41
+ /** Under a sheet shown in part: its first rows of how many. */
42
+ rows: (shown: number, total: number) => string;
43
+ /** In place of a sheet with nothing in it. */
44
+ emptySheet: string;
45
+ /** Over a slide: its number. */
46
+ slide: (number: number) => string;
47
+ /** Over a slide's speaker notes. */
48
+ notes: string;
49
+ }
50
+
51
+ export const FILE_MESSAGES: FileMessages = {
52
+ download: "Download",
53
+ noPreview: "This file can't be previewed here.",
54
+ noPreviewHint: "Download it to open it on your device.",
55
+ truncated: "Only the beginning is shown. Download it to see it whole.",
56
+ file: "File",
57
+ size: (bytes) => formatSize(bytes),
58
+ pages: (count) => (count === 1 ? "1 page" : `${count} pages`),
59
+ sheets: "Sheets",
60
+ rows: (shown, total) => `The first ${shown} of ${total} rows`,
61
+ emptySheet: "This sheet is empty.",
62
+ slide: (number) => `Slide ${number}`,
63
+ notes: "Notes",
64
+ };
65
+
66
+ /** The parts, by the class each carries; `classNames` adds a host's own under the same keys. */
67
+ export type FilePart =
68
+ | "sc-file"
69
+ | "sc-file__bar"
70
+ | "sc-file__meta"
71
+ | "sc-file__body"
72
+ | "sc-file__text"
73
+ | "sc-file__plain"
74
+ | "sc-file__code"
75
+ | "sc-file__table"
76
+ | "sc-file__sheet"
77
+ | "sc-file__tabs"
78
+ | "sc-file__tab"
79
+ | "sc-file__document"
80
+ | "sc-file__slides"
81
+ | "sc-file__slide"
82
+ | "sc-file__notes"
83
+ | "sc-file__frame"
84
+ | "sc-file__image"
85
+ | "sc-file__media"
86
+ | "sc-file__none"
87
+ | "sc-file__note";
88
+
89
+ type ClassNames = Partial<Record<FilePart | KitPart, string>> | undefined;
90
+
91
+ export interface FileViewProps {
92
+ /** The file's bytes, as the API answers them (`Response.blob()`). */
93
+ blob: Blob;
94
+ /** Its name or path, with its extension: how it is read, and what it is saved as. */
95
+ name: string;
96
+ /**
97
+ * What the API made of it to draw (`client.files.preview`): a spreadsheet's sheets, a Word
98
+ * file as a document, a deck's slides, the words of a text, how a picture, a video or a sound
99
+ * is typed. Without it, what the browser can read of the bytes alone.
100
+ */
101
+ preview?: FilePreview | undefined;
102
+ messages?: Partial<FileMessages> | undefined;
103
+ classNames?: ClassNames;
104
+ }
105
+
106
+ /** The most of a file read as words: a longer one shows its beginning. */
107
+ const TEXT_LIMIT = 256 * 1024;
108
+ /** The most rows a table draws. */
109
+ const ROW_LIMIT = 500;
110
+
111
+ /**
112
+ * One file, to see and to save, whatever its kind: a bar with its kind, its size (a PDF's pages)
113
+ * and the button that saves it under its name, over the file as it reads. A PDF in the browser's
114
+ * own viewer; a spreadsheet as a grid, its header kept in view, its sheets as tabs at its foot; a
115
+ * Word file as a document at a reading measure; a deck as its slides one under another, their
116
+ * notes under each; Markdown drawn, plain words as written, a source in the mono face, wrapped,
117
+ * never run; a picture whole, a video and a sound in the browser's own players; any other kind
118
+ * says it can't be shown, and is saved. What it can't read alone (a sheet, a document, slides)
119
+ * it draws from `preview`. It fills the height it is given (a dialog's body), and scrolls inside.
120
+ * The addresses it makes for the bytes are let go when it goes.
121
+ */
122
+ export function FileView(props: FileViewProps) {
123
+ return (
124
+ <KitProvider classNames={props.classNames as KitClassNames}>
125
+ <View {...props} />
126
+ </KitProvider>
127
+ );
128
+ }
129
+
130
+ function View({ blob, name, preview, messages, classNames }: FileViewProps) {
131
+ const words = { ...FILE_MESSAGES, ...messages };
132
+ const extension = extensionOf(name);
133
+ // What is saved is plain bytes, so opening its address shows nothing, it only downloads.
134
+ const saved = useMemo(() => new Blob([blob], { type: "application/octet-stream" }), [blob]);
135
+ const save = useObjectUrl(saved);
136
+ const pages = preview?.kind === "pdf" ? preview.pages : null;
137
+
138
+ return (
139
+ <div className={`sc ${classes(classNames, "sc-file")}`}>
140
+ <div className={classes(classNames, "sc-file__bar")}>
141
+ <FileMark name={name} size={24} />
142
+ <span className={classes(classNames, "sc-file__meta")}>
143
+ <span>{extension === "" ? words.file : extension.toUpperCase()}</span>
144
+ <span>{words.size(blob.size)}</span>
145
+ {pages !== null && <span>{words.pages(pages)}</span>}
146
+ </span>
147
+ {save !== null && (
148
+ <Button size="sm" icon={DownloadSimpleIcon} href={save} download={baseName(name)}>
149
+ {words.download}
150
+ </Button>
151
+ )}
152
+ </div>
153
+ <div className={classes(classNames, "sc-file__body")}>
154
+ {preview === undefined ? (
155
+ <Read blob={blob} name={name} words={words} classNames={classNames} />
156
+ ) : (
157
+ <Previewed
158
+ preview={preview}
159
+ blob={blob}
160
+ name={name}
161
+ words={words}
162
+ classNames={classNames}
163
+ />
164
+ )}
165
+ </div>
166
+ </div>
167
+ );
168
+ }
169
+
170
+ interface Drawn {
171
+ name: string;
172
+ words: FileMessages;
173
+ classNames: ClassNames;
174
+ }
175
+
176
+ /** Under a file shown only in part: the words that say so. */
177
+ function Cut({
178
+ shown,
179
+ words,
180
+ classNames,
181
+ }: { shown: boolean; words: FileMessages } & Pick<Drawn, "classNames">) {
182
+ return shown ? <p className={classes(classNames, "sc-file__note")}>{words.truncated}</p> : null;
183
+ }
184
+
185
+ /** The file as the API made it to draw, by its kind. */
186
+ function Previewed({
187
+ preview,
188
+ blob,
189
+ name,
190
+ words,
191
+ classNames,
192
+ }: Drawn & { preview: FilePreview; blob: Blob }) {
193
+ switch (preview.kind) {
194
+ case "pdf":
195
+ return <Pdf blob={blob} name={name} classNames={classNames} />;
196
+ case "image":
197
+ return preview.media_type.includes("svg") ? (
198
+ <Svg blob={blob} name={name} classNames={classNames} />
199
+ ) : (
200
+ <Media
201
+ blob={blob}
202
+ type={preview.media_type}
203
+ name={name}
204
+ classNames={classNames}
205
+ kind="image"
206
+ />
207
+ );
208
+ case "video":
209
+ case "audio":
210
+ return (
211
+ <Media
212
+ blob={blob}
213
+ type={preview.media_type}
214
+ name={name}
215
+ classNames={classNames}
216
+ kind={preview.kind}
217
+ />
218
+ );
219
+ case "sheet":
220
+ return (
221
+ <Sheets
222
+ sheets={preview.sheets}
223
+ truncated={preview.truncated}
224
+ words={words}
225
+ classNames={classNames}
226
+ />
227
+ );
228
+ case "document":
229
+ return (
230
+ <Document
231
+ html={preview.html}
232
+ truncated={preview.truncated}
233
+ words={words}
234
+ classNames={classNames}
235
+ />
236
+ );
237
+ case "slides":
238
+ return (
239
+ <Slides
240
+ slides={preview.slides}
241
+ truncated={preview.truncated}
242
+ words={words}
243
+ classNames={classNames}
244
+ />
245
+ );
246
+ case "markdown":
247
+ case "text":
248
+ return (
249
+ <Words
250
+ text={preview.text}
251
+ markdown={preview.kind === "markdown"}
252
+ truncated={preview.truncated}
253
+ words={words}
254
+ classNames={classNames}
255
+ />
256
+ );
257
+ case "code":
258
+ case "json":
259
+ return (
260
+ <Source
261
+ text={preview.kind === "json" && !preview.truncated ? pretty(preview.text) : preview.text}
262
+ truncated={preview.truncated}
263
+ words={words}
264
+ classNames={classNames}
265
+ />
266
+ );
267
+ case "unknown":
268
+ return <None name={name} words={words} classNames={classNames} />;
269
+ }
270
+ }
271
+
272
+ /** The file as the browser reads its bytes alone, by its name and type. */
273
+ function Read({ blob, name, words, classNames }: Drawn & { blob: Blob }) {
274
+ const preview: Preview = previewOf(name, blob.type);
275
+ const svg = extensionOf(name) === "svg";
276
+ const reads = preview === "markdown" || preview === "text" || preview === "code";
277
+ const text = useText(blob, reads || preview === "table", TEXT_LIMIT);
278
+ const cut = blob.size > TEXT_LIMIT;
279
+
280
+ if (preview === "image") {
281
+ return svg ? (
282
+ <Svg blob={blob} name={name} classNames={classNames} />
283
+ ) : (
284
+ <Media blob={typedFor(blob, name)} name={name} classNames={classNames} kind="image" />
285
+ );
286
+ }
287
+ if (preview === "pdf") return <Pdf blob={blob} name={name} classNames={classNames} />;
288
+ if (preview === "none") return <None name={name} words={words} classNames={classNames} />;
289
+ if (text === null) return null;
290
+
291
+ const rows = preview === "table" ? tableOf(text) : null;
292
+ if (rows !== null) {
293
+ const [columns = [], ...body] = rows;
294
+ return (
295
+ <Sheets
296
+ sheets={[{ name: baseName(name), columns, rows: body, total_rows: body.length }]}
297
+ truncated={cut}
298
+ words={words}
299
+ classNames={classNames}
300
+ />
301
+ );
302
+ }
303
+ if (preview === "markdown" || preview === "text") {
304
+ return (
305
+ <Words
306
+ text={text}
307
+ markdown={preview === "markdown"}
308
+ truncated={cut}
309
+ words={words}
310
+ classNames={classNames}
311
+ />
312
+ );
313
+ }
314
+ // A source, or a CSV not simple enough for a table: as written, in the mono face.
315
+ return (
316
+ <Source
317
+ text={extensionOf(name) === "json" && !cut ? pretty(text) : text}
318
+ truncated={cut}
319
+ words={words}
320
+ classNames={classNames}
321
+ />
322
+ );
323
+ }
324
+
325
+ /** A PDF in the browser's own viewer. */
326
+ function Pdf({ blob, name, classNames }: { blob: Blob; name: string; classNames: ClassNames }) {
327
+ const typed = useMemo(() => typedFor(blob, name), [blob, name]);
328
+ const view = useObjectUrl(typed);
329
+ return (
330
+ view !== null && (
331
+ <iframe src={view} title={baseName(name)} className={classes(classNames, "sc-file__frame")} />
332
+ )
333
+ );
334
+ }
335
+
336
+ /**
337
+ * An SVG, from its words as a data address: one of the page's own (a blob's) would run its
338
+ * scripts as the page if it were opened apart.
339
+ */
340
+ function Svg({ blob, name, classNames }: { blob: Blob; name: string; classNames: ClassNames }) {
341
+ const text = useText(blob, true, Infinity);
342
+ return (
343
+ text !== null && (
344
+ <div className={classes(classNames, "sc-file__image")}>
345
+ <img
346
+ src={`data:image/svg+xml;charset=utf-8,${encodeURIComponent(text)}`}
347
+ alt={baseName(name)}
348
+ />
349
+ </div>
350
+ )
351
+ );
352
+ }
353
+
354
+ /** A picture whole, a video or a sound in the browser's own player, from its bytes typed. */
355
+ function Media({
356
+ blob,
357
+ type,
358
+ name,
359
+ kind,
360
+ classNames,
361
+ }: {
362
+ blob: Blob;
363
+ /** The type it plays as; none: the one the bytes came with. */
364
+ type?: string | undefined;
365
+ name: string;
366
+ kind: "image" | "video" | "audio";
367
+ classNames: ClassNames;
368
+ }) {
369
+ const typed = useMemo(
370
+ () => (type === undefined || blob.type === type ? blob : new Blob([blob], { type })),
371
+ [blob, type],
372
+ );
373
+ const src = useObjectUrl(typed);
374
+ if (src === null) return null;
375
+ if (kind === "image") {
376
+ return (
377
+ <div className={classes(classNames, "sc-file__image")}>
378
+ <img src={src} alt={baseName(name)} />
379
+ </div>
380
+ );
381
+ }
382
+ return (
383
+ <div className={classes(classNames, "sc-file__media")} data-kind={kind}>
384
+ {kind === "video" ? (
385
+ <video src={src} controls playsInline preload="metadata" aria-label={baseName(name)} />
386
+ ) : (
387
+ <>
388
+ <FileMark name={name} size={44} />
389
+ <AudioPlayer src={src} label={baseName(name)} />
390
+ </>
391
+ )}
392
+ </div>
393
+ );
394
+ }
395
+
396
+ /**
397
+ * A spreadsheet: one sheet at a time as a grid, its columns over it kept in view as it scrolls;
398
+ * its sheets as tabs at its foot, as a spreadsheet has them. Under a
399
+ * sheet shown in part, how many of its rows are.
400
+ */
401
+ function Sheets({
402
+ sheets,
403
+ truncated,
404
+ words,
405
+ classNames,
406
+ }: {
407
+ sheets: readonly PreviewSheet[];
408
+ truncated: boolean;
409
+ } & Omit<Drawn, "name">) {
410
+ const [at, setAt] = useState(0);
411
+ const sheet = sheets[at] ?? sheets[0];
412
+ if (sheet === undefined) return <None name="" words={words} classNames={classNames} />;
413
+ const rows = sheet.rows.slice(0, ROW_LIMIT);
414
+ const width = Math.max(sheet.columns?.length ?? 0, ...rows.map((row) => row.length));
415
+ const several = sheets.length > 1;
416
+ return (
417
+ <div className={classes(classNames, "sc-file__sheet")}>
418
+ {/* Another sheet opens at its top-left corner. */}
419
+ <div
420
+ key={at}
421
+ role={several ? "tabpanel" : undefined}
422
+ className={classes(classNames, "sc-file__table")}
423
+ >
424
+ {sheet.columns === null ? (
425
+ <p className={classes(classNames, "sc-file__note")}>{words.emptySheet}</p>
426
+ ) : (
427
+ <table>
428
+ <thead>
429
+ <tr>
430
+ {pad(sheet.columns, width).map((cell, index) => (
431
+ <th key={index} scope="col">
432
+ {cell}
433
+ </th>
434
+ ))}
435
+ </tr>
436
+ </thead>
437
+ <tbody>
438
+ {rows.map((row, index) => (
439
+ <tr key={index}>
440
+ {pad(row, width).map((cell, column) => (
441
+ <td key={column} title={cell.length > 36 ? cell : undefined}>
442
+ {cell}
443
+ </td>
444
+ ))}
445
+ </tr>
446
+ ))}
447
+ </tbody>
448
+ </table>
449
+ )}
450
+ {sheet.total_rows > rows.length ? (
451
+ <p className={classes(classNames, "sc-file__note")}>
452
+ {words.rows(rows.length, sheet.total_rows)}
453
+ </p>
454
+ ) : (
455
+ <Cut shown={truncated} words={words} classNames={classNames} />
456
+ )}
457
+ </div>
458
+ {several && (
459
+ <div
460
+ role="tablist"
461
+ aria-label={words.sheets}
462
+ className={classes(classNames, "sc-file__tabs")}
463
+ >
464
+ {sheets.map((each, index) => (
465
+ <button
466
+ key={index}
467
+ type="button"
468
+ role="tab"
469
+ aria-selected={index === at}
470
+ onClick={() => {
471
+ setAt(index);
472
+ }}
473
+ className={classes(classNames, "sc-file__tab")}
474
+ >
475
+ {each.name}
476
+ </button>
477
+ ))}
478
+ </div>
479
+ )}
480
+ </div>
481
+ );
482
+ }
483
+
484
+ /** A row as wide as the widest, its missing cells empty. */
485
+ const pad = (cells: readonly string[], width: number): string[] =>
486
+ cells.length >= width ? [...cells] : [...cells, ...Array<string>(width - cells.length).fill("")];
487
+
488
+ /**
489
+ * A Word file as its HTML at a reading measure: headings, paragraphs, lists, tables, pictures,
490
+ * kept to what a viewer draws (`cleanDocument`), again here after the API.
491
+ */
492
+ function Document({
493
+ html,
494
+ truncated,
495
+ words,
496
+ classNames,
497
+ }: { html: string; truncated: boolean } & Omit<Drawn, "name">) {
498
+ const clean = useMemo(() => cleanDocument(html), [html]);
499
+ return (
500
+ <div className={classes(classNames, "sc-file__text")}>
501
+ <div
502
+ className={classes(classNames, "sc-file__document")}
503
+ // Kept to the API's allow-list, by the API and again by `cleanDocument`.
504
+ dangerouslySetInnerHTML={{ __html: clean }}
505
+ />
506
+ <Cut shown={truncated} words={words} classNames={classNames} />
507
+ </div>
508
+ );
509
+ }
510
+
511
+ /** A deck: its slides one under another, each a card with its number, its words, its notes. */
512
+ function Slides({
513
+ slides,
514
+ truncated,
515
+ words,
516
+ classNames,
517
+ }: { slides: readonly PreviewSlide[]; truncated: boolean } & Omit<Drawn, "name">) {
518
+ return (
519
+ <>
520
+ <ol className={classes(classNames, "sc-file__slides")}>
521
+ {slides.map((slide, index) => (
522
+ <li key={index} className={classes(classNames, "sc-file__slide")}>
523
+ <span>{words.slide(index + 1)}</span>
524
+ {slide.title !== null && slide.title !== "" && <h3>{slide.title}</h3>}
525
+ {slide.text !== "" && <p>{slide.text}</p>}
526
+ {slide.notes !== null && slide.notes !== "" && (
527
+ <div className={classes(classNames, "sc-file__notes")}>
528
+ <span>{words.notes}</span>
529
+ <p>{slide.notes}</p>
530
+ </div>
531
+ )}
532
+ </li>
533
+ ))}
534
+ </ol>
535
+ <Cut shown={truncated} words={words} classNames={classNames} />
536
+ </>
537
+ );
538
+ }
539
+
540
+ /** Words at a reading measure: Markdown drawn, plain words as written. */
541
+ function Words({
542
+ text,
543
+ markdown,
544
+ truncated,
545
+ words,
546
+ classNames,
547
+ }: { text: string; markdown: boolean; truncated: boolean } & Omit<Drawn, "name">) {
548
+ return (
549
+ <div className={classes(classNames, "sc-file__text")}>
550
+ {markdown ? (
551
+ <Markdown text={text} />
552
+ ) : (
553
+ <p className={classes(classNames, "sc-file__plain")}>{text}</p>
554
+ )}
555
+ <Cut shown={truncated} words={words} classNames={classNames} />
556
+ </div>
557
+ );
558
+ }
559
+
560
+ /** A source as written, in the mono face, its long lines wrapped; never run. */
561
+ function Source({
562
+ text,
563
+ truncated,
564
+ words,
565
+ classNames,
566
+ }: { text: string; truncated: boolean } & Omit<Drawn, "name">) {
567
+ return (
568
+ <>
569
+ <pre className={classes(classNames, "sc-file__code")}>
570
+ <code>{text}</code>
571
+ </pre>
572
+ <Cut shown={truncated} words={words} classNames={classNames} />
573
+ </>
574
+ );
575
+ }
576
+
577
+ /** A kind that can't be shown: its mark, the line that says so, and what to do instead. */
578
+ function None({ name, words, classNames }: Drawn): ReactNode {
579
+ return (
580
+ <div className={classes(classNames, "sc-file__none")}>
581
+ <FileMark name={name} size={44} />
582
+ <p>
583
+ <strong>{words.noPreview}</strong>
584
+ <span>{words.noPreviewHint}</span>
585
+ </p>
586
+ </div>
587
+ );
588
+ }
589
+
590
+ /** The first `limit` bytes of a blob as words, once read; null while reading, or when not wanted. */
591
+ function useText(blob: Blob, wanted: boolean, limit: number): string | null {
592
+ const [text, setText] = useState<string | null>(null);
593
+ useEffect(() => {
594
+ if (!wanted) return;
595
+ let live = true;
596
+ void (blob.size > limit ? blob.slice(0, limit) : blob).text().then((read) => {
597
+ if (live) setText(read);
598
+ });
599
+ return () => {
600
+ live = false;
601
+ setText(null);
602
+ };
603
+ }, [blob, wanted, limit]);
604
+ return text;
605
+ }
606
+
607
+ /** An address for a blob while it is shown, let go when it changes or goes. */
608
+ function useObjectUrl(blob: Blob | null): string | null {
609
+ const [url, setUrl] = useState<string | null>(null);
610
+ useEffect(() => {
611
+ if (blob === null) return;
612
+ const made = URL.createObjectURL(blob);
613
+ setUrl(made);
614
+ return () => {
615
+ URL.revokeObjectURL(made);
616
+ setUrl(null);
617
+ };
618
+ }, [blob]);
619
+ return url;
620
+ }