@signalcore/ui 0.1.0 → 1.0.0-beta.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 (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 +1119 -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 +534 -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 +1795 -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 +270 -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 +6961 -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 +596 -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,150 @@
1
+ /**
2
+ * Days and times as the kit's controls hold them, "YYYY-MM-DD", "HH:MM" and
3
+ * "YYYY-MM-DDTHH:MM", as pure functions: reading them, writing them in a language, and which
4
+ * of them a control offers.
5
+ */
6
+
7
+ /** What bounds a day: the only days to pick, and the first and last. */
8
+ export interface DayBounds {
9
+ dates?: string[] | undefined;
10
+ earliest?: string | undefined;
11
+ latest?: string | undefined;
12
+ }
13
+
14
+ export const DAY = /^\d{4}-\d{2}-\d{2}$/;
15
+ export const TIME = /^([01]\d|2[0-3]):[0-5]\d$/;
16
+ export const MOMENT = /^\d{4}-\d{2}-\d{2}T([01]\d|2[0-3]):[0-5]\d$/;
17
+
18
+ /** A day "YYYY-MM-DD" as a local date, or null. */
19
+ export function dayOf(iso: string): Date | null {
20
+ if (!DAY.test(iso)) return null;
21
+ const [year = 0, month = 1, day = 1] = iso.split("-").map(Number);
22
+ const date = new Date(year, month - 1, day);
23
+ return date.getMonth() === month - 1 ? date : null;
24
+ }
25
+
26
+ /** A local date as "YYYY-MM-DD". */
27
+ export function isoDay(date: Date): string {
28
+ const pad = (n: number) => String(n).padStart(2, "0");
29
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
30
+ }
31
+
32
+ /** A day in words: its weekday, day and month, and its year when not this one. */
33
+ export function formatDay(iso: string, code: string, today: Date = new Date()): string {
34
+ const day = dayOf(iso);
35
+ if (!day) return iso;
36
+ return new Intl.DateTimeFormat(code, {
37
+ weekday: "long",
38
+ day: "numeric",
39
+ month: "long",
40
+ ...(day.getFullYear() !== today.getFullYear() && { year: "numeric" }),
41
+ }).format(day);
42
+ }
43
+
44
+ /** A time "HH:MM" as the language writes it: "10:30", or "10:30 AM". */
45
+ export function formatTime(time: string, code: string): string {
46
+ const [hours = 0, minutes = 0] = time.split(":").map(Number);
47
+ const at = new Date(2000, 0, 1, hours, minutes);
48
+ const clock = new Intl.DateTimeFormat(code, { hour: "numeric", minute: "2-digit" });
49
+ // The day's end, as a 24-hour clock writes it ("24:00"), not as the next day's start.
50
+ if (hours === 24 && clock.resolvedOptions().hourCycle === "h23") {
51
+ return new Intl.DateTimeFormat(code, {
52
+ hour: "numeric",
53
+ minute: "2-digit",
54
+ hourCycle: "h24",
55
+ }).format(at);
56
+ }
57
+ return clock.format(at);
58
+ }
59
+
60
+ /** A moment in words; a half-picked one reads as the half there is. */
61
+ export function formatMoment(moment: string, code: string, today: Date = new Date()): string {
62
+ const [date, time] = momentParts(moment);
63
+ if (!date || !TIME.test(time)) return date ? formatDay(date, code, today) : time;
64
+ const day = dayOf(date);
65
+ if (!day) return moment;
66
+ const [hours = 0, minutes = 0] = time.split(":").map(Number);
67
+ day.setHours(hours, minutes);
68
+ return new Intl.DateTimeFormat(code, {
69
+ weekday: "long",
70
+ day: "numeric",
71
+ month: "long",
72
+ ...(day.getFullYear() !== today.getFullYear() && { year: "numeric" }),
73
+ hour: "numeric",
74
+ minute: "2-digit",
75
+ }).format(day);
76
+ }
77
+
78
+ /** Whether a day is offered: one of the `dates` when there are, within the bounds. */
79
+ export function dayAllowed(bounds: DayBounds, iso: string): boolean {
80
+ if (!DAY.test(iso)) return false;
81
+ if (bounds.dates && !bounds.dates.includes(iso)) return false;
82
+ if (bounds.earliest !== undefined && iso < bounds.earliest) return false;
83
+ if (bounds.latest !== undefined && iso > bounds.latest) return false;
84
+ return true;
85
+ }
86
+
87
+ /** Whether a time is offered: one of the `times` when there are. */
88
+ export function slotAllowed(times: string[] | undefined, time: string): boolean {
89
+ return times === undefined || times.includes(time);
90
+ }
91
+
92
+ /** The day a calendar opens on: the one picked, else the first offered, else today. */
93
+ export function openingDay(bounds: DayBounds, picked: string | null, today: Date): string {
94
+ if (picked && DAY.test(picked)) return picked;
95
+ const first = bounds.dates?.toSorted()[0] ?? bounds.earliest;
96
+ const now = isoDay(today);
97
+ if (first !== undefined && (bounds.dates || first > now)) return first;
98
+ return bounds.latest !== undefined && bounds.latest < now ? bounds.latest : now;
99
+ }
100
+
101
+ /** The first and last days a calendar can go to, when they are bounded. */
102
+ export function daySpan(bounds: DayBounds): { first?: string; last?: string } {
103
+ const sorted = bounds.dates?.toSorted();
104
+ const first = sorted?.[0] ?? bounds.earliest;
105
+ const last = sorted?.at(-1) ?? bounds.latest;
106
+ return { ...(first !== undefined && { first }), ...(last !== undefined && { last }) };
107
+ }
108
+
109
+ /** A moment's day and time, either "" while not picked: "2026-10-14T" is a day alone. */
110
+ export function momentParts(moment: string | null): [date: string, time: string] {
111
+ if (!moment) return ["", ""];
112
+ const at = moment.indexOf("T");
113
+ return at < 0 ? [moment, ""] : [moment.slice(0, at), moment.slice(at + 1, at + 6)];
114
+ }
115
+
116
+ /** A moment from its parts, held while half picked; null when neither is. */
117
+ export function momentOf(date: string, time: string): string | null {
118
+ return date === "" && time === "" ? null : `${date}T${time}`;
119
+ }
120
+
121
+ /** Every half hour of a day, "00:00" to "23:30": what a time offers without its own slots. */
122
+ export function halfHours(): string[] {
123
+ return Array.from({ length: 48 }, (_, index) => {
124
+ const hours = String(Math.floor(index / 2)).padStart(2, "0");
125
+ return `${hours}:${index % 2 === 0 ? "00" : "30"}`;
126
+ });
127
+ }
128
+
129
+ /** The day's end, where a stretch of it can end: midnight at its close. */
130
+ export const DAY_END = "24:00";
131
+
132
+ /** A time a stretch of the day ends at, as typed: any time, or the day's end ("24", "24:00"). */
133
+ export function parseEndTime(typed: string): string | null {
134
+ return /^24(?:[:.h]?00)?$/i.test(typed.trim()) ? DAY_END : parseTime(typed);
135
+ }
136
+
137
+ /** A time as a person types it, as "HH:MM", or null: "9", "930", "9:30", "21.30", "9:30 pm". */
138
+ export function parseTime(typed: string): string | null {
139
+ const match = /^(\d{1,2})(?:[:.h]?(\d{2}))?\s*([ap])?\.?\s*m?\.?$/i.exec(typed.trim());
140
+ if (!match) return null;
141
+ let hours = Number(match[1]);
142
+ const minutes = Number(match[2] ?? "0");
143
+ const half = match[3]?.toLowerCase();
144
+ if (half) {
145
+ if (hours < 1 || hours > 12) return null;
146
+ hours = (hours % 12) + (half === "p" ? 12 : 0);
147
+ }
148
+ if (hours > 23 || minutes > 59) return null;
149
+ return `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
150
+ }
@@ -0,0 +1,160 @@
1
+ import type { DayPickerLocale } from "react-day-picker";
2
+
3
+ import { AUTOMATION_MESSAGES, type AutomationMessages } from "../automation/messages";
4
+
5
+ /**
6
+ * The language the kit's dates are read in: a locale from `@signalcore/ui/locale` (the
7
+ * calendar's, with its words), whose `code` also formats days, times, numbers and lists.
8
+ */
9
+ export type KitLocale = DayPickerLocale;
10
+
11
+ /** The words the kit's controls say; a host gives its own, in its language. */
12
+ export interface KitMessages {
13
+ /** A field left empty that must be filled. */
14
+ required: string;
15
+ /** A day, a time, both, an option, a rating still to pick; also an empty picker's invitation. */
16
+ chooseDate: string;
17
+ chooseTime: string;
18
+ chooseMoment: string;
19
+ chooseOption: string;
20
+ chooseRating: string;
21
+ /** A box that must be ticked to go on. */
22
+ check: string;
23
+ invalidEmail: string;
24
+ invalidPhone: string;
25
+ invalidUrl: string;
26
+ invalidNumber: string;
27
+ /** A time typed in a shape that is not one. */
28
+ invalidTime: string;
29
+ /** A number under its least, or over its most, given formatted. */
30
+ atLeast: (min: string) => string;
31
+ atMost: (max: string) => string;
32
+ /** A day or a time that is not offered. */
33
+ unavailableDate: string;
34
+ unavailableTime: string;
35
+ /** Beside the label of a field that may stay empty. */
36
+ optional: string;
37
+ /** In a long list's box while nothing is picked. */
38
+ pick: string;
39
+ /** In that box while the person types. */
40
+ search: string;
41
+ noResults: string;
42
+ /** The button that shows or hides a secret as it is typed. */
43
+ show: string;
44
+ hide: string;
45
+ /** A number's steppers, for screen readers. */
46
+ increase: string;
47
+ decrease: string;
48
+ /** A picked tag's remove button, for screen readers. */
49
+ remove: (label: string) => string;
50
+ /** A box ticked or not, as an answer reads. */
51
+ yes: string;
52
+ no: string;
53
+ /** A rating, as an answer reads. */
54
+ rated: (value: number, max: number) => string;
55
+ /** One star of a rating, for screen readers. */
56
+ stars: (count: number) => string;
57
+ /** A choice's last row, to answer in one's own words, and its box while empty. */
58
+ other: string;
59
+ otherPlaceholder: string;
60
+ /** A form's submit when the agent gave it no words. */
61
+ send: string;
62
+ /** Where a form's submit was, once it is sent. */
63
+ sent: string;
64
+ /** A file field left empty that must be filled. */
65
+ chooseFile: string;
66
+ /** A file field's drop zone: what it asks, and how. */
67
+ upload: (multiple: boolean) => string;
68
+ drop: string;
69
+ /**
70
+ * Under them, what it takes: the kinds (named and joined, "" when anything) and the most a
71
+ * file may weigh, formatted.
72
+ */
73
+ limits: (kinds: string, size: string) => string;
74
+ /** A family of kinds as the limits name it: "image" for any image, "video", "audio", "text". */
75
+ anyOf: (family: string) => string;
76
+ /** A file on its way, beside how much has gone. */
77
+ uploading: string;
78
+ /** A file that was not sent: heavier than the most (formatted), a kind not taken, one too many. */
79
+ tooBig: (size: string) => string;
80
+ wrongType: string;
81
+ tooMany: (max: number) => string;
82
+ /** A file whose upload failed, and the button that tries it again. */
83
+ uploadFailed: string;
84
+ retry: string;
85
+ /** A form sent while a file is still on its way, or one failed. */
86
+ stillUploading: string;
87
+ fixFiles: string;
88
+ /** A file's chip, opened on a click, for screen readers. */
89
+ open: (name: string) => string;
90
+ /** A file whose name is not known yet. */
91
+ file: string;
92
+ /** An audio player's button, and its way through, for screen readers. */
93
+ play: string;
94
+ pause: string;
95
+ position: string;
96
+ /** An automation and its runs: when it runs, how it stands, what each run did. */
97
+ automation: AutomationMessages;
98
+ }
99
+
100
+ const FAMILIES: Readonly<Record<string, string>> = {
101
+ image: "images",
102
+ video: "videos",
103
+ audio: "audio",
104
+ text: "text",
105
+ };
106
+
107
+ export const KIT_MESSAGES: KitMessages = {
108
+ required: "This field is required",
109
+ chooseDate: "Choose a day",
110
+ chooseTime: "Choose a time",
111
+ chooseMoment: "Choose a day and a time",
112
+ chooseOption: "Choose an option",
113
+ other: "Another answer",
114
+ otherPlaceholder: "Write your answer",
115
+ chooseRating: "Choose a rating",
116
+ check: "Tick the box to go on",
117
+ invalidEmail: "Enter a valid email",
118
+ invalidPhone: "Enter a valid phone number",
119
+ invalidUrl: "Enter a valid address",
120
+ invalidNumber: "Enter a number",
121
+ invalidTime: "Write a time like 9:30",
122
+ atLeast: (min) => `At least ${min}`,
123
+ atMost: (max) => `At most ${max}`,
124
+ unavailableDate: "That day is not available",
125
+ unavailableTime: "That time is not available",
126
+ optional: "Optional",
127
+ pick: "Choose…",
128
+ search: "Search…",
129
+ noResults: "No results",
130
+ show: "Show",
131
+ hide: "Hide",
132
+ increase: "Increase",
133
+ decrease: "Decrease",
134
+ remove: (label) => `Remove ${label}`,
135
+ yes: "Yes",
136
+ no: "No",
137
+ rated: (value, max) => `${value} of ${max}`,
138
+ stars: (count) => (count === 1 ? "1 star" : `${count} stars`),
139
+ send: "Send",
140
+ sent: "Sent",
141
+ chooseFile: "Add a file",
142
+ upload: (multiple) => (multiple ? "Upload files" : "Upload a file"),
143
+ drop: "Drop it here or choose",
144
+ limits: (kinds, size) => (kinds ? `${kinds}, up to ${size}` : `Up to ${size}`),
145
+ anyOf: (family) => FAMILIES[family] ?? family,
146
+ uploading: "Uploading",
147
+ tooBig: (size) => `Over ${size}`,
148
+ wrongType: "This kind of file isn't taken here",
149
+ tooMany: (max) => `At most ${max} files`,
150
+ uploadFailed: "Couldn't upload it",
151
+ retry: "Retry",
152
+ stillUploading: "Wait for the upload to finish",
153
+ fixFiles: "Remove or retry the files that failed",
154
+ open: (name) => `Open ${name}`,
155
+ file: "File",
156
+ play: "Play",
157
+ pause: "Pause",
158
+ position: "Position",
159
+ automation: AUTOMATION_MESSAGES,
160
+ };
@@ -0,0 +1,44 @@
1
+ /** Numbers as the kit's controls hold and write them, as pure functions. */
2
+
3
+ /** What bounds a number: its least, its most, the step between values. */
4
+ export interface NumberBounds {
5
+ min?: number | undefined;
6
+ max?: number | undefined;
7
+ step?: number | undefined;
8
+ }
9
+
10
+ export function formatNumber(value: number, code: string): string {
11
+ return new Intl.NumberFormat(code, { maximumFractionDigits: 6 }).format(value);
12
+ }
13
+
14
+ /** A number with its unit after it: "3 personas", "25 €". */
15
+ export function withUnit(text: string, unit: string | undefined): string {
16
+ return unit ? `${text} ${unit}` : text;
17
+ }
18
+
19
+ /**
20
+ * A number one step up or down (`direction` 1 or -1), kept within its bounds and on its step's
21
+ * decimals; from nothing, it starts at its least, or 0.
22
+ */
23
+ export function stepped(bounds: NumberBounds, value: number | null, direction: 1 | -1): number {
24
+ const step = bounds.step ?? 1;
25
+ const next = value === null ? (bounds.min ?? 0) : value + direction * step;
26
+ const decimals = (String(step).split(".")[1] ?? "").length;
27
+ const rounded = Number(next.toFixed(decimals));
28
+ return Math.min(bounds.max ?? Infinity, Math.max(bounds.min ?? -Infinity, rounded));
29
+ }
30
+
31
+ const UNITS = ["B", "KB", "MB", "GB"] as const;
32
+
33
+ /** A file's size as people read it: whole bytes, one decimal under ten of a larger unit. */
34
+ export function formatSize(bytes: number, locale?: string): string {
35
+ let size = Math.max(0, bytes);
36
+ let unit = 0;
37
+ while (size >= 1024 && unit < UNITS.length - 1) {
38
+ size /= 1024;
39
+ unit += 1;
40
+ }
41
+ const digits = unit === 0 || size >= 10 ? 0 : 1;
42
+ const number = new Intl.NumberFormat(locale, { maximumFractionDigits: digits }).format(size);
43
+ return `${number} ${UNITS[unit]}`;
44
+ }
@@ -0,0 +1,30 @@
1
+ /** The options a control offers, as pure functions: finding one, ticking one on and off. */
2
+
3
+ /** One thing to pick: its id (what comes back), its label, and a quiet line under it. */
4
+ export interface Option {
5
+ id: string;
6
+ label: string;
7
+ hint?: string | undefined;
8
+ }
9
+
10
+ /** Whether an option is what the person is looking for: in its label, hint or id, any case or accent. */
11
+ export function matches(option: Option, query: string): boolean {
12
+ const wanted = fold(query.trim());
13
+ if (wanted === "") return true;
14
+ return [option.label, option.hint ?? "", option.id].some((text) => fold(text).includes(wanted));
15
+ }
16
+
17
+ function fold(text: string): string {
18
+ return text
19
+ .normalize("NFD")
20
+ .replace(/\p{Diacritic}/gu, "")
21
+ .toLowerCase();
22
+ }
23
+
24
+ /** The ids picked once the person ticks one on or off, in the options' order. */
25
+ export function toggled(options: Option[], picked: readonly string[], id: string): string[] {
26
+ const on = !picked.includes(id);
27
+ return options
28
+ .filter((option) => (option.id === id ? on : picked.includes(option.id)))
29
+ .map((option) => option.id);
30
+ }
@@ -0,0 +1,244 @@
1
+ /**
2
+ * Files a person picks, as pure functions: whether a field takes one (its kind, its weight), how
3
+ * a field's kinds and limits read, what family a file is of (for its glyph), and the words for
4
+ * what went wrong. Nothing here touches the page or the network.
5
+ */
6
+ import type { Attachment } from "../types";
7
+ import type { KitMessages } from "./messages";
8
+ import { formatSize } from "./numbers";
9
+
10
+ /** The most a file may weigh anywhere, in MB: the API's ceiling. */
11
+ export const MAX_MB = 50;
12
+ const MB = 1024 * 1024;
13
+
14
+ /**
15
+ * Sends one file where it belongs, telling how much of it has gone (0 to 1) as it goes; aborting
16
+ * `signal` lets it go. Resolves to the file as stored.
17
+ */
18
+ export type Uploader = (
19
+ file: File,
20
+ progress: (share: number) => void,
21
+ signal: AbortSignal,
22
+ ) => Promise<Attachment>;
23
+
24
+ /** Where a field's files go and how the ones already sent are found: the conversation's. */
25
+ export interface FileHost {
26
+ upload: Uploader;
27
+ /** The files known by id: said in the conversation, uploaded to it. */
28
+ known: ReadonlyMap<string, Attachment>;
29
+ /** Asks for files it does not know yet, by id: read back from the conversation. */
30
+ find?: ((ids: readonly string[]) => void) | undefined;
31
+ /** Opens one, when the host shows files. */
32
+ open?: ((file: Attachment) => void) | undefined;
33
+ /**
34
+ * Where a picture, a video or a sound plays from in the page's own player: an address the
35
+ * player streams with no credential, for a while.
36
+ */
37
+ play?: ((file: Attachment) => Promise<string>) | undefined;
38
+ }
39
+
40
+ /** A file as picked: its name, its type as the browser gave it ("" when none), its weight. */
41
+ export interface Picked {
42
+ name: string;
43
+ type: string;
44
+ size: number;
45
+ }
46
+
47
+ /** A name's extension, lowercase, without its dot; "" for one without (`README`, `.env`). */
48
+ export function extensionOf(name: string): string {
49
+ const dot = name.lastIndexOf(".");
50
+ return dot <= 0 ? "" : name.slice(dot + 1).toLowerCase();
51
+ }
52
+
53
+ /** The types a browser often leaves out, by extension. */
54
+ const TYPES: Readonly<Record<string, string>> = {
55
+ pdf: "application/pdf",
56
+ png: "image/png",
57
+ jpg: "image/jpeg",
58
+ jpeg: "image/jpeg",
59
+ gif: "image/gif",
60
+ webp: "image/webp",
61
+ heic: "image/heic",
62
+ heif: "image/heif",
63
+ csv: "text/csv",
64
+ txt: "text/plain",
65
+ md: "text/markdown",
66
+ json: "application/json",
67
+ doc: "application/msword",
68
+ docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
69
+ xls: "application/vnd.ms-excel",
70
+ xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
71
+ ppt: "application/vnd.ms-powerpoint",
72
+ pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
73
+ zip: "application/zip",
74
+ };
75
+
76
+ /** A file's type: the browser's, else the one its extension names, else "". */
77
+ export function typeOf(file: Pick<Picked, "name" | "type">): string {
78
+ return (file.type || TYPES[extensionOf(file.name)] || "").toLowerCase();
79
+ }
80
+
81
+ /**
82
+ * Whether a file is of a kind `accept` lists, read as an <input accept> reads it: a type
83
+ * ("application/pdf"), a family ("image/*") or an extension (".xlsx"); none takes anything.
84
+ */
85
+ export function accepts(
86
+ accept: readonly string[] | undefined,
87
+ file: Pick<Picked, "name" | "type">,
88
+ ): boolean {
89
+ if (accept === undefined || accept.length === 0) return true;
90
+ const type = typeOf(file);
91
+ const extension = extensionOf(file.name);
92
+ return accept.some((raw) => {
93
+ const rule = raw.trim().toLowerCase();
94
+ if (rule === "*" || rule === "*/*") return true;
95
+ if (rule.startsWith(".")) return extension !== "" && rule === `.${extension}`;
96
+ if (rule.endsWith("/*")) return type.startsWith(rule.slice(0, -1));
97
+ return type === rule;
98
+ });
99
+ }
100
+
101
+ /** The most a field takes per file, in MB: its own, within the ceiling. */
102
+ export function limitOf(maxMb: number | undefined): number {
103
+ return maxMb !== undefined && maxMb > 0 ? Math.min(maxMb, MAX_MB) : MAX_MB;
104
+ }
105
+
106
+ /** That most, as people read it: "10 MB". */
107
+ function limitWords(maxMb: number | undefined, code: string): string {
108
+ return formatSize(limitOf(maxMb) * MB, code);
109
+ }
110
+
111
+ /** What keeps a file from being sent, in words: a kind not taken, or past the most; else null. */
112
+ export function refusalOf(
113
+ file: Picked,
114
+ accept: readonly string[] | undefined,
115
+ maxMb: number | undefined,
116
+ code: string,
117
+ messages: KitMessages,
118
+ ): string | null {
119
+ if (!accepts(accept, file)) return messages.wrongType;
120
+ if (file.size > limitOf(maxMb) * MB) return messages.tooBig(limitWords(maxMb, code));
121
+ return null;
122
+ }
123
+
124
+ /**
125
+ * What a failed upload says: past what the server takes (413), a kind it refused (415), or that
126
+ * it failed, to be tried again.
127
+ */
128
+ export function failureOf(
129
+ error: unknown,
130
+ maxMb: number | undefined,
131
+ code: string,
132
+ messages: KitMessages,
133
+ ): string {
134
+ const status =
135
+ typeof error === "object" && error !== null && "status" in error ? error.status : undefined;
136
+ if (status === 413) return messages.tooBig(limitWords(maxMb, code));
137
+ if (status === 415) return messages.wrongType;
138
+ return messages.uploadFailed;
139
+ }
140
+
141
+ /** Whether an upload's failure is the person letting it go: nothing to show. */
142
+ export function isAbort(error: unknown): boolean {
143
+ return error instanceof DOMException && error.name === "AbortError";
144
+ }
145
+
146
+ /** Short names for the types people know by one. */
147
+ const SHORT: Readonly<Record<string, string>> = Object.fromEntries(
148
+ Object.entries(TYPES).map(([extension, type]) => [type, extension.toUpperCase()]),
149
+ );
150
+
151
+ /**
152
+ * The kinds a field takes as people name them, each once: a family ("image/*") by `anyOf`, a type
153
+ * by its short name ("PDF", "XLSX"), an extension by its letters; none when it takes anything.
154
+ */
155
+ export function kindsOf(accept: readonly string[] | undefined, messages: KitMessages): string[] {
156
+ const rules = (accept ?? []).map((rule) => rule.trim().toLowerCase());
157
+ if (rules.some((rule) => rule === "*" || rule === "*/*")) return [];
158
+ const names = rules.map((rule) => {
159
+ if (rule.startsWith(".")) return rule.slice(1).toUpperCase();
160
+ if (rule.endsWith("/*")) return messages.anyOf(rule.slice(0, -2));
161
+ return SHORT[rule] ?? (rule.split("/")[1] ?? rule).toUpperCase();
162
+ });
163
+ return [...new Set(names.filter((name) => name !== ""))];
164
+ }
165
+
166
+ /** The line under a drop zone: the kinds it takes, joined ("Images or PDF"), and its most. */
167
+ export function limitsOf(
168
+ accept: readonly string[] | undefined,
169
+ maxMb: number | undefined,
170
+ code: string,
171
+ messages: KitMessages,
172
+ ): string {
173
+ const kinds = kindsOf(accept, messages);
174
+ const joined =
175
+ kinds.length === 0 ? "" : new Intl.ListFormat(code, { type: "disjunction" }).format(kinds);
176
+ const line = messages.limits(joined, limitWords(maxMb, code));
177
+ return line.charAt(0).toLocaleUpperCase(code) + line.slice(1);
178
+ }
179
+
180
+ /** The families a file's glyph tells apart. */
181
+ export type FileFamily =
182
+ "image" | "pdf" | "sheet" | "doc" | "slides" | "text" | "archive" | "audio" | "video" | "other";
183
+
184
+ const FAMILIES: Readonly<Record<string, FileFamily>> = {
185
+ png: "image",
186
+ jpg: "image",
187
+ jpeg: "image",
188
+ gif: "image",
189
+ webp: "image",
190
+ avif: "image",
191
+ heic: "image",
192
+ heif: "image",
193
+ svg: "image",
194
+ bmp: "image",
195
+ pdf: "pdf",
196
+ csv: "sheet",
197
+ tsv: "sheet",
198
+ xls: "sheet",
199
+ xlsx: "sheet",
200
+ ods: "sheet",
201
+ numbers: "sheet",
202
+ doc: "doc",
203
+ docx: "doc",
204
+ odt: "doc",
205
+ rtf: "doc",
206
+ pages: "doc",
207
+ ppt: "slides",
208
+ pptx: "slides",
209
+ odp: "slides",
210
+ key: "slides",
211
+ txt: "text",
212
+ md: "text",
213
+ markdown: "text",
214
+ json: "text",
215
+ yaml: "text",
216
+ yml: "text",
217
+ xml: "text",
218
+ html: "text",
219
+ log: "text",
220
+ zip: "archive",
221
+ rar: "archive",
222
+ "7z": "archive",
223
+ tar: "archive",
224
+ gz: "archive",
225
+ mp3: "audio",
226
+ wav: "audio",
227
+ m4a: "audio",
228
+ ogg: "audio",
229
+ mp4: "video",
230
+ mov: "video",
231
+ webm: "video",
232
+ };
233
+
234
+ /** A file's family, by its name's extension first, then by its type. */
235
+ export function familyOf(name: string, type: string): FileFamily {
236
+ const known = FAMILIES[extensionOf(name)];
237
+ if (known) return known;
238
+ const media = type.toLowerCase();
239
+ if (media === "application/pdf") return "pdf";
240
+ const family = media.split("/")[0];
241
+ return family === "image" || family === "audio" || family === "video" || family === "text"
242
+ ? family
243
+ : "other";
244
+ }