@openrails/contentkit-ui 0.0.0-stage → 0.68.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 (367) hide show
  1. package/README.md +425 -2
  2. package/dist/appearance.d.ts +38 -0
  3. package/dist/appearance.js +15 -0
  4. package/dist/appearance.js.map +1 -0
  5. package/dist/assets/hash.worker-BYfo-7MQ.js.map +1 -0
  6. package/dist/client/aspect.d.ts +6 -0
  7. package/dist/client/aspect.js +17 -0
  8. package/dist/client/aspect.js.map +1 -0
  9. package/dist/client/client.d.ts +51 -0
  10. package/dist/client/client.js +35 -0
  11. package/dist/client/client.js.map +1 -0
  12. package/dist/client/codes.d.ts +12 -0
  13. package/dist/client/codes.js +19 -0
  14. package/dist/client/codes.js.map +1 -0
  15. package/dist/client/content/bans.d.ts +15 -0
  16. package/dist/client/content/bans.js +40 -0
  17. package/dist/client/content/bans.js.map +1 -0
  18. package/dist/client/content/comments.d.ts +36 -0
  19. package/dist/client/content/comments.js +93 -0
  20. package/dist/client/content/comments.js.map +1 -0
  21. package/dist/client/content/favorites.d.ts +14 -0
  22. package/dist/client/content/favorites.js +42 -0
  23. package/dist/client/content/favorites.js.map +1 -0
  24. package/dist/client/content/moderation.d.ts +18 -0
  25. package/dist/client/content/moderation.js +37 -0
  26. package/dist/client/content/moderation.js.map +1 -0
  27. package/dist/client/content/polls.d.ts +47 -0
  28. package/dist/client/content/polls.js +148 -0
  29. package/dist/client/content/polls.js.map +1 -0
  30. package/dist/client/content/posts.d.ts +44 -0
  31. package/dist/client/content/posts.js +91 -0
  32. package/dist/client/content/posts.js.map +1 -0
  33. package/dist/client/content/reactions.d.ts +12 -0
  34. package/dist/client/content/reactions.js +36 -0
  35. package/dist/client/content/reactions.js.map +1 -0
  36. package/dist/client/content/types.d.ts +91 -0
  37. package/dist/client/content/types.js +8 -0
  38. package/dist/client/content/types.js.map +1 -0
  39. package/dist/client/crop.d.ts +32 -0
  40. package/dist/client/crop.js +103 -0
  41. package/dist/client/crop.js.map +1 -0
  42. package/dist/client/errors.d.ts +54 -0
  43. package/dist/client/errors.js +80 -0
  44. package/dist/client/errors.js.map +1 -0
  45. package/dist/client/gallery.d.ts +43 -0
  46. package/dist/client/gallery.js +86 -0
  47. package/dist/client/gallery.js.map +1 -0
  48. package/dist/client/generated/error-codes.d.ts +5 -0
  49. package/dist/client/generated/error-codes.js +131 -0
  50. package/dist/client/generated/error-codes.js.map +1 -0
  51. package/dist/client/generated/routes.d.ts +1086 -0
  52. package/dist/client/generated/routes.js +1400 -0
  53. package/dist/client/generated/routes.js.map +1 -0
  54. package/dist/client/generated/wire.d.ts +630 -0
  55. package/dist/client/generated/wire.js +6 -0
  56. package/dist/client/generated/wire.js.map +1 -0
  57. package/dist/client/http.d.ts +79 -0
  58. package/dist/client/http.js +74 -0
  59. package/dist/client/http.js.map +1 -0
  60. package/dist/client/image.d.ts +24 -0
  61. package/dist/client/image.js +65 -0
  62. package/dist/client/image.js.map +1 -0
  63. package/dist/client/index.d.ts +33 -0
  64. package/dist/client/media/api.d.ts +36 -0
  65. package/dist/client/media/api.js +61 -0
  66. package/dist/client/media/api.js.map +1 -0
  67. package/dist/client/media/client.d.ts +247 -0
  68. package/dist/client/media/client.js +407 -0
  69. package/dist/client/media/client.js.map +1 -0
  70. package/dist/client/media/encode.d.ts +3 -0
  71. package/dist/client/media/encode.js +8 -0
  72. package/dist/client/media/encode.js.map +1 -0
  73. package/dist/client/media/hash-stream.d.ts +6 -0
  74. package/dist/client/media/hash-stream.js +16 -0
  75. package/dist/client/media/hash-stream.js.map +1 -0
  76. package/dist/client/media/hash.d.ts +12 -0
  77. package/dist/client/media/hash.js +48 -0
  78. package/dist/client/media/hash.js.map +1 -0
  79. package/dist/client/media/hash.worker-inline.js +18 -0
  80. package/dist/client/media/hash.worker-inline.js.map +1 -0
  81. package/dist/client/media/pacer.d.ts +21 -0
  82. package/dist/client/media/pacer.js +25 -0
  83. package/dist/client/media/pacer.js.map +1 -0
  84. package/dist/client/media/queue.d.ts +112 -0
  85. package/dist/client/media/queue.js +274 -0
  86. package/dist/client/media/queue.js.map +1 -0
  87. package/dist/client/media/ref.d.ts +6 -0
  88. package/dist/client/media/ref.js +10 -0
  89. package/dist/client/media/ref.js.map +1 -0
  90. package/dist/client/media/rules.d.ts +52 -0
  91. package/dist/client/media/rules.js +139 -0
  92. package/dist/client/media/rules.js.map +1 -0
  93. package/dist/client/media/transport.d.ts +13 -0
  94. package/dist/client/media/transport.js +33 -0
  95. package/dist/client/media/transport.js.map +1 -0
  96. package/dist/client/media/windows.d.ts +15 -0
  97. package/dist/client/media/windows.js +39 -0
  98. package/dist/client/media/windows.js.map +1 -0
  99. package/dist/client/playback.d.ts +200 -0
  100. package/dist/client/playback.js +142 -0
  101. package/dist/client/playback.js.map +1 -0
  102. package/dist/client/player.d.ts +102 -0
  103. package/dist/client/player.js +155 -0
  104. package/dist/client/player.js.map +1 -0
  105. package/dist/client/public.d.ts +25 -0
  106. package/dist/client/public.js +18 -0
  107. package/dist/client/public.js.map +1 -0
  108. package/dist/client/rendition.d.ts +19 -0
  109. package/dist/client/rendition.js +16 -0
  110. package/dist/client/rendition.js.map +1 -0
  111. package/dist/client/route.d.ts +39 -0
  112. package/dist/client/route.js +31 -0
  113. package/dist/client/route.js.map +1 -0
  114. package/dist/client/taxonomy.d.ts +30 -0
  115. package/dist/client/taxonomy.js +77 -0
  116. package/dist/client/taxonomy.js.map +1 -0
  117. package/dist/client.js +33 -0
  118. package/dist/components/encode-progress.d.ts +15 -0
  119. package/dist/components/encode-progress.js +49 -0
  120. package/dist/components/encode-progress.js.map +1 -0
  121. package/dist/components/hover-preview.d.ts +29 -0
  122. package/dist/components/hover-preview.js +49 -0
  123. package/dist/components/hover-preview.js.map +1 -0
  124. package/dist/components/image-crop-dialog.d.ts +48 -0
  125. package/dist/components/image-crop-dialog.js +359 -0
  126. package/dist/components/image-crop-dialog.js.map +1 -0
  127. package/dist/components/lazy-mount.d.ts +10 -0
  128. package/dist/components/lazy-mount.js +22 -0
  129. package/dist/components/lazy-mount.js.map +1 -0
  130. package/dist/components/media-folder-editor.d.ts +45 -0
  131. package/dist/components/media-folder-editor.js +564 -0
  132. package/dist/components/media-folder-editor.js.map +1 -0
  133. package/dist/components/media-gallery.d.ts +54 -0
  134. package/dist/components/media-gallery.js +597 -0
  135. package/dist/components/media-gallery.js.map +1 -0
  136. package/dist/components/media-readiness-notice.d.ts +24 -0
  137. package/dist/components/media-readiness-notice.js +61 -0
  138. package/dist/components/media-readiness-notice.js.map +1 -0
  139. package/dist/components/player-controls.d.ts +71 -0
  140. package/dist/components/player-controls.js +264 -0
  141. package/dist/components/player-controls.js.map +1 -0
  142. package/dist/components/progress.d.ts +5 -0
  143. package/dist/components/progress.js +14 -0
  144. package/dist/components/progress.js.map +1 -0
  145. package/dist/components/rendition-img.d.ts +34 -0
  146. package/dist/components/rendition-img.js +78 -0
  147. package/dist/components/rendition-img.js.map +1 -0
  148. package/dist/components/slot-editor.d.ts +95 -0
  149. package/dist/components/slot-editor.js +182 -0
  150. package/dist/components/slot-editor.js.map +1 -0
  151. package/dist/components/slot-image.d.ts +23 -0
  152. package/dist/components/slot-image.js +48 -0
  153. package/dist/components/slot-image.js.map +1 -0
  154. package/dist/components/slot-upload.d.ts +41 -0
  155. package/dist/components/slot-upload.js +213 -0
  156. package/dist/components/slot-upload.js.map +1 -0
  157. package/dist/components/social/bans.d.ts +42 -0
  158. package/dist/components/social/bans.js +300 -0
  159. package/dist/components/social/bans.js.map +1 -0
  160. package/dist/components/social/comments.d.ts +42 -0
  161. package/dist/components/social/comments.js +517 -0
  162. package/dist/components/social/comments.js.map +1 -0
  163. package/dist/components/social/engagement.d.ts +45 -0
  164. package/dist/components/social/engagement.js +129 -0
  165. package/dist/components/social/engagement.js.map +1 -0
  166. package/dist/components/social/index.d.ts +6 -0
  167. package/dist/components/social/moderation.d.ts +32 -0
  168. package/dist/components/social/moderation.js +383 -0
  169. package/dist/components/social/moderation.js.map +1 -0
  170. package/dist/components/social/parts.d.ts +50 -0
  171. package/dist/components/social/parts.js +106 -0
  172. package/dist/components/social/parts.js.map +1 -0
  173. package/dist/components/social/poll-editor.d.ts +34 -0
  174. package/dist/components/social/poll-editor.js +567 -0
  175. package/dist/components/social/poll-editor.js.map +1 -0
  176. package/dist/components/social/poll.d.ts +30 -0
  177. package/dist/components/social/poll.js +252 -0
  178. package/dist/components/social/poll.js.map +1 -0
  179. package/dist/components/sortable-list.d.ts +29 -0
  180. package/dist/components/sortable-list.js +121 -0
  181. package/dist/components/sortable-list.js.map +1 -0
  182. package/dist/components/video-mini-player.d.ts +35 -0
  183. package/dist/components/video-mini-player.js +236 -0
  184. package/dist/components/video-mini-player.js.map +1 -0
  185. package/dist/components/video-player.d.ts +146 -0
  186. package/dist/components/video-player.js +630 -0
  187. package/dist/components/video-player.js.map +1 -0
  188. package/dist/components/video-poster-picker.d.ts +59 -0
  189. package/dist/components/video-poster-picker.js +335 -0
  190. package/dist/components/video-poster-picker.js.map +1 -0
  191. package/dist/components/video-poster.d.ts +24 -0
  192. package/dist/components/video-poster.js +46 -0
  193. package/dist/components/video-poster.js.map +1 -0
  194. package/dist/i18n/context.d.ts +4 -0
  195. package/dist/i18n/context.js +11 -0
  196. package/dist/i18n/context.js.map +1 -0
  197. package/dist/i18n/messages.d.ts +40 -0
  198. package/dist/i18n/messages.js +94 -0
  199. package/dist/i18n/messages.js.map +1 -0
  200. package/dist/index.d.ts +23 -0
  201. package/dist/index.js +41 -0
  202. package/dist/locales/de.d.ts +2 -0
  203. package/dist/locales/de.js +271 -0
  204. package/dist/locales/de.js.map +1 -0
  205. package/dist/locales/en.d.ts +457 -0
  206. package/dist/locales/en.js +271 -0
  207. package/dist/locales/en.js.map +1 -0
  208. package/dist/locales/es.d.ts +2 -0
  209. package/dist/locales/es.js +271 -0
  210. package/dist/locales/es.js.map +1 -0
  211. package/dist/locales/ja.d.ts +2 -0
  212. package/dist/locales/ja.js +271 -0
  213. package/dist/locales/ja.js.map +1 -0
  214. package/dist/locales/ko.d.ts +2 -0
  215. package/dist/locales/ko.js +271 -0
  216. package/dist/locales/ko.js.map +1 -0
  217. package/dist/locales/social/de.d.ts +2 -0
  218. package/dist/locales/social/de.js +198 -0
  219. package/dist/locales/social/de.js.map +1 -0
  220. package/dist/locales/social/en.d.ts +195 -0
  221. package/dist/locales/social/en.js +198 -0
  222. package/dist/locales/social/en.js.map +1 -0
  223. package/dist/locales/social/es.d.ts +2 -0
  224. package/dist/locales/social/es.js +198 -0
  225. package/dist/locales/social/es.js.map +1 -0
  226. package/dist/locales/social/ja.d.ts +2 -0
  227. package/dist/locales/social/ja.js +198 -0
  228. package/dist/locales/social/ja.js.map +1 -0
  229. package/dist/locales/social/ko.d.ts +2 -0
  230. package/dist/locales/social/ko.js +198 -0
  231. package/dist/locales/social/ko.js.map +1 -0
  232. package/dist/locales/social/zh.d.ts +2 -0
  233. package/dist/locales/social/zh.js +198 -0
  234. package/dist/locales/social/zh.js.map +1 -0
  235. package/dist/locales/zh.d.ts +2 -0
  236. package/dist/locales/zh.js +271 -0
  237. package/dist/locales/zh.js.map +1 -0
  238. package/dist/provider.d.ts +22 -0
  239. package/dist/provider.js +59 -0
  240. package/dist/provider.js.map +1 -0
  241. package/dist/react/canonical.d.ts +33 -0
  242. package/dist/react/canonical.js +88 -0
  243. package/dist/react/canonical.js.map +1 -0
  244. package/dist/react/comments.d.ts +82 -0
  245. package/dist/react/comments.js +147 -0
  246. package/dist/react/comments.js.map +1 -0
  247. package/dist/react/config.d.ts +13 -0
  248. package/dist/react/config.js +14 -0
  249. package/dist/react/config.js.map +1 -0
  250. package/dist/react/context.d.ts +48 -0
  251. package/dist/react/context.js +37 -0
  252. package/dist/react/context.js.map +1 -0
  253. package/dist/react/crop.d.ts +49 -0
  254. package/dist/react/crop.js +107 -0
  255. package/dist/react/crop.js.map +1 -0
  256. package/dist/react/engagement.d.ts +38 -0
  257. package/dist/react/engagement.js +88 -0
  258. package/dist/react/engagement.js.map +1 -0
  259. package/dist/react/folder.d.ts +83 -0
  260. package/dist/react/folder.js +183 -0
  261. package/dist/react/folder.js.map +1 -0
  262. package/dist/react/gallery.d.ts +140 -0
  263. package/dist/react/gallery.js +477 -0
  264. package/dist/react/gallery.js.map +1 -0
  265. package/dist/react/index.d.ts +21 -0
  266. package/dist/react/inline-preview.d.ts +24 -0
  267. package/dist/react/inline-preview.js +76 -0
  268. package/dist/react/inline-preview.js.map +1 -0
  269. package/dist/react/player.d.ts +70 -0
  270. package/dist/react/player.js +214 -0
  271. package/dist/react/player.js.map +1 -0
  272. package/dist/react/polls.d.ts +74 -0
  273. package/dist/react/polls.js +176 -0
  274. package/dist/react/polls.js.map +1 -0
  275. package/dist/react/posts.d.ts +59 -0
  276. package/dist/react/posts.js +149 -0
  277. package/dist/react/posts.js.map +1 -0
  278. package/dist/react/provider.d.ts +23 -0
  279. package/dist/react/provider.js +35 -0
  280. package/dist/react/provider.js.map +1 -0
  281. package/dist/react/public.d.ts +39 -0
  282. package/dist/react/public.js +70 -0
  283. package/dist/react/public.js.map +1 -0
  284. package/dist/react/read.d.ts +52 -0
  285. package/dist/react/read.js +143 -0
  286. package/dist/react/read.js.map +1 -0
  287. package/dist/react/resources.d.ts +70 -0
  288. package/dist/react/resources.js +247 -0
  289. package/dist/react/resources.js.map +1 -0
  290. package/dist/react/slot.d.ts +102 -0
  291. package/dist/react/slot.js +181 -0
  292. package/dist/react/slot.js.map +1 -0
  293. package/dist/react/store.d.ts +51 -0
  294. package/dist/react/store.js +164 -0
  295. package/dist/react/store.js.map +1 -0
  296. package/dist/react/upload.d.ts +85 -0
  297. package/dist/react/upload.js +150 -0
  298. package/dist/react/upload.js.map +1 -0
  299. package/dist/react/use-resource.d.ts +43 -0
  300. package/dist/react/use-resource.js +66 -0
  301. package/dist/react/use-resource.js.map +1 -0
  302. package/dist/react/video.d.ts +118 -0
  303. package/dist/react/video.js +184 -0
  304. package/dist/react/video.js.map +1 -0
  305. package/dist/react/viewport.d.ts +19 -0
  306. package/dist/react/viewport.js +30 -0
  307. package/dist/react/viewport.js.map +1 -0
  308. package/dist/react.js +21 -0
  309. package/dist/scope.d.ts +14 -0
  310. package/dist/scope.js +30 -0
  311. package/dist/scope.js.map +1 -0
  312. package/dist/styles.css +3 -0
  313. package/dist/ui/alert-dialog.d.ts +18 -0
  314. package/dist/ui/alert-dialog.js +86 -0
  315. package/dist/ui/alert-dialog.js.map +1 -0
  316. package/dist/ui/alert.d.ts +10 -0
  317. package/dist/ui/alert.js +38 -0
  318. package/dist/ui/alert.js.map +1 -0
  319. package/dist/ui/avatar.d.ts +11 -0
  320. package/dist/ui/avatar.js +31 -0
  321. package/dist/ui/avatar.js.map +1 -0
  322. package/dist/ui/badge.d.ts +7 -0
  323. package/dist/ui/badge.js +31 -0
  324. package/dist/ui/badge.js.map +1 -0
  325. package/dist/ui/button.d.ts +8 -0
  326. package/dist/ui/button.js +46 -0
  327. package/dist/ui/button.js.map +1 -0
  328. package/dist/ui/dialog.d.ts +17 -0
  329. package/dist/ui/dialog.js +91 -0
  330. package/dist/ui/dialog.js.map +1 -0
  331. package/dist/ui/dropdown-menu.d.ts +15 -0
  332. package/dist/ui/dropdown-menu.js +105 -0
  333. package/dist/ui/dropdown-menu.js.map +1 -0
  334. package/dist/ui/input.d.ts +3 -0
  335. package/dist/ui/input.js +17 -0
  336. package/dist/ui/input.js.map +1 -0
  337. package/dist/ui/label.d.ts +3 -0
  338. package/dist/ui/label.js +15 -0
  339. package/dist/ui/label.js.map +1 -0
  340. package/dist/ui/progress.d.ts +7 -0
  341. package/dist/ui/progress.js +31 -0
  342. package/dist/ui/progress.js.map +1 -0
  343. package/dist/ui/select.d.ts +15 -0
  344. package/dist/ui/select.js +98 -0
  345. package/dist/ui/select.js.map +1 -0
  346. package/dist/ui/skeleton.d.ts +2 -0
  347. package/dist/ui/skeleton.js +14 -0
  348. package/dist/ui/skeleton.js.map +1 -0
  349. package/dist/ui/slider.d.ts +3 -0
  350. package/dist/ui/slider.js +35 -0
  351. package/dist/ui/slider.js.map +1 -0
  352. package/dist/ui/switch.d.ts +5 -0
  353. package/dist/ui/switch.js +20 -0
  354. package/dist/ui/switch.js.map +1 -0
  355. package/dist/ui/tabs.d.ts +10 -0
  356. package/dist/ui/tabs.js +47 -0
  357. package/dist/ui/tabs.js.map +1 -0
  358. package/dist/ui/textarea.d.ts +3 -0
  359. package/dist/ui/textarea.js +15 -0
  360. package/dist/ui/textarea.js.map +1 -0
  361. package/dist/ui/toggle-group.d.ts +5 -0
  362. package/dist/ui/toggle-group.js +23 -0
  363. package/dist/ui/toggle-group.js.map +1 -0
  364. package/dist/urls/index.d.ts +100 -0
  365. package/dist/urls.js +118 -0
  366. package/dist/urls.js.map +1 -0
  367. package/package.json +118 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moderation.js","names":[],"sources":["../../../src/components/social/moderation.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useMemo, useState } from \"react\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { Decision, HeldKind } from \"../../client/content/types.js\";\nimport { toContentKitError, type ContentKitError } from \"../../client/errors.js\";\nimport type { AdminComment, HeldItem, PublicUser } from \"../../client/generated/wire.js\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { useAdminComments, useModerationQueue } from \"../../react/comments.js\";\nimport { useErrorReporter, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Input } from \"#ckui/ui/input\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"#ckui/ui/select\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"#ckui/ui/tabs\";\nimport { CommentBanDialog, CommentBans } from \"./bans.js\";\nimport { contentError, ErrorLine, RelativeTime, UserAvatar, UserName } from \"./parts.js\";\n\nexport type ModerationSection = \"comments\" | \"queue\" | \"bans\";\n\nexport interface CommentModerationProps {\n /** Content kinds offered as a filter of the comment list: codes, or codes with labels. */\n contentKinds?: readonly (string | { value: string; label: string })[];\n /** A link to a commented item. */\n itemHref?: (item: { kind: string; id: string }) => string | undefined;\n userHref?: (user: PublicUser) => string | undefined;\n /** The sections, in order. Default all: every comment, the review queue, the site's bans. */\n sections?: readonly ModerationSection[];\n pageSize?: number;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\n/**\n * Staff: every comment (deleted, held and rejected ones with their text) to\n * delete, restore or ban its author; the review queue of held comments and\n * posts to approve or reject; and the site's comment bans. Each section\n * shows what the caller's permissions allow and says so when they don't.\n */\nexport function CommentModeration({ sections = [\"comments\", \"queue\", \"bans\"], className, appearance, ...p }: CommentModerationProps) {\n const { t } = useMessages();\n const [tab, setTab] = useState<ModerationSection>(sections[0] ?? \"comments\");\n const label: Record<ModerationSection, string> = { comments: t(\"moderation.all\"), queue: t(\"moderation.queue\"), bans: t(\"moderation.bans\") };\n return (\n <ContentKitUiRoot appearance={appearance} className={cn(\"grid gap-4 text-sm\", className)} data-ckui=\"comment-moderation\">\n <h2 className=\"text-base font-semibold\">{t(\"moderation.title\")}</h2>\n <Tabs value={tab} onValueChange={(v) => setTab(v as ModerationSection)}>\n {sections.length > 1 && (\n <TabsList>\n {sections.map((s) => (\n <TabsTrigger key={s} value={s}>\n {label[s]}\n </TabsTrigger>\n ))}\n </TabsList>\n )}\n {sections.includes(\"comments\") && (\n <TabsContent value=\"comments\" className=\"pt-3\">\n <AllComments {...p} />\n </TabsContent>\n )}\n {sections.includes(\"queue\") && (\n <TabsContent value=\"queue\" className=\"pt-3\">\n <Queue {...p} />\n </TabsContent>\n )}\n {sections.includes(\"bans\") && (\n <TabsContent value=\"bans\" className=\"pt-3\">\n <CommentBans scope=\"global\" pageSize={p.pageSize} userHref={p.userHref} client={p.client} onError={p.onError} />\n </TabsContent>\n )}\n </Tabs>\n </ContentKitUiRoot>\n );\n}\n\ntype Rest = Omit<CommentModerationProps, \"sections\" | \"className\" | \"appearance\">;\n\nfunction status(c: AdminComment): \"deleted\" | \"held\" | \"rejected\" | \"published\" {\n if (c.deleted) return \"deleted\";\n return c.moderation === \"held\" ? \"held\" : c.moderation === \"rejected\" ? \"rejected\" : \"published\";\n}\n\nfunction AllComments(p: Rest) {\n const m = useMessages();\n const { t } = m;\n const kinds = useMemo(() => (p.contentKinds ?? []).map((k) => (typeof k === \"string\" ? { value: k, label: k } : k)), [p.contentKinds]);\n const [kind, setKind] = useState(\"\");\n const list = useAdminComments({ contentKind: kind, pageSize: p.pageSize, client: p.client });\n const report = useErrorReporter(p.onError);\n const [error, setError] = useState<ContentKitError | null>(null);\n const [banning, setBanning] = useState<{ id: string; name: string } | null>(null);\n const act = (op: \"comment.delete\" | \"comment.restore\", fn: () => Promise<unknown>) => {\n setError(null);\n fn().catch((e) => {\n const err = toContentKitError(e);\n setError(err);\n report(err, op);\n });\n };\n return (\n <div className=\"grid gap-3\">\n {kinds.length > 0 && (\n <Select value={kind} onValueChange={(v) => setKind(String(v ?? \"\"))}>\n <SelectTrigger size=\"sm\" aria-label={t(\"moderation.kind\")}>\n <SelectValue>{(v: string) => (v ? (kinds.find((k) => k.value === v)?.label ?? v) : t(\"moderation.allKinds\"))}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"\">{t(\"moderation.allKinds\")}</SelectItem>\n {kinds.map((k) => (\n <SelectItem key={k.value} value={k.value}>\n {k.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n <ErrorLine error={error} />\n <Listing loading={list.loading} error={list.error} empty={t(\"moderation.empty\")} count={list.items.length} reload={list.reload}>\n {list.items.map((c) => {\n const name = c.author?.username ?? c.anon_name ?? c.user_id ?? t(\"comments.anonymous\");\n const s = status(c);\n const href = p.itemHref?.({ kind: c.content_kind, id: c.content_id });\n return (\n <li key={c.id} className=\"grid gap-2 p-3\" data-ckui=\"admin-comment\" data-status={s}>\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-1\">\n <UserAvatar user={c.author} name={name} size=\"sm\" />\n <UserName user={c.author} name={name} href={p.userHref} />\n <RelativeTime at={c.created_at} className=\"text-xs text-muted-foreground\" />\n <Badge variant={s === \"published\" ? \"outline\" : s === \"held\" ? \"secondary\" : \"destructive\"}>{t(`moderation.${s}`)}</Badge>\n {c.reply_to_id && <Badge variant=\"outline\">{t(\"moderation.reply\")}</Badge>}\n <span className=\"text-xs text-muted-foreground\">\n {t(\"moderation.on\")}{\" \"}\n {href ? (\n <a className=\"hover:underline\" href={href}>\n {c.content_kind}/{c.content_id}\n </a>\n ) : (\n `${c.content_kind}/${c.content_id}`\n )}\n </span>\n </div>\n <p className={cn(\"line-clamp-4 break-words whitespace-pre-wrap\", c.deleted && \"text-muted-foreground line-through\")}>{c.body}</p>\n {c.moderation_reason && <p className=\"text-xs text-muted-foreground\">{t(\"moderation.heldBecause\", { reason: c.moderation_reason })}</p>}\n <div className=\"flex flex-wrap gap-2\">\n {c.deleted ? (\n <Button size=\"sm\" variant=\"outline\" onClick={() => act(\"comment.restore\", () => list.restore(c.id))}>\n {t(\"moderation.restore\")}\n </Button>\n ) : (\n <Button size=\"sm\" variant=\"destructive\" onClick={() => act(\"comment.delete\", () => list.remove(c.id))}>\n {t(\"moderation.delete\")}\n </Button>\n )}\n {c.user_id && (\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setBanning({ id: c.user_id!, name })}>\n {t(\"comments.ban\")}\n </Button>\n )}\n </div>\n </li>\n );\n })}\n </Listing>\n {list.hasMore && (\n <Button variant=\"outline\" className=\"justify-self-center\" disabled={list.loadingMore} onClick={() => void list.loadMore()}>\n {t(\"moderation.loadMore\")}\n </Button>\n )}\n {banning && <CommentBanDialog open onOpenChange={(o) => !o && setBanning(null)} user={banning} scopes={[\"global\"]} client={p.client} onError={p.onError} />}\n </div>\n );\n}\n\nfunction Queue(p: Rest) {\n const m = useMessages();\n const { t } = m;\n const [kind, setKind] = useState<HeldKind>(\"comment\");\n const queue = useModerationQueue({ kind, pageSize: p.pageSize, client: p.client });\n return (\n <div className=\"grid gap-3\">\n <div className=\"flex gap-2\" role=\"group\" aria-label={t(\"moderation.queue\")}>\n {([\"comment\", \"post\"] as const).map((k) => (\n <Button key={k} size=\"sm\" variant={kind === k ? \"default\" : \"outline\"} aria-pressed={kind === k} onClick={() => setKind(k)}>\n {t(k === \"post\" ? \"moderation.queuePosts\" : \"moderation.queueComments\")}\n </Button>\n ))}\n </div>\n <Listing loading={queue.loading} error={queue.error} empty={t(\"moderation.queueEmpty\")} count={queue.items.length} reload={queue.reload}>\n {queue.items.map((it) => (\n <HeldRow key={it.id} item={it} itemHref={p.itemHref} userHref={p.userHref} onResolve={queue.resolve} reload={queue.reload} onError={p.onError} />\n ))}\n </Listing>\n {queue.hasMore && (\n <Button variant=\"outline\" className=\"justify-self-center\" disabled={queue.loadingMore} onClick={() => void queue.loadMore()}>\n {t(\"moderation.loadMore\")}\n </Button>\n )}\n </div>\n );\n}\n\nfunction HeldRow(p: {\n item: HeldItem;\n itemHref?: Rest[\"itemHref\"];\n userHref?: Rest[\"userHref\"];\n onResolve: (item: HeldItem, d: Decision, reason?: string) => Promise<void>;\n reload: () => void;\n onError?: ContentKitErrorHandler;\n}) {\n const m = useMessages();\n const { t } = m;\n const report = useErrorReporter(p.onError);\n const { item: it } = p;\n const [rejecting, setRejecting] = useState(false);\n const [reason, setReason] = useState(\"\");\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const name = it.author?.username ?? it.anon_name ?? it.author_id ?? t(\"comments.anonymous\");\n const href = p.itemHref?.({ kind: it.ref.content_kind, id: it.ref.content_id });\n const resolve = async (d: Decision) => {\n setPending(true);\n setError(null);\n try {\n await p.onResolve(it, d, d === \"reject\" ? reason.trim() || undefined : undefined);\n } catch (e) {\n const err = toContentKitError(e);\n report(err, \"moderation.resolve\");\n // A stale revision: the text changed since it was listed.\n if (err.code === \"not_found\" || err.code === \"conflict\") {\n setError(t(\"moderation.stale\"));\n p.reload();\n } else setError(contentError(m, err));\n } finally {\n setPending(false);\n }\n };\n return (\n <li className=\"grid gap-2 p-3\" data-ckui=\"held-item\">\n <div className=\"flex flex-wrap items-center gap-x-2 gap-y-1\">\n <UserAvatar user={it.author} name={name} size=\"sm\" />\n <UserName user={it.author} name={name} href={p.userHref} />\n <RelativeTime at={it.held_at} className=\"text-xs text-muted-foreground\" />\n {href && (\n <a className=\"text-xs text-muted-foreground hover:underline\" href={href}>\n {t(\"moderation.on\")} {it.ref.content_kind}/{it.ref.content_id}\n </a>\n )}\n </div>\n {it.title && <p className=\"font-medium\">{it.title}</p>}\n <p className=\"line-clamp-6 break-words whitespace-pre-wrap\">{it.body}</p>\n {(it.reason || it.error) && <p className=\"text-xs text-muted-foreground\">{t(\"moderation.heldBecause\", { reason: it.reason || it.error || \"\" })}</p>}\n {rejecting && (\n <Input value={reason} maxLength={500} placeholder={t(\"moderation.rejectReason\")} aria-label={t(\"moderation.rejectReason\")} onChange={(e) => setReason(e.target.value)} autoFocus />\n )}\n <div className=\"flex flex-wrap gap-2\">\n <Button size=\"sm\" disabled={pending} onClick={() => void resolve(\"approve\")}>\n {t(\"moderation.approve\")}\n </Button>\n <Button size=\"sm\" variant=\"destructive\" disabled={pending} onClick={() => (rejecting ? void resolve(\"reject\") : setRejecting(true))}>\n {t(\"moderation.reject\")}\n </Button>\n {rejecting && (\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setRejecting(false)}>\n {t(\"common.cancel\")}\n </Button>\n )}\n </div>\n {error && <ErrorLine>{error}</ErrorLine>}\n </li>\n );\n}\n\nfunction Listing(p: { loading: boolean; error?: ContentKitError; empty: string; count: number; reload: () => void; children: React.ReactNode }) {\n const m = useMessages();\n const { t } = m;\n if (p.loading && !p.count) {\n return (\n <div className=\"grid gap-3\" aria-busy>\n <Skeleton className=\"h-16 w-full\" />\n <Skeleton className=\"h-16 w-full\" />\n </div>\n );\n }\n if (p.error && !p.count) {\n return (\n <div className=\"grid justify-items-start gap-2\">\n <ErrorLine>{p.error.code === \"forbidden\" || p.error.code === \"unauthorized\" ? contentError(m, p.error) : t(\"moderation.loadFailed\")}</ErrorLine>\n <Button size=\"sm\" variant=\"outline\" onClick={p.reload}>\n {t(\"common.retry\")}\n </Button>\n </div>\n );\n }\n if (!p.count) return <p className=\"text-muted-foreground\">{p.empty}</p>;\n return <ul className=\"grid divide-y divide-border rounded-lg border border-border\">{p.children}</ul>;\n}\n"],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { ReactNode } from 'react';
2
+ import { ContentKitError } from '../../client/errors.js';
3
+ import { PublicUser } from '../../client/generated/wire.js';
4
+ import { Translator } from '../../i18n/messages.js';
5
+ import { ContentKitErrorHandler, SocialOperation } from '../../react/context.js';
6
+ /** A content refusal or fault in words: the content wording for shared codes, else the code's. */
7
+ export declare function contentError(m: Translator, e: unknown): string;
8
+ /** Runs one async action at a time: its pending state and last error, reported once. */
9
+ export declare function useAction(operation: SocialOperation, onError?: ContentKitErrorHandler): {
10
+ run: <T>(fn: () => Promise<T>) => Promise<T | undefined>;
11
+ pending: boolean;
12
+ error: ContentKitError | null;
13
+ setError: import('react').Dispatch<import('react').SetStateAction<ContentKitError | null>>;
14
+ };
15
+ /** "3 minutes ago", in the UI's language. */
16
+ export declare function relativeTime(m: Translator, iso: string, now?: number): string;
17
+ export declare function formatDate(m: Translator, iso: string, time?: boolean): string;
18
+ /** A relative time with the full date as its title. */
19
+ export declare function RelativeTime({ at, className }: {
20
+ at: string;
21
+ className?: string;
22
+ }): import('react').JSX.Element;
23
+ /** A user's avatar, or their initial. */
24
+ export declare function UserAvatar({ user, name, size }: {
25
+ user?: PublicUser;
26
+ name: string;
27
+ size?: "default" | "sm" | "lg";
28
+ }): import('react').JSX.Element;
29
+ /** A user's name, linked when the host gives a profile URL. */
30
+ export declare function UserName({ user, name, href, className }: {
31
+ user?: PublicUser;
32
+ name: string;
33
+ href?: (u: PublicUser) => string | undefined;
34
+ className?: string;
35
+ }): import('react').JSX.Element;
36
+ /** A confirmation for a destructive action. */
37
+ export declare function ConfirmDialog(p: {
38
+ open: boolean;
39
+ onOpenChange: (open: boolean) => void;
40
+ title: ReactNode;
41
+ description?: ReactNode;
42
+ confirm: ReactNode;
43
+ onConfirm: () => void;
44
+ }): import('react').JSX.Element;
45
+ /** A failure line, announced politely. */
46
+ export declare function ErrorLine({ error, children, className }: {
47
+ error?: ContentKitError | null;
48
+ children?: ReactNode;
49
+ className?: string;
50
+ }): import('react').JSX.Element | null;
@@ -0,0 +1,106 @@
1
+ import { toContentKitError as e } from "../../client/errors.js";
2
+ import { useMessages as t } from "../../i18n/context.js";
3
+ import { useErrorReporter as n } from "../../react/context.js";
4
+ import { AlertDialog as r, AlertDialogAction as i, AlertDialogCancel as a, AlertDialogContent as o, AlertDialogDescription as s, AlertDialogFooter as c, AlertDialogHeader as l, AlertDialogTitle as u } from "../../ui/alert-dialog.js";
5
+ import { Avatar as d, AvatarFallback as f, AvatarImage as p } from "../../ui/avatar.js";
6
+ import { useCallback as m, useState as h } from "react";
7
+ import { jsx as g, jsxs as _ } from "react/jsx-runtime";
8
+ import { cn as v } from "cn";
9
+ //#region src/components/social/parts.tsx
10
+ function y(t, n) {
11
+ let r = e(n);
12
+ return r.code === "rate_limited" ? t.t("contentErrors.rate_limited", { seconds: r.retryAfter ?? 60 }) : r.code === "forbidden" || r.code === "unauthorized" || r.code === "not_found" || r.code === "conflict" ? t.t(`contentErrors.${r.code}`) : r.code === "moderation_rejected" ? r.message ? t.t("comments.rejected", { reason: r.message }) : t.t("comments.rejectedNoReason") : t.error(r);
13
+ }
14
+ function b(t, r) {
15
+ let i = n(r), [a, o] = h(!1), [s, c] = h(null);
16
+ return {
17
+ run: m(async (n) => {
18
+ o(!0), c(null);
19
+ try {
20
+ return await n();
21
+ } catch (n) {
22
+ let r = e(n);
23
+ r.code !== "aborted" && (c(r), i(r, t));
24
+ return;
25
+ } finally {
26
+ o(!1);
27
+ }
28
+ }, [t, i]),
29
+ pending: a,
30
+ error: s,
31
+ setError: c
32
+ };
33
+ }
34
+ function x(e, t, n = Date.now()) {
35
+ let r = (Date.parse(t) - n) / 1e3, i = Math.abs(r);
36
+ if (i < 45) return e.t("time.justNow");
37
+ let a = new Intl.RelativeTimeFormat(e.language, { numeric: "auto" });
38
+ return i < 2700 ? a.format(Math.round(r / 60), "minute") : i < 79200 ? a.format(Math.round(r / 3600), "hour") : i < 2246400 ? a.format(Math.round(r / 86400), "day") : i < 28512e3 ? a.format(Math.round(r / 2592e3), "month") : a.format(Math.round(r / 31536e3), "year");
39
+ }
40
+ function S(e, t, n = !0) {
41
+ return new Intl.DateTimeFormat(e.language, n ? {
42
+ dateStyle: "medium",
43
+ timeStyle: "short"
44
+ } : { dateStyle: "medium" }).format(new Date(t));
45
+ }
46
+ function C({ at: e, className: n }) {
47
+ let r = t();
48
+ return /* @__PURE__ */ g("time", {
49
+ dateTime: e,
50
+ title: S(r, e),
51
+ className: n,
52
+ children: x(r, e)
53
+ });
54
+ }
55
+ function w({ user: e, name: t, size: n = "default" }) {
56
+ return /* @__PURE__ */ _(d, {
57
+ size: n,
58
+ children: [e?.avatar && /* @__PURE__ */ g(p, {
59
+ src: e.avatar,
60
+ srcSet: e.avatar_srcset,
61
+ sizes: n === "lg" ? "40px" : n === "sm" ? "24px" : "32px",
62
+ alt: "",
63
+ loading: "lazy"
64
+ }), /* @__PURE__ */ g(f, {
65
+ "aria-hidden": !0,
66
+ children: (t.trim()[0] ?? "?").toUpperCase()
67
+ })]
68
+ });
69
+ }
70
+ function T({ user: e, name: t, href: n, className: r }) {
71
+ let i = e && n?.(e), a = v("font-medium text-foreground", r);
72
+ return i ? /* @__PURE__ */ g("a", {
73
+ href: i,
74
+ className: v(a, "hover:underline"),
75
+ children: t
76
+ }) : /* @__PURE__ */ g("span", {
77
+ className: a,
78
+ children: t
79
+ });
80
+ }
81
+ function E(e) {
82
+ let { t: n } = t();
83
+ return /* @__PURE__ */ g(r, {
84
+ open: e.open,
85
+ onOpenChange: e.onOpenChange,
86
+ children: /* @__PURE__ */ _(o, { children: [/* @__PURE__ */ _(l, { children: [/* @__PURE__ */ g(u, { children: e.title }), e.description && /* @__PURE__ */ g(s, { children: e.description })] }), /* @__PURE__ */ _(c, { children: [/* @__PURE__ */ g(a, { children: n("common.cancel") }), /* @__PURE__ */ g(i, {
87
+ variant: "destructive",
88
+ onClick: () => {
89
+ e.onOpenChange(!1), e.onConfirm();
90
+ },
91
+ children: e.confirm
92
+ })] })] })
93
+ });
94
+ }
95
+ function D({ error: e, children: n, className: r }) {
96
+ let i = t();
97
+ return !e && !n ? null : /* @__PURE__ */ g("p", {
98
+ role: "alert",
99
+ className: v("text-sm text-destructive", r),
100
+ children: n ?? y(i, e)
101
+ });
102
+ }
103
+ //#endregion
104
+ export { E as ConfirmDialog, D as ErrorLine, C as RelativeTime, w as UserAvatar, T as UserName, y as contentError, S as formatDate, x as relativeTime, b as useAction };
105
+
106
+ //# sourceMappingURL=parts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parts.js","names":[],"sources":["../../../src/components/social/parts.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useCallback, useState, type ReactNode } from \"react\";\nimport { toContentKitError, type ContentKitError } from \"../../client/errors.js\";\nimport type { PublicUser } from \"../../client/generated/wire.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport type { Translator } from \"../../i18n/messages.js\";\nimport { useErrorReporter, type ContentKitErrorHandler, type SocialOperation } from \"../../react/context.js\";\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogTitle,\n} from \"#ckui/ui/alert-dialog\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"#ckui/ui/avatar\";\n\n/** A content refusal or fault in words: the content wording for shared codes, else the code's. */\nexport function contentError(m: Translator, e: unknown): string {\n const err = toContentKitError(e);\n if (err.code === \"rate_limited\") return m.t(\"contentErrors.rate_limited\", { seconds: err.retryAfter ?? 60 });\n if (err.code === \"forbidden\" || err.code === \"unauthorized\" || err.code === \"not_found\" || err.code === \"conflict\") return m.t(`contentErrors.${err.code}`);\n if (err.code === \"moderation_rejected\") return err.message ? m.t(\"comments.rejected\", { reason: err.message }) : m.t(\"comments.rejectedNoReason\");\n return m.error(err);\n}\n\n/** Runs one async action at a time: its pending state and last error, reported once. */\nexport function useAction(operation: SocialOperation, onError?: ContentKitErrorHandler) {\n const report = useErrorReporter(onError);\n const [pending, setPending] = useState(false);\n const [error, setError] = useState<ContentKitError | null>(null);\n const run = useCallback(\n async <T,>(fn: () => Promise<T>): Promise<T | undefined> => {\n setPending(true);\n setError(null);\n try {\n return await fn();\n } catch (e) {\n const err = toContentKitError(e);\n if (err.code !== \"aborted\") {\n setError(err);\n report(err, operation);\n }\n return undefined;\n } finally {\n setPending(false);\n }\n },\n [operation, report],\n );\n return { run, pending, error, setError };\n}\n\n/** \"3 minutes ago\", in the UI's language. */\nexport function relativeTime(m: Translator, iso: string, now = Date.now()): string {\n const s = (Date.parse(iso) - now) / 1000;\n const a = Math.abs(s);\n if (a < 45) return m.t(\"time.justNow\");\n const f = new Intl.RelativeTimeFormat(m.language, { numeric: \"auto\" });\n if (a < 2700) return f.format(Math.round(s / 60), \"minute\");\n if (a < 79200) return f.format(Math.round(s / 3600), \"hour\");\n if (a < 2246400) return f.format(Math.round(s / 86400), \"day\");\n if (a < 28512000) return f.format(Math.round(s / 2592000), \"month\");\n return f.format(Math.round(s / 31536000), \"year\");\n}\n\nexport function formatDate(m: Translator, iso: string, time = true): string {\n return new Intl.DateTimeFormat(m.language, time ? { dateStyle: \"medium\", timeStyle: \"short\" } : { dateStyle: \"medium\" }).format(new Date(iso));\n}\n\n/** A relative time with the full date as its title. */\nexport function RelativeTime({ at, className }: { at: string; className?: string }) {\n const m = useMessages();\n return (\n <time dateTime={at} title={formatDate(m, at)} className={className}>\n {relativeTime(m, at)}\n </time>\n );\n}\n\n/** A user's avatar, or their initial. */\nexport function UserAvatar({ user, name, size = \"default\" }: { user?: PublicUser; name: string; size?: \"default\" | \"sm\" | \"lg\" }) {\n return (\n <Avatar size={size}>\n {user?.avatar && <AvatarImage src={user.avatar} srcSet={user.avatar_srcset} sizes={size === \"lg\" ? \"40px\" : size === \"sm\" ? \"24px\" : \"32px\"} alt=\"\" loading=\"lazy\" />}\n <AvatarFallback aria-hidden>{(name.trim()[0] ?? \"?\").toUpperCase()}</AvatarFallback>\n </Avatar>\n );\n}\n\n/** A user's name, linked when the host gives a profile URL. */\nexport function UserName({ user, name, href, className }: { user?: PublicUser; name: string; href?: (u: PublicUser) => string | undefined; className?: string }) {\n const url = user && href?.(user);\n const cls = cn(\"font-medium text-foreground\", className);\n return url ? (\n <a href={url} className={cn(cls, \"hover:underline\")}>\n {name}\n </a>\n ) : (\n <span className={cls}>{name}</span>\n );\n}\n\n/** A confirmation for a destructive action. */\nexport function ConfirmDialog(p: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n title: ReactNode;\n description?: ReactNode;\n confirm: ReactNode;\n onConfirm: () => void;\n}) {\n const { t } = useMessages();\n return (\n <AlertDialog open={p.open} onOpenChange={p.onOpenChange}>\n <AlertDialogContent>\n <AlertDialogHeader>\n <AlertDialogTitle>{p.title}</AlertDialogTitle>\n {p.description && <AlertDialogDescription>{p.description}</AlertDialogDescription>}\n </AlertDialogHeader>\n <AlertDialogFooter>\n <AlertDialogCancel>{t(\"common.cancel\")}</AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={() => {\n p.onOpenChange(false);\n p.onConfirm();\n }}\n >\n {p.confirm}\n </AlertDialogAction>\n </AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n );\n}\n\n/** A failure line, announced politely. */\nexport function ErrorLine({ error, children, className }: { error?: ContentKitError | null; children?: ReactNode; className?: string }) {\n const m = useMessages();\n if (!error && !children) return null;\n return (\n <p role=\"alert\" className={cn(\"text-sm text-destructive\", className)}>\n {children ?? contentError(m, error)}\n </p>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { ContentKitClient } from '../../client/client.js';
2
+ import { Poll } from '../../client/generated/wire.js';
3
+ import { ContentKitUiAppearance } from '../../appearance.js';
4
+ import { ContentKitErrorHandler } from '../../react/context.js';
5
+ export interface PollEditorProps {
6
+ /** The poll to edit; none creates one. */
7
+ poll?: string | null;
8
+ /** Languages offered for a new poll: codes, or codes with labels. Without them the language is typed. */
9
+ languages?: readonly (string | {
10
+ value: string;
11
+ label: string;
12
+ })[];
13
+ /** A new poll's language. Default the first offered, else "en". */
14
+ defaultLanguage?: string;
15
+ /** Offer free-text polls (the host registered an answer classifier). Default false. */
16
+ freeText?: boolean;
17
+ /** Most options. Default 10. */
18
+ maxOptions?: number;
19
+ onCreated?: (poll: Poll) => void;
20
+ onSaved?: (poll: Poll) => void;
21
+ onDeleted?: () => void;
22
+ client?: ContentKitClient;
23
+ onError?: ContentKitErrorHandler;
24
+ className?: string;
25
+ appearance?: ContentKitUiAppearance;
26
+ }
27
+ /**
28
+ * Staff: creates or edits a poll (PollWrite): question, language, type, when
29
+ * it goes live and closes, visibility, a question image, and options with
30
+ * images, reordered with the move buttons. A new poll is written at once with
31
+ * its images; an existing one saves its fields with Save and each option
32
+ * change as it is made.
33
+ */
34
+ export declare function PollEditor(p: PollEditorProps): import('react').JSX.Element;