@ciridae/ui 0.2.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 (339) hide show
  1. package/README.md +31 -0
  2. package/dist/components/agentic/agent-card.d.ts +28 -0
  3. package/dist/components/agentic/agent-card.js +27 -0
  4. package/dist/components/agentic/agent-composer.d.ts +44 -0
  5. package/dist/components/agentic/agent-composer.js +104 -0
  6. package/dist/components/agentic/agent-context.d.ts +28 -0
  7. package/dist/components/agentic/agent-context.js +102 -0
  8. package/dist/components/agentic/agent-plan.d.ts +27 -0
  9. package/dist/components/agentic/agent-plan.js +43 -0
  10. package/dist/components/agentic/agent-queue.d.ts +46 -0
  11. package/dist/components/agentic/agent-queue.js +53 -0
  12. package/dist/components/agentic/agent-task.d.ts +16 -0
  13. package/dist/components/agentic/agent-task.js +20 -0
  14. package/dist/components/agentic/approval-request.d.ts +24 -0
  15. package/dist/components/agentic/approval-request.js +57 -0
  16. package/dist/components/agentic/artifact.d.ts +24 -0
  17. package/dist/components/agentic/artifact.js +72 -0
  18. package/dist/components/agentic/attachments.d.ts +124 -0
  19. package/dist/components/agentic/attachments.js +595 -0
  20. package/dist/components/agentic/audio-player.d.ts +16 -0
  21. package/dist/components/agentic/audio-player.js +21 -0
  22. package/dist/components/agentic/canvas.d.ts +10 -0
  23. package/dist/components/agentic/canvas.js +22 -0
  24. package/dist/components/agentic/clipboard.d.ts +2 -0
  25. package/dist/components/agentic/clipboard.js +12 -0
  26. package/dist/components/agentic/code-block.d.ts +43 -0
  27. package/dist/components/agentic/code-block.js +92 -0
  28. package/dist/components/agentic/commit.d.ts +57 -0
  29. package/dist/components/agentic/commit.js +85 -0
  30. package/dist/components/agentic/connection.d.ts +3 -0
  31. package/dist/components/agentic/connection.js +8 -0
  32. package/dist/components/agentic/controls.d.ts +6 -0
  33. package/dist/components/agentic/controls.js +7 -0
  34. package/dist/components/agentic/conversation.d.ts +25 -0
  35. package/dist/components/agentic/conversation.js +56 -0
  36. package/dist/components/agentic/edge.d.ts +8 -0
  37. package/dist/components/agentic/edge.js +65 -0
  38. package/dist/components/agentic/effort-selector.d.ts +43 -0
  39. package/dist/components/agentic/effort-selector.js +47 -0
  40. package/dist/components/agentic/environment-variables.d.ts +32 -0
  41. package/dist/components/agentic/environment-variables.js +66 -0
  42. package/dist/components/agentic/file-tree.d.ts +24 -0
  43. package/dist/components/agentic/file-tree.js +56 -0
  44. package/dist/components/agentic/image.d.ts +9 -0
  45. package/dist/components/agentic/image.js +11 -0
  46. package/dist/components/agentic/inline-citation.d.ts +40 -0
  47. package/dist/components/agentic/inline-citation.js +111 -0
  48. package/dist/components/agentic/jsx-preview.d.ts +19 -0
  49. package/dist/components/agentic/jsx-preview.js +34 -0
  50. package/dist/components/agentic/message-branch.d.ts +20 -0
  51. package/dist/components/agentic/message-branch.js +83 -0
  52. package/dist/components/agentic/message-response.css +265 -0
  53. package/dist/components/agentic/message-response.css.d.ts +2 -0
  54. package/dist/components/agentic/message.d.ts +27 -0
  55. package/dist/components/agentic/message.js +57 -0
  56. package/dist/components/agentic/mic-selector.d.ts +58 -0
  57. package/dist/components/agentic/mic-selector.js +173 -0
  58. package/dist/components/agentic/model-selector.d.ts +39 -0
  59. package/dist/components/agentic/model-selector.js +47 -0
  60. package/dist/components/agentic/node.d.ts +26 -0
  61. package/dist/components/agentic/node.js +29 -0
  62. package/dist/components/agentic/open-in-chat.d.ts +9 -0
  63. package/dist/components/agentic/open-in-chat.js +8 -0
  64. package/dist/components/agentic/package-info.d.ts +30 -0
  65. package/dist/components/agentic/package-info.js +44 -0
  66. package/dist/components/agentic/panel.d.ts +6 -0
  67. package/dist/components/agentic/panel.js +7 -0
  68. package/dist/components/agentic/persona.d.ts +16 -0
  69. package/dist/components/agentic/persona.js +116 -0
  70. package/dist/components/agentic/prompt-input-action-menu.d.ts +16 -0
  71. package/dist/components/agentic/prompt-input-action-menu.js +22 -0
  72. package/dist/components/agentic/prompt-input-command.d.ts +18 -0
  73. package/dist/components/agentic/prompt-input-command.js +25 -0
  74. package/dist/components/agentic/prompt-input-hover-card.d.ts +10 -0
  75. package/dist/components/agentic/prompt-input-hover-card.js +13 -0
  76. package/dist/components/agentic/prompt-input-select.d.ts +14 -0
  77. package/dist/components/agentic/prompt-input-select.js +19 -0
  78. package/dist/components/agentic/prompt-input-tabs.d.ts +17 -0
  79. package/dist/components/agentic/prompt-input-tabs.js +45 -0
  80. package/dist/components/agentic/prompt-input.d.ts +79 -0
  81. package/dist/components/agentic/prompt-input.js +206 -0
  82. package/dist/components/agentic/reasoning.d.ts +21 -0
  83. package/dist/components/agentic/reasoning.js +106 -0
  84. package/dist/components/agentic/run-checkpoint.d.ts +13 -0
  85. package/dist/components/agentic/run-checkpoint.js +19 -0
  86. package/dist/components/agentic/run-trace.d.ts +30 -0
  87. package/dist/components/agentic/run-trace.js +56 -0
  88. package/dist/components/agentic/sandbox.d.ts +24 -0
  89. package/dist/components/agentic/sandbox.js +33 -0
  90. package/dist/components/agentic/schema-display.d.ts +39 -0
  91. package/dist/components/agentic/schema-display.js +56 -0
  92. package/dist/components/agentic/shimmer.d.ts +11 -0
  93. package/dist/components/agentic/shimmer.js +16 -0
  94. package/dist/components/agentic/snippet.d.ts +18 -0
  95. package/dist/components/agentic/snippet.js +35 -0
  96. package/dist/components/agentic/sources.d.ts +16 -0
  97. package/dist/components/agentic/sources.js +17 -0
  98. package/dist/components/agentic/speech-input.d.ts +24 -0
  99. package/dist/components/agentic/speech-input.js +30 -0
  100. package/dist/components/agentic/stack-trace.d.ts +27 -0
  101. package/dist/components/agentic/stack-trace.js +76 -0
  102. package/dist/components/agentic/suggestion.d.ts +12 -0
  103. package/dist/components/agentic/suggestion.js +15 -0
  104. package/dist/components/agentic/terminal.d.ts +24 -0
  105. package/dist/components/agentic/terminal.js +47 -0
  106. package/dist/components/agentic/test-results.d.ts +51 -0
  107. package/dist/components/agentic/test-results.js +83 -0
  108. package/dist/components/agentic/theme.d.ts +5 -0
  109. package/dist/components/agentic/theme.js +31 -0
  110. package/dist/components/agentic/tool.d.ts +25 -0
  111. package/dist/components/agentic/tool.js +73 -0
  112. package/dist/components/agentic/toolbar.d.ts +6 -0
  113. package/dist/components/agentic/toolbar.js +7 -0
  114. package/dist/components/agentic/transcription.d.ts +20 -0
  115. package/dist/components/agentic/transcription.js +32 -0
  116. package/dist/components/agentic/types.d.ts +172 -0
  117. package/dist/components/agentic/types.js +1 -0
  118. package/dist/components/agentic/use-controllable-state.d.ts +6 -0
  119. package/dist/components/agentic/use-controllable-state.js +13 -0
  120. package/dist/components/agentic/voice-selector.d.ts +69 -0
  121. package/dist/components/agentic/voice-selector.js +122 -0
  122. package/dist/components/agentic/web-preview.d.ts +25 -0
  123. package/dist/components/agentic/web-preview.js +33 -0
  124. package/dist/components/ui/accordion.d.ts +7 -0
  125. package/dist/components/ui/accordion.js +17 -0
  126. package/dist/components/ui/alert-dialog.d.ts +22 -0
  127. package/dist/components/ui/alert-dialog.js +51 -0
  128. package/dist/components/ui/alert.d.ts +9 -0
  129. package/dist/components/ui/alert.js +24 -0
  130. package/dist/components/ui/aspect-ratio.d.ts +3 -0
  131. package/dist/components/ui/aspect-ratio.js +7 -0
  132. package/dist/components/ui/avatar.d.ts +11 -0
  133. package/dist/components/ui/avatar.js +22 -0
  134. package/dist/components/ui/badge-variants.d.ts +100 -0
  135. package/dist/components/ui/badge-variants.js +140 -0
  136. package/dist/components/ui/badge.d.ts +6 -0
  137. package/dist/components/ui/badge.js +9 -0
  138. package/dist/components/ui/breadcrumb.d.ts +11 -0
  139. package/dist/components/ui/breadcrumb.js +27 -0
  140. package/dist/components/ui/button-group-variants.d.ts +6 -0
  141. package/dist/components/ui/button-group-variants.js +13 -0
  142. package/dist/components/ui/button-group.d.ts +8 -0
  143. package/dist/components/ui/button-group.js +16 -0
  144. package/dist/components/ui/button-variants.d.ts +133 -0
  145. package/dist/components/ui/button-variants.js +170 -0
  146. package/dist/components/ui/button.d.ts +8 -0
  147. package/dist/components/ui/button.js +67 -0
  148. package/dist/components/ui/calendar.d.ts +9 -0
  149. package/dist/components/ui/calendar.js +99 -0
  150. package/dist/components/ui/card.d.ts +14 -0
  151. package/dist/components/ui/card.js +28 -0
  152. package/dist/components/ui/carousel.d.ts +19 -0
  153. package/dist/components/ui/carousel.js +104 -0
  154. package/dist/components/ui/chart-context.d.ts +33 -0
  155. package/dist/components/ui/chart-context.js +36 -0
  156. package/dist/components/ui/chart-panel.d.ts +11 -0
  157. package/dist/components/ui/chart-panel.js +6 -0
  158. package/dist/components/ui/chart-tooltip.d.ts +13 -0
  159. package/dist/components/ui/chart-tooltip.js +84 -0
  160. package/dist/components/ui/chart.d.ts +23 -0
  161. package/dist/components/ui/chart.js +52 -0
  162. package/dist/components/ui/checkbox.d.ts +4 -0
  163. package/dist/components/ui/checkbox.js +9 -0
  164. package/dist/components/ui/collapsible.d.ts +5 -0
  165. package/dist/components/ui/collapsible.js +12 -0
  166. package/dist/components/ui/combobox-anchor.d.ts +3 -0
  167. package/dist/components/ui/combobox-anchor.js +5 -0
  168. package/dist/components/ui/combobox.d.ts +23 -0
  169. package/dist/components/ui/combobox.js +54 -0
  170. package/dist/components/ui/command.d.ts +19 -0
  171. package/dist/components/ui/command.js +38 -0
  172. package/dist/components/ui/context-menu.d.ts +30 -0
  173. package/dist/components/ui/context-menu.js +63 -0
  174. package/dist/components/ui/data-table.d.ts +17 -0
  175. package/dist/components/ui/data-table.js +26 -0
  176. package/dist/components/ui/dialog.d.ts +22 -0
  177. package/dist/components/ui/dialog.js +48 -0
  178. package/dist/components/ui/direction-context.d.ts +3 -0
  179. package/dist/components/ui/direction-context.js +3 -0
  180. package/dist/components/ui/direction.d.ts +6 -0
  181. package/dist/components/ui/direction.js +7 -0
  182. package/dist/components/ui/drawer.d.ts +18 -0
  183. package/dist/components/ui/drawer.js +47 -0
  184. package/dist/components/ui/dropdown-menu.d.ts +30 -0
  185. package/dist/components/ui/dropdown-menu.js +63 -0
  186. package/dist/components/ui/empty.d.ts +11 -0
  187. package/dist/components/ui/empty.js +33 -0
  188. package/dist/components/ui/expandable-data-table.d.ts +24 -0
  189. package/dist/components/ui/expandable-data-table.js +62 -0
  190. package/dist/components/ui/field.d.ts +26 -0
  191. package/dist/components/ui/field.js +74 -0
  192. package/dist/components/ui/file-upload-field-parts.d.ts +21 -0
  193. package/dist/components/ui/file-upload-field-parts.js +55 -0
  194. package/dist/components/ui/file-upload-field.d.ts +15 -0
  195. package/dist/components/ui/file-upload-field.js +85 -0
  196. package/dist/components/ui/form-context.d.ts +23 -0
  197. package/dist/components/ui/form-context.js +35 -0
  198. package/dist/components/ui/form.d.ts +12 -0
  199. package/dist/components/ui/form.js +38 -0
  200. package/dist/components/ui/hover-card.d.ts +10 -0
  201. package/dist/components/ui/hover-card.js +22 -0
  202. package/dist/components/ui/input-group.d.ts +16 -0
  203. package/dist/components/ui/input-group.js +62 -0
  204. package/dist/components/ui/input-otp.d.ts +11 -0
  205. package/dist/components/ui/input-otp.js +21 -0
  206. package/dist/components/ui/input.d.ts +3 -0
  207. package/dist/components/ui/input.js +6 -0
  208. package/dist/components/ui/item.d.ts +23 -0
  209. package/dist/components/ui/item.js +66 -0
  210. package/dist/components/ui/kbd.d.ts +3 -0
  211. package/dist/components/ui/kbd.js +9 -0
  212. package/dist/components/ui/label.d.ts +4 -0
  213. package/dist/components/ui/label.js +7 -0
  214. package/dist/components/ui/loading-state.d.ts +27 -0
  215. package/dist/components/ui/loading-state.js +44 -0
  216. package/dist/components/ui/menubar.d.ts +30 -0
  217. package/dist/components/ui/menubar.js +63 -0
  218. package/dist/components/ui/metrics-strip.d.ts +7 -0
  219. package/dist/components/ui/metrics-strip.js +18 -0
  220. package/dist/components/ui/native-select.d.ts +7 -0
  221. package/dist/components/ui/native-select.js +13 -0
  222. package/dist/components/ui/navigation-menu-variants.d.ts +2 -0
  223. package/dist/components/ui/navigation-menu-variants.js +3 -0
  224. package/dist/components/ui/navigation-menu.d.ts +13 -0
  225. package/dist/components/ui/navigation-menu.js +30 -0
  226. package/dist/components/ui/page-header.d.ts +19 -0
  227. package/dist/components/ui/page-header.js +36 -0
  228. package/dist/components/ui/pagination.d.ts +13 -0
  229. package/dist/components/ui/pagination.js +29 -0
  230. package/dist/components/ui/popover.d.ts +14 -0
  231. package/dist/components/ui/popover.js +34 -0
  232. package/dist/components/ui/progress.d.ts +4 -0
  233. package/dist/components/ui/progress.js +8 -0
  234. package/dist/components/ui/property-list.d.ts +6 -0
  235. package/dist/components/ui/property-list.js +15 -0
  236. package/dist/components/ui/radio-group.d.ts +5 -0
  237. package/dist/components/ui/radio-group.js +11 -0
  238. package/dist/components/ui/registry-docs-api.d.ts +11 -0
  239. package/dist/components/ui/registry-docs-api.js +9 -0
  240. package/dist/components/ui/registry-docs-code.d.ts +19 -0
  241. package/dist/components/ui/registry-docs-code.js +78 -0
  242. package/dist/components/ui/registry-docs-showcase.d.ts +11 -0
  243. package/dist/components/ui/registry-docs-showcase.js +27 -0
  244. package/dist/components/ui/registry-docs.d.ts +27 -0
  245. package/dist/components/ui/registry-docs.js +32 -0
  246. package/dist/components/ui/resizable.d.ts +7 -0
  247. package/dist/components/ui/resizable.js +15 -0
  248. package/dist/components/ui/scroll-area.d.ts +7 -0
  249. package/dist/components/ui/scroll-area.js +10 -0
  250. package/dist/components/ui/select.d.ts +15 -0
  251. package/dist/components/ui/select.js +38 -0
  252. package/dist/components/ui/separator.d.ts +4 -0
  253. package/dist/components/ui/separator.js +7 -0
  254. package/dist/components/ui/sheet.d.ts +21 -0
  255. package/dist/components/ui/sheet.js +62 -0
  256. package/dist/components/ui/sidebar/context.d.ts +21 -0
  257. package/dist/components/ui/sidebar/context.js +15 -0
  258. package/dist/components/ui/sidebar/group.d.ts +10 -0
  259. package/dist/components/ui/sidebar/group.js +18 -0
  260. package/dist/components/ui/sidebar/layout.d.ts +17 -0
  261. package/dist/components/ui/sidebar/layout.js +73 -0
  262. package/dist/components/ui/sidebar/menu.d.ts +30 -0
  263. package/dist/components/ui/sidebar/menu.js +64 -0
  264. package/dist/components/ui/sidebar/provider.d.ts +7 -0
  265. package/dist/components/ui/sidebar/provider.js +53 -0
  266. package/dist/components/ui/sidebar/rail.d.ts +3 -0
  267. package/dist/components/ui/sidebar/rail.js +12 -0
  268. package/dist/components/ui/sidebar/trigger.d.ts +4 -0
  269. package/dist/components/ui/sidebar/trigger.js +16 -0
  270. package/dist/components/ui/sidebar-account-menu-theme.d.ts +7 -0
  271. package/dist/components/ui/sidebar-account-menu-theme.js +32 -0
  272. package/dist/components/ui/sidebar-account-menu.d.ts +14 -0
  273. package/dist/components/ui/sidebar-account-menu.js +51 -0
  274. package/dist/components/ui/sidebar.d.ts +7 -0
  275. package/dist/components/ui/sidebar.js +7 -0
  276. package/dist/components/ui/skeleton.d.ts +2 -0
  277. package/dist/components/ui/skeleton.js +15 -0
  278. package/dist/components/ui/slider.d.ts +4 -0
  279. package/dist/components/ui/slider.js +9 -0
  280. package/dist/components/ui/sonner.d.ts +3 -0
  281. package/dist/components/ui/sonner.js +33 -0
  282. package/dist/components/ui/spinner.d.ts +2 -0
  283. package/dist/components/ui/spinner.js +16 -0
  284. package/dist/components/ui/switch.d.ts +6 -0
  285. package/dist/components/ui/switch.js +7 -0
  286. package/dist/components/ui/table.d.ts +10 -0
  287. package/dist/components/ui/table.js +28 -0
  288. package/dist/components/ui/tabs-variants.d.ts +6 -0
  289. package/dist/components/ui/tabs-variants.js +13 -0
  290. package/dist/components/ui/tabs.d.ts +8 -0
  291. package/dist/components/ui/tabs.js +17 -0
  292. package/dist/components/ui/textarea.d.ts +3 -0
  293. package/dist/components/ui/textarea.js +6 -0
  294. package/dist/components/ui/toggle-group.d.ts +9 -0
  295. package/dist/components/ui/toggle-group.js +24 -0
  296. package/dist/components/ui/toggle-variants.d.ts +7 -0
  297. package/dist/components/ui/toggle-variants.js +19 -0
  298. package/dist/components/ui/toggle.d.ts +5 -0
  299. package/dist/components/ui/toggle.js +9 -0
  300. package/dist/components/ui/tooltip.d.ts +11 -0
  301. package/dist/components/ui/tooltip.js +25 -0
  302. package/dist/components/ui/workflow-timeline.d.ts +20 -0
  303. package/dist/components/ui/workflow-timeline.js +92 -0
  304. package/dist/hooks/use-mobile.d.ts +1 -0
  305. package/dist/hooks/use-mobile.js +15 -0
  306. package/dist/lib/utils.d.ts +5 -0
  307. package/dist/lib/utils.js +8 -0
  308. package/dist/styled-system/css/conditions.mjs +36 -0
  309. package/dist/styled-system/css/css.mjs +45 -0
  310. package/dist/styled-system/css/cva.mjs +87 -0
  311. package/dist/styled-system/css/cx.mjs +15 -0
  312. package/dist/styled-system/css/index.mjs +4 -0
  313. package/dist/styled-system/css/sva.mjs +46 -0
  314. package/dist/styled-system/helpers.mjs +316 -0
  315. package/dist/styled-system/patterns/aspect-ratio.mjs +38 -0
  316. package/dist/styled-system/patterns/bleed.mjs +24 -0
  317. package/dist/styled-system/patterns/box.mjs +15 -0
  318. package/dist/styled-system/patterns/center.mjs +21 -0
  319. package/dist/styled-system/patterns/circle.mjs +25 -0
  320. package/dist/styled-system/patterns/container.mjs +21 -0
  321. package/dist/styled-system/patterns/cq.mjs +21 -0
  322. package/dist/styled-system/patterns/divider.mjs +25 -0
  323. package/dist/styled-system/patterns/flex.mjs +26 -0
  324. package/dist/styled-system/patterns/float.mjs +52 -0
  325. package/dist/styled-system/patterns/grid-item.mjs +25 -0
  326. package/dist/styled-system/patterns/grid.mjs +27 -0
  327. package/dist/styled-system/patterns/hstack.mjs +24 -0
  328. package/dist/styled-system/patterns/index.mjs +20 -0
  329. package/dist/styled-system/patterns/link-overlay.mjs +24 -0
  330. package/dist/styled-system/patterns/spacer.mjs +25 -0
  331. package/dist/styled-system/patterns/square.mjs +24 -0
  332. package/dist/styled-system/patterns/stack.mjs +24 -0
  333. package/dist/styled-system/patterns/visually-hidden.mjs +18 -0
  334. package/dist/styled-system/patterns/vstack.mjs +24 -0
  335. package/dist/styled-system/patterns/wrap.mjs +25 -0
  336. package/dist/styled-system/styles.css +1089 -0
  337. package/dist/styled-system/styles.css.d.ts +2 -0
  338. package/dist/styled-system/tokens/index.mjs +2304 -0
  339. package/package.json +688 -0
@@ -0,0 +1,265 @@
1
+ @import "katex/dist/katex.min.css";
2
+
3
+ @keyframes sd-fade-in {
4
+ from {
5
+ opacity: 0;
6
+ }
7
+ to {
8
+ opacity: 1;
9
+ }
10
+ }
11
+
12
+ @keyframes sd-blur-in {
13
+ from {
14
+ filter: blur(4px);
15
+ opacity: 0;
16
+ }
17
+ to {
18
+ filter: blur(0);
19
+ opacity: 1;
20
+ }
21
+ }
22
+
23
+ @keyframes sd-slide-up {
24
+ from {
25
+ opacity: 0;
26
+ transform: translateY(4px);
27
+ }
28
+ to {
29
+ opacity: 1;
30
+ transform: translateY(0);
31
+ }
32
+ }
33
+
34
+ [data-sd-animate] {
35
+ animation: var(--sd-animation, sd-fade-in) var(--sd-duration, var(--motion-duration-fast))
36
+ var(--sd-easing, var(--motion-ease-standard)) var(--sd-delay, 0ms) both;
37
+ }
38
+
39
+ .agentic-message-response {
40
+ color: var(--foreground);
41
+ font-size: 0.875rem;
42
+ line-height: 1.6;
43
+ max-width: 100%;
44
+ min-width: 0;
45
+ overflow-wrap: anywhere;
46
+ }
47
+
48
+ .agentic-message-response :where(h1, h2, h3, h4, h5, h6) {
49
+ color: var(--foreground);
50
+ font-family: var(--font-ciridae-display);
51
+ font-weight: var(--font-ciridae-heading-weight);
52
+ letter-spacing: 0;
53
+ line-height: 1.2;
54
+ margin-block: 1.25rem 0.5rem;
55
+ }
56
+
57
+ .agentic-message-response :where(h1) {
58
+ font-size: 1.35rem;
59
+ }
60
+
61
+ .agentic-message-response :where(h2) {
62
+ font-size: 1.2rem;
63
+ }
64
+
65
+ .agentic-message-response :where(h3) {
66
+ font-size: 1.05rem;
67
+ }
68
+
69
+ .agentic-message-response :where(h4, h5, h6) {
70
+ font-size: 0.95rem;
71
+ }
72
+
73
+ .agentic-message-response :where(p) {
74
+ margin-block: 0.75rem;
75
+ }
76
+
77
+ .agentic-message-response :where(ul, ol) {
78
+ margin-block: 0.75rem;
79
+ padding-inline-start: 1.25rem;
80
+ }
81
+
82
+ .agentic-message-response :where(ul) {
83
+ list-style: disc;
84
+ }
85
+
86
+ .agentic-message-response :where(ol) {
87
+ list-style: decimal;
88
+ }
89
+
90
+ .agentic-message-response :where(li) {
91
+ margin-block: 0.25rem;
92
+ padding-inline-start: 0.125rem;
93
+ }
94
+
95
+ .agentic-message-response :where(a) {
96
+ color: var(--foreground);
97
+ text-decoration-color: color-mix(in oklch, var(--foreground) 36%, transparent);
98
+ text-decoration-line: underline;
99
+ text-underline-offset: 0.18em;
100
+ }
101
+
102
+ .agentic-message-response :where(a:hover) {
103
+ text-decoration-color: var(--foreground);
104
+ }
105
+
106
+ .agentic-message-response :where(strong) {
107
+ font-weight: var(--font-ciridae-strong-weight);
108
+ }
109
+
110
+ .agentic-message-response :where(hr) {
111
+ border: 0;
112
+ border-block-start: 1px solid var(--border);
113
+ margin-block: 1rem;
114
+ }
115
+
116
+ .agentic-message-response :where(blockquote) {
117
+ border-inline-start: 2px solid var(--border);
118
+ color: var(--muted-foreground);
119
+ font-style: normal;
120
+ margin-block: 1rem;
121
+ padding-inline-start: 0.875rem;
122
+ }
123
+
124
+ .agentic-message-response :where(code),
125
+ .agentic-message-response :where(kbd),
126
+ .agentic-message-response :where(pre) {
127
+ font-family: var(--font-ciridae-mono);
128
+ font-variant-numeric: tabular-nums;
129
+ }
130
+
131
+ .agentic-message-response :where(:not(pre) > code),
132
+ .agentic-message-response [data-streamdown="inline-code"] {
133
+ background: var(--muted);
134
+ border: 1px solid color-mix(in oklch, var(--border) 72%, transparent);
135
+ border-radius: var(--radius-sm);
136
+ color: var(--foreground);
137
+ font-size: 0.8125rem;
138
+ padding: 0.0625rem 0.3125rem;
139
+ }
140
+
141
+ .agentic-message-response [data-streamdown="code-block"],
142
+ .agentic-message-response [data-streamdown="mermaid-block"] {
143
+ background: color-mix(in oklch, var(--muted) 52%, transparent);
144
+ border: 1px solid var(--border);
145
+ border-radius: var(--radius-lg);
146
+ box-shadow: var(--shadow-xs);
147
+ margin-block: 1rem;
148
+ max-width: 100%;
149
+ overflow: hidden;
150
+ padding: 0.5rem;
151
+ }
152
+
153
+ .agentic-message-response [data-streamdown="code-block-header"] {
154
+ color: var(--muted-foreground);
155
+ font-size: 0.75rem;
156
+ height: 1.75rem;
157
+ line-height: 1.75rem;
158
+ }
159
+
160
+ .agentic-message-response [data-streamdown="code-block-body"] {
161
+ background: var(--background);
162
+ border: 1px solid color-mix(in oklch, var(--border) 72%, transparent);
163
+ border-radius: var(--radius-md);
164
+ font-size: 0.8125rem;
165
+ line-height: 1.55;
166
+ overflow-x: auto;
167
+ padding: 0.875rem;
168
+ }
169
+
170
+ .agentic-message-response [data-streamdown="code-block-body"] pre {
171
+ background: transparent;
172
+ margin: 0;
173
+ }
174
+
175
+ .agentic-message-response [data-streamdown="code-block-actions"],
176
+ .agentic-message-response [data-streamdown="mermaid-block-actions"] {
177
+ align-items: center;
178
+ background: color-mix(in oklch, var(--background) 88%, transparent);
179
+ border: 1px solid var(--border);
180
+ border-radius: var(--radius-md);
181
+ gap: 0.125rem;
182
+ min-height: 1.75rem;
183
+ padding: 0.125rem;
184
+ transform: translateY(-0.625rem);
185
+ }
186
+
187
+ .agentic-message-response [data-streamdown="code-block-copy-button"],
188
+ .agentic-message-response [data-streamdown="code-block-download-button"],
189
+ .agentic-message-response [data-streamdown="table-copy-button"],
190
+ .agentic-message-response [data-streamdown="table-download-button"],
191
+ .agentic-message-response [data-streamdown="mermaid-copy-button"],
192
+ .agentic-message-response [data-streamdown="mermaid-download-button"] {
193
+ align-items: center;
194
+ color: var(--muted-foreground);
195
+ display: inline-flex;
196
+ height: 1.5rem;
197
+ justify-content: center;
198
+ transition:
199
+ background-color var(--motion-duration-fast) var(--motion-ease-standard),
200
+ color var(--motion-duration-fast) var(--motion-ease-standard);
201
+ width: 1.5rem;
202
+ }
203
+
204
+ .agentic-message-response [data-streamdown="code-block-copy-button"]:hover,
205
+ .agentic-message-response [data-streamdown="code-block-download-button"]:hover,
206
+ .agentic-message-response [data-streamdown="table-copy-button"]:hover,
207
+ .agentic-message-response [data-streamdown="table-download-button"]:hover,
208
+ .agentic-message-response [data-streamdown="mermaid-copy-button"]:hover,
209
+ .agentic-message-response [data-streamdown="mermaid-download-button"]:hover {
210
+ background: var(--accent);
211
+ color: var(--accent-foreground);
212
+ }
213
+
214
+ .agentic-message-response :where(table) {
215
+ border: 1px solid var(--border);
216
+ border-collapse: separate;
217
+ border-radius: var(--radius-md);
218
+ border-spacing: 0;
219
+ display: block;
220
+ margin-block: 1rem;
221
+ max-width: 100%;
222
+ overflow-x: auto;
223
+ width: max-content;
224
+ }
225
+
226
+ .agentic-message-response :where(thead) {
227
+ background: var(--muted);
228
+ color: var(--table-header-foreground);
229
+ }
230
+
231
+ .agentic-message-response :where(th, td) {
232
+ border-block-end: 1px solid var(--border);
233
+ font-size: 0.8125rem;
234
+ padding: 0.5rem 0.625rem;
235
+ text-align: start;
236
+ vertical-align: top;
237
+ }
238
+
239
+ .agentic-message-response :where(th) {
240
+ font-weight: var(--font-ciridae-metadata-weight);
241
+ }
242
+
243
+ .agentic-message-response :where(tr:last-child td) {
244
+ border-block-end: 0;
245
+ }
246
+
247
+ .agentic-message-response :where(.katex-display) {
248
+ overflow-x: auto;
249
+ overflow-y: hidden;
250
+ padding-block: 0.25rem;
251
+ }
252
+
253
+ .agentic-message-response [data-streamdown="mermaid"] {
254
+ background: var(--background);
255
+ border: 1px solid color-mix(in oklch, var(--border) 72%, transparent);
256
+ border-radius: var(--radius-md);
257
+ color: var(--foreground);
258
+ padding: 1rem;
259
+ }
260
+
261
+ @media (prefers-reduced-motion: reduce) {
262
+ .agentic-message-response [data-sd-animate] {
263
+ animation: none !important;
264
+ }
265
+ }
@@ -0,0 +1,2 @@
1
+ declare const stylesheet: string;
2
+ export default stylesheet;
@@ -0,0 +1,27 @@
1
+ import type * as React from "react";
2
+ import { Streamdown } from "streamdown";
3
+ import { MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, type MessageBranchContentProps, type MessageBranchNextProps, type MessageBranchPageProps, type MessageBranchPreviousProps, type MessageBranchProps, type MessageBranchSelectorProps } from "@ciridae/ui/message-branch";
4
+ import type { AgenticMessageRole } from "@ciridae/ui/types";
5
+ import "@ciridae/ui/message-response.css";
6
+ import { Button } from "@ciridae/ui/button";
7
+ type MessageProps = React.ComponentProps<"div"> & {
8
+ role: AgenticMessageRole;
9
+ };
10
+ type MessageContentProps = React.ComponentProps<"div"> & {
11
+ variant?: "default" | "bubble";
12
+ };
13
+ type MessageActionsProps = React.ComponentProps<"div">;
14
+ type MessageActionProps = React.ComponentProps<typeof Button> & {
15
+ label?: string;
16
+ tooltip?: string;
17
+ };
18
+ type MessageToolbarProps = React.ComponentProps<"div">;
19
+ type MessageResponseProps = React.ComponentProps<typeof Streamdown>;
20
+ declare function Message({ className, role, ...props }: MessageProps): import("react/jsx-runtime").JSX.Element;
21
+ declare function MessageContent({ className, variant, ...props }: MessageContentProps): import("react/jsx-runtime").JSX.Element;
22
+ declare function MessageActions({ className, ...props }: MessageActionsProps): import("react/jsx-runtime").JSX.Element;
23
+ declare function MessageAction({ children, label, tooltip, variant, size, ...props }: MessageActionProps): import("react/jsx-runtime").JSX.Element;
24
+ declare const MessageResponse: React.MemoExoticComponent<({ animated, className, plugins, ...props }: MessageResponseProps) => import("react/jsx-runtime").JSX.Element>;
25
+ declare function MessageToolbar({ className, ...props }: MessageToolbarProps): import("react/jsx-runtime").JSX.Element;
26
+ export { Message, MessageAction, MessageActions, MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, MessageContent, MessageResponse, MessageToolbar, };
27
+ export type { MessageActionProps, MessageActionsProps, MessageBranchContentProps, MessageBranchNextProps, MessageBranchPageProps, MessageBranchPreviousProps, MessageBranchProps, MessageBranchSelectorProps, MessageContentProps, MessageProps, MessageResponseProps, MessageToolbarProps, };
@@ -0,0 +1,57 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cjk } from "@streamdown/cjk";
3
+ import { code } from "@streamdown/code";
4
+ import { math } from "@streamdown/math";
5
+ import { mermaid } from "@streamdown/mermaid";
6
+ import { memo, useEffect, useState } from "react";
7
+ import { Streamdown } from "streamdown";
8
+ import { MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, } from "@ciridae/ui/message-branch";
9
+ import "@ciridae/ui/message-response.css";
10
+ import { Button } from "@ciridae/ui/button";
11
+ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@ciridae/ui/tooltip";
12
+ import { cn } from "@ciridae/ui/utils";
13
+ const streamdownPlugins = { cjk, code, math, mermaid };
14
+ const messageResponseAnimation = {
15
+ animation: "fade-in",
16
+ duration: 200,
17
+ easing: "var(--motion-ease-standard)",
18
+ sep: "word",
19
+ };
20
+ function Message({ className, role, ...props }) {
21
+ return (_jsx("div", { "data-role": role, "data-slot": "message", className: cn("group/message flex w-full flex-col gap-2", role === "user" ? "items-end" : "items-start", role === "system" ? "py-1" : undefined, className), ...props }));
22
+ }
23
+ function MessageContent({ className, variant = "default", ...props }) {
24
+ return (_jsx("div", { "data-slot": "message-content", "data-variant": variant, className: cn("min-w-0 max-w-[min(42rem,100%)] text-sm leading-relaxed", "data-[variant=bubble]:rounded-lg data-[variant=bubble]:border data-[variant=bubble]:bg-card data-[variant=bubble]:px-4 data-[variant=bubble]:py-3 data-[variant=bubble]:text-card-foreground data-[variant=bubble]:shadow-xs", "group-data-[role=user]/message:max-w-[min(34rem,78%)] group-data-[role=user]/message:rounded-lg group-data-[role=user]/message:border group-data-[role=user]/message:bg-secondary group-data-[role=user]/message:px-4 group-data-[role=user]/message:py-3 group-data-[role=user]/message:text-secondary-foreground group-data-[role=user]/message:shadow-xs", "group-data-[role=assistant]/message:text-foreground", "group-data-[role=system]/message:max-w-full group-data-[role=system]/message:rounded-md group-data-[role=system]/message:border group-data-[role=system]/message:bg-muted/30 group-data-[role=system]/message:px-3 group-data-[role=system]/message:py-2 group-data-[role=system]/message:text-xs group-data-[role=system]/message:text-muted-foreground", className), ...props }));
25
+ }
26
+ function MessageActions({ className, ...props }) {
27
+ return (_jsx("div", { "data-slot": "message-actions", className: cn("flex items-center gap-1", className), ...props }));
28
+ }
29
+ function MessageAction({ children, label, tooltip, variant = "ghost", size = "icon-sm", ...props }) {
30
+ const accessibleLabel = props["aria-label"] ?? label ?? tooltip;
31
+ const button = (_jsxs(Button, { "aria-label": accessibleLabel, size: size, type: "button", variant: variant, ...props, children: [children, label || tooltip ? _jsx("span", { className: "sr-only", children: label ?? tooltip }) : null] }));
32
+ if (!tooltip)
33
+ return button;
34
+ return (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: button }), _jsx(TooltipContent, { children: _jsx("p", { children: tooltip }) })] }) }));
35
+ }
36
+ const MessageResponse = memo(function MessageResponse({ animated, className, plugins, ...props }) {
37
+ const prefersReducedMotion = usePrefersReducedMotion();
38
+ const resolvedAnimation = animated === true ? messageResponseAnimation : animated;
39
+ return (_jsx(Streamdown, { animated: prefersReducedMotion ? false : resolvedAnimation, className: cn("agentic-message-response", className), plugins: { ...streamdownPlugins, ...plugins }, ...props }));
40
+ });
41
+ MessageResponse.displayName = "MessageResponse";
42
+ function usePrefersReducedMotion() {
43
+ const [prefersReducedMotion, setPrefersReducedMotion] = useState(() => typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches);
44
+ useEffect(() => {
45
+ if (typeof window === "undefined")
46
+ return;
47
+ const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
48
+ const handleChange = (event) => setPrefersReducedMotion(event.matches);
49
+ mediaQuery.addEventListener("change", handleChange);
50
+ return () => mediaQuery.removeEventListener("change", handleChange);
51
+ }, []);
52
+ return prefersReducedMotion;
53
+ }
54
+ function MessageToolbar({ className, ...props }) {
55
+ return (_jsx("div", { "data-slot": "message-toolbar", className: cn("mt-1 flex w-full max-w-[min(42rem,100%)] items-center justify-between gap-3", "group-data-[role=user]/message:ml-auto group-data-[role=system]/message:max-w-full", className), ...props }));
56
+ }
57
+ export { Message, MessageAction, MessageActions, MessageBranch, MessageBranchContent, MessageBranchNext, MessageBranchPage, MessageBranchPrevious, MessageBranchSelector, MessageContent, MessageResponse, MessageToolbar, };
@@ -0,0 +1,58 @@
1
+ import * as React from "react";
2
+ import type { AgenticMicOption } from "@ciridae/ui/types";
3
+ import { CommandEmpty, CommandInput, CommandItem, CommandList } from "@ciridae/ui/command";
4
+ import { Popover, PopoverContent, PopoverTrigger } from "@ciridae/ui/popover";
5
+ type MicSelectorContextValue = {
6
+ data: AgenticMicOption[];
7
+ open: boolean;
8
+ setOpen: (open: boolean) => void;
9
+ setValue: (value: string | undefined) => void;
10
+ setWidth: (width: number) => void;
11
+ value: string | undefined;
12
+ width: number;
13
+ };
14
+ type MicSelectorProps = React.ComponentProps<typeof Popover> & {
15
+ defaultValue?: string;
16
+ mics?: AgenticMicOption[];
17
+ onValueChange?: (value: string | undefined) => void;
18
+ value?: string;
19
+ };
20
+ type MicSelectorTriggerProps = React.ComponentProps<typeof PopoverTrigger>;
21
+ type MicSelectorContentProps = React.ComponentProps<typeof PopoverContent> & {
22
+ popoverOptions?: React.ComponentProps<typeof PopoverContent>;
23
+ };
24
+ type MicSelectorInputProps = React.ComponentProps<typeof CommandInput>;
25
+ type MicSelectorListProps = Omit<React.ComponentProps<typeof CommandList>, "children"> & {
26
+ children: (mics: AgenticMicOption[]) => React.ReactNode;
27
+ };
28
+ type MicSelectorEmptyProps = React.ComponentProps<typeof CommandEmpty>;
29
+ type MicSelectorItemProps = React.ComponentProps<typeof CommandItem> & {
30
+ mic?: AgenticMicOption;
31
+ };
32
+ type MicSelectorLabelProps = React.ComponentProps<"span"> & {
33
+ mic: AgenticMicOption;
34
+ };
35
+ type MicSelectorValueProps = React.ComponentProps<"span"> & {
36
+ placeholder?: string;
37
+ };
38
+ declare function MicSelector({ children, defaultOpen, defaultValue, mics, onOpenChange, onValueChange, open: openProp, value: valueProp, ...props }: MicSelectorProps): import("react/jsx-runtime").JSX.Element;
39
+ declare function useMicSelector(): MicSelectorContextValue;
40
+ declare function useAudioDevices({ enabled }?: {
41
+ enabled?: boolean;
42
+ }): {
43
+ devices: AgenticMicOption[];
44
+ error: string | null;
45
+ hasPermission: boolean;
46
+ loadDevices: () => Promise<void>;
47
+ loading: boolean;
48
+ };
49
+ declare function MicSelectorTrigger({ children, ...props }: MicSelectorTriggerProps): import("react/jsx-runtime").JSX.Element;
50
+ declare function MicSelectorContent({ className, popoverOptions, style, ...props }: MicSelectorContentProps): import("react/jsx-runtime").JSX.Element;
51
+ declare function MicSelectorInput(props: MicSelectorInputProps): import("react/jsx-runtime").JSX.Element;
52
+ declare function MicSelectorList({ children, ...props }: MicSelectorListProps): import("react/jsx-runtime").JSX.Element;
53
+ declare function MicSelectorEmpty({ children, ...props }: MicSelectorEmptyProps): import("react/jsx-runtime").JSX.Element;
54
+ declare function MicSelectorItem({ children, mic, onSelect, value, ...props }: MicSelectorItemProps): import("react/jsx-runtime").JSX.Element;
55
+ declare function MicSelectorLabel({ className, mic, ...props }: MicSelectorLabelProps): import("react/jsx-runtime").JSX.Element;
56
+ declare function MicSelectorValue({ className, placeholder, ...props }: MicSelectorValueProps): import("react/jsx-runtime").JSX.Element;
57
+ export { MicSelector, MicSelectorContent, MicSelectorEmpty, MicSelectorInput, MicSelectorItem, MicSelectorLabel, MicSelectorList, MicSelectorTrigger, MicSelectorValue, useAudioDevices, useMicSelector, };
58
+ export type { MicSelectorContentProps, MicSelectorEmptyProps, MicSelectorInputProps, MicSelectorItemProps, MicSelectorLabelProps, MicSelectorListProps, MicSelectorProps, MicSelectorTriggerProps, MicSelectorValueProps, };
@@ -0,0 +1,173 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /* eslint-disable max-lines, react-refresh/only-export-components */
3
+ import { ChevronsUpDownIcon } from "lucide-react";
4
+ import * as React from "react";
5
+ import { Button } from "@ciridae/ui/button";
6
+ import { Command, CommandEmpty, CommandInput, CommandItem, CommandList, } from "@ciridae/ui/command";
7
+ import { Popover, PopoverContent, PopoverTrigger } from "@ciridae/ui/popover";
8
+ import { cn } from "@ciridae/ui/utils";
9
+ import { useControllableState } from "./use-controllable-state";
10
+ const deviceIdRegex = /\(([\da-fA-F]{4}:[\da-fA-F]{4})\)$/;
11
+ const MicSelectorContext = React.createContext(null);
12
+ function MicSelector({ children, defaultOpen = false, defaultValue, mics, onOpenChange, onValueChange, open: openProp, value: valueProp, ...props }) {
13
+ const [value, setValue] = useControllableState({
14
+ defaultValue,
15
+ onChange: onValueChange,
16
+ value: valueProp,
17
+ });
18
+ const [open, setOpen] = useControllableState({
19
+ defaultValue: defaultOpen,
20
+ onChange: onOpenChange,
21
+ value: openProp,
22
+ });
23
+ const [width, setWidth] = React.useState(200);
24
+ const audioDevices = useAudioDevices({ enabled: !mics });
25
+ const { devices: detectedMics, hasPermission, loadDevices, loading: devicesLoading, } = audioDevices;
26
+ const attemptedPermissionRef = React.useRef(false);
27
+ React.useEffect(() => {
28
+ if (open && !mics && !hasPermission && !devicesLoading && !attemptedPermissionRef.current) {
29
+ attemptedPermissionRef.current = true;
30
+ void loadDevices();
31
+ }
32
+ }, [devicesLoading, hasPermission, loadDevices, mics, open]);
33
+ React.useEffect(() => {
34
+ if (!open)
35
+ attemptedPermissionRef.current = false;
36
+ }, [open]);
37
+ const contextValue = React.useMemo(() => ({
38
+ data: mics ?? detectedMics,
39
+ open,
40
+ setOpen,
41
+ setValue,
42
+ setWidth,
43
+ value,
44
+ width,
45
+ }), [detectedMics, mics, open, setOpen, setValue, value, width]);
46
+ return (_jsx(MicSelectorContext.Provider, { value: contextValue, children: _jsx(Popover, { onOpenChange: setOpen, open: open, ...props, children: children ?? _jsx(MicSelectorDefaultContent, {}) }) }));
47
+ }
48
+ function MicSelectorDefaultContent() {
49
+ return (_jsxs(_Fragment, { children: [_jsx(MicSelectorTrigger, { asChild: true, children: _jsxs(Button, { className: "w-64 justify-between", variant: "outline", children: [_jsx(MicSelectorValue, { className: "max-w-52 text-left" }), _jsx(ChevronsUpDownIcon, { className: "size-4 opacity-60" })] }) }), _jsxs(MicSelectorContent, { children: [_jsx(MicSelectorInput, { placeholder: "Search microphones..." }), _jsx(MicSelectorList, { children: (devices) => (_jsxs(_Fragment, { children: [_jsx(MicSelectorEmpty, { children: "No microphone found." }), devices.map((mic) => (_jsx(MicSelectorItem, { mic: mic }, mic.id)))] })) })] })] }));
50
+ }
51
+ function useMicSelector() {
52
+ const context = React.useContext(MicSelectorContext);
53
+ if (!context)
54
+ throw new Error("MicSelector components must be used within MicSelector");
55
+ return context;
56
+ }
57
+ function useAudioDevices({ enabled = true } = {}) {
58
+ const [devices, setDevices] = React.useState([]);
59
+ const [error, setError] = React.useState(null);
60
+ const [hasPermission, setHasPermission] = React.useState(false);
61
+ const [loading, setLoading] = React.useState(false);
62
+ const loadDevicesWithoutPermission = React.useCallback(async () => {
63
+ if (!enabled || !navigator.mediaDevices?.enumerateDevices)
64
+ return;
65
+ try {
66
+ setLoading(true);
67
+ setError(null);
68
+ const deviceList = await navigator.mediaDevices.enumerateDevices();
69
+ setDevices(deviceList.filter(isAudioInput).map(mediaDeviceToMicOption));
70
+ }
71
+ catch (caughtError) {
72
+ setError(caughtError instanceof Error ? caughtError.message : "Failed to get audio devices");
73
+ }
74
+ finally {
75
+ setLoading(false);
76
+ }
77
+ }, [enabled]);
78
+ const loadDevices = React.useCallback(async () => {
79
+ if (!enabled || !navigator.mediaDevices?.getUserMedia)
80
+ return;
81
+ try {
82
+ setLoading(true);
83
+ setError(null);
84
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
85
+ for (const track of stream.getTracks())
86
+ track.stop();
87
+ const deviceList = await navigator.mediaDevices.enumerateDevices();
88
+ setDevices(deviceList.filter(isAudioInput).map(mediaDeviceToMicOption));
89
+ setHasPermission(true);
90
+ }
91
+ catch (caughtError) {
92
+ setError(caughtError instanceof Error ? caughtError.message : "Failed to get audio devices");
93
+ }
94
+ finally {
95
+ setLoading(false);
96
+ }
97
+ }, [enabled]);
98
+ React.useEffect(() => {
99
+ void loadDevicesWithoutPermission();
100
+ }, [loadDevicesWithoutPermission]);
101
+ React.useEffect(() => {
102
+ if (!enabled || !navigator.mediaDevices?.addEventListener)
103
+ return;
104
+ const handleDeviceChange = () => {
105
+ void (hasPermission ? loadDevices() : loadDevicesWithoutPermission());
106
+ };
107
+ navigator.mediaDevices.addEventListener("devicechange", handleDeviceChange);
108
+ return () => navigator.mediaDevices.removeEventListener("devicechange", handleDeviceChange);
109
+ }, [enabled, hasPermission, loadDevices, loadDevicesWithoutPermission]);
110
+ return { devices, error, hasPermission, loadDevices, loading };
111
+ }
112
+ function MicSelectorTrigger({ children, ...props }) {
113
+ const { setWidth } = useMicSelector();
114
+ const ref = React.useRef(null);
115
+ React.useEffect(() => {
116
+ if (!ref.current)
117
+ return;
118
+ const resizeObserver = new ResizeObserver(([entry]) => {
119
+ if (entry?.target instanceof HTMLElement)
120
+ setWidth(entry.target.offsetWidth);
121
+ });
122
+ resizeObserver.observe(ref.current);
123
+ return () => resizeObserver.disconnect();
124
+ }, [setWidth]);
125
+ return (_jsx(PopoverTrigger, { ref: ref, ...props, children: children }));
126
+ }
127
+ function MicSelectorContent({ className, popoverOptions, style, ...props }) {
128
+ const { width } = useMicSelector();
129
+ const { className: popoverClassName, style: popoverStyle, ...popoverContentOptions } = popoverOptions ?? {};
130
+ return (_jsx(PopoverContent, { align: "start", ...popoverContentOptions, ...props, className: cn("p-0", popoverClassName, className), style: { ...popoverStyle, ...style, width }, children: _jsx(Command, { children: props.children }) }));
131
+ }
132
+ function MicSelectorInput(props) {
133
+ return _jsx(CommandInput, { ...props });
134
+ }
135
+ function MicSelectorList({ children, ...props }) {
136
+ const { data } = useMicSelector();
137
+ return _jsx(CommandList, { ...props, children: children(data) });
138
+ }
139
+ function MicSelectorEmpty({ children = "No microphone found.", ...props }) {
140
+ return _jsx(CommandEmpty, { ...props, children: children });
141
+ }
142
+ function MicSelectorItem({ children, mic, onSelect, value, ...props }) {
143
+ const { setOpen, setValue } = useMicSelector();
144
+ const itemValue = value ?? mic?.id;
145
+ return (_jsx(CommandItem, { onSelect: (currentValue) => {
146
+ setValue(itemValue ?? currentValue);
147
+ setOpen(false);
148
+ onSelect?.(currentValue);
149
+ }, value: itemValue, ...props, children: children ?? (mic ? _jsx(MicSelectorLabel, { mic: mic }) : null) }));
150
+ }
151
+ function MicSelectorLabel({ className, mic, ...props }) {
152
+ const matches = mic.label.match(deviceIdRegex);
153
+ const deviceId = matches?.[1];
154
+ const name = deviceId ? mic.label.replace(deviceIdRegex, "").trim() : mic.label;
155
+ return (_jsxs("span", { className: cn("grid min-w-0 gap-0.5", className), ...props, children: [_jsx("span", { className: "truncate", children: name }), _jsx("span", { className: "truncate text-xs text-muted-foreground", children: mic.description ?? (deviceId ? `Device ${deviceId}` : "Audio input") })] }));
156
+ }
157
+ function MicSelectorValue({ className, placeholder = "Select microphone...", ...props }) {
158
+ const { data, value } = useMicSelector();
159
+ const currentDevice = data.find((device) => device.id === value);
160
+ return (_jsx("span", { className: cn("truncate", className), ...props, children: currentDevice?.label ?? placeholder }));
161
+ }
162
+ function isAudioInput(device) {
163
+ return device.kind === "audioinput";
164
+ }
165
+ function mediaDeviceToMicOption(device) {
166
+ return {
167
+ description: device.groupId ? `Group ${device.groupId.slice(0, 8)}` : undefined,
168
+ id: device.deviceId,
169
+ label: device.label || "Microphone",
170
+ mediaType: device.kind,
171
+ };
172
+ }
173
+ export { MicSelector, MicSelectorContent, MicSelectorEmpty, MicSelectorInput, MicSelectorItem, MicSelectorLabel, MicSelectorList, MicSelectorTrigger, MicSelectorValue, useAudioDevices, useMicSelector, };
@@ -0,0 +1,39 @@
1
+ import type * as React from "react";
2
+ import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from "@ciridae/ui/command";
3
+ import { Dialog, DialogContent, DialogTrigger } from "@ciridae/ui/dialog";
4
+ type ModelSelectorProps = React.ComponentProps<typeof Dialog>;
5
+ type ModelSelectorTriggerProps = React.ComponentProps<typeof DialogTrigger>;
6
+ type ModelSelectorContentProps = React.ComponentProps<typeof DialogContent> & {
7
+ title?: React.ReactNode;
8
+ };
9
+ type ModelSelectorDialogProps = React.ComponentProps<typeof CommandDialog>;
10
+ type ModelSelectorInputProps = React.ComponentProps<typeof CommandInput>;
11
+ type ModelSelectorListProps = React.ComponentProps<typeof CommandList>;
12
+ type ModelSelectorEmptyProps = React.ComponentProps<typeof CommandEmpty>;
13
+ type ModelSelectorGroupProps = React.ComponentProps<typeof CommandGroup>;
14
+ type ModelSelectorItemProps = React.ComponentProps<typeof CommandItem>;
15
+ type ModelSelectorShortcutProps = React.ComponentProps<typeof CommandShortcut>;
16
+ type ModelSelectorSeparatorProps = React.ComponentProps<typeof CommandSeparator>;
17
+ type ModelSelectorLogoProps = Omit<React.ComponentProps<"img">, "alt" | "src"> & {
18
+ alt?: string;
19
+ provider: string;
20
+ src?: string;
21
+ };
22
+ type ModelSelectorLogoGroupProps = React.ComponentProps<"div">;
23
+ type ModelSelectorNameProps = React.ComponentProps<"span">;
24
+ declare function ModelSelector(props: ModelSelectorProps): import("react/jsx-runtime").JSX.Element;
25
+ declare function ModelSelectorTrigger(props: ModelSelectorTriggerProps): import("react/jsx-runtime").JSX.Element;
26
+ declare function ModelSelectorContent({ children, className, title, ...props }: ModelSelectorContentProps): import("react/jsx-runtime").JSX.Element;
27
+ declare function ModelSelectorDialog(props: ModelSelectorDialogProps): import("react/jsx-runtime").JSX.Element;
28
+ declare function ModelSelectorInput({ className, ...props }: ModelSelectorInputProps): import("react/jsx-runtime").JSX.Element;
29
+ declare function ModelSelectorList(props: ModelSelectorListProps): import("react/jsx-runtime").JSX.Element;
30
+ declare function ModelSelectorEmpty(props: ModelSelectorEmptyProps): import("react/jsx-runtime").JSX.Element;
31
+ declare function ModelSelectorGroup(props: ModelSelectorGroupProps): import("react/jsx-runtime").JSX.Element;
32
+ declare function ModelSelectorItem(props: ModelSelectorItemProps): import("react/jsx-runtime").JSX.Element;
33
+ declare function ModelSelectorShortcut(props: ModelSelectorShortcutProps): import("react/jsx-runtime").JSX.Element;
34
+ declare function ModelSelectorSeparator(props: ModelSelectorSeparatorProps): import("react/jsx-runtime").JSX.Element;
35
+ declare function ModelSelectorLogo({ alt, className, provider, src, ...props }: ModelSelectorLogoProps): import("react/jsx-runtime").JSX.Element;
36
+ declare function ModelSelectorLogoGroup({ className, ...props }: ModelSelectorLogoGroupProps): import("react/jsx-runtime").JSX.Element;
37
+ declare function ModelSelectorName({ className, ...props }: ModelSelectorNameProps): import("react/jsx-runtime").JSX.Element;
38
+ export { ModelSelector, ModelSelectorContent, ModelSelectorDialog, ModelSelectorEmpty, ModelSelectorGroup, ModelSelectorInput, ModelSelectorItem, ModelSelectorList, ModelSelectorLogo, ModelSelectorLogoGroup, ModelSelectorName, ModelSelectorSeparator, ModelSelectorShortcut, ModelSelectorTrigger, };
39
+ export type { ModelSelectorContentProps, ModelSelectorDialogProps, ModelSelectorEmptyProps, ModelSelectorGroupProps, ModelSelectorInputProps, ModelSelectorItemProps, ModelSelectorListProps, ModelSelectorLogoGroupProps, ModelSelectorLogoProps, ModelSelectorNameProps, ModelSelectorProps, ModelSelectorSeparatorProps, ModelSelectorShortcutProps, ModelSelectorTriggerProps, };