@mastra/playground-ui 41.1.0-alpha.2 → 42.0.0-alpha.13

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 (275) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/dist/Card-BjFMX3pD.js +96 -0
  3. package/dist/Card-BjFMX3pD.js.map +1 -0
  4. package/dist/Card-WU2qkiHB.cjs +123 -0
  5. package/dist/Card-WU2qkiHB.cjs.map +1 -0
  6. package/dist/{Txt-p33XTnu8.js → Txt-Df42XG5p.js} +3 -3
  7. package/dist/Txt-Df42XG5p.js.map +1 -0
  8. package/dist/{Txt-BT8_EkuZ.cjs → Txt-I5lK8zy7.cjs} +3 -3
  9. package/dist/Txt-I5lK8zy7.cjs.map +1 -0
  10. package/dist/{buttons-group-b6an6uao.js → buttons-group-DJh4wnMs.js} +4 -4
  11. package/dist/{buttons-group-b6an6uao.js.map → buttons-group-DJh4wnMs.js.map} +1 -1
  12. package/dist/{buttons-group-C0fJastT.cjs → buttons-group-Dw8Wu4sj.cjs} +4 -4
  13. package/dist/{buttons-group-C0fJastT.cjs.map → buttons-group-Dw8Wu4sj.cjs.map} +1 -1
  14. package/dist/components/Avatar.cjs.js +1 -1
  15. package/dist/components/Avatar.es.js +1 -1
  16. package/dist/components/Breadcrumb.cjs.js +2 -2
  17. package/dist/components/Breadcrumb.cjs.js.map +1 -1
  18. package/dist/components/Breadcrumb.es.js +2 -2
  19. package/dist/components/Breadcrumb.es.js.map +1 -1
  20. package/dist/components/ButtonsGroup.cjs.js +1 -1
  21. package/dist/components/ButtonsGroup.es.js +1 -1
  22. package/dist/components/Card.cjs.js +8 -84
  23. package/dist/components/Card.cjs.js.map +1 -1
  24. package/dist/components/Card.es.js +1 -63
  25. package/dist/components/Card.es.js.map +1 -1
  26. package/dist/components/ClampedText.cjs.js +51 -0
  27. package/dist/components/ClampedText.cjs.js.map +1 -0
  28. package/dist/components/ClampedText.d.ts +2 -0
  29. package/dist/components/ClampedText.es.js +47 -0
  30. package/dist/components/ClampedText.es.js.map +1 -0
  31. package/dist/components/Composer.cjs.js +2 -2
  32. package/dist/components/Composer.cjs.js.map +1 -1
  33. package/dist/components/Composer.es.js +2 -2
  34. package/dist/components/Composer.es.js.map +1 -1
  35. package/dist/components/ContentBlocks.cjs.js.map +1 -1
  36. package/dist/components/ContentBlocks.es.js.map +1 -1
  37. package/dist/components/DataCodeSection.cjs.js +1 -1
  38. package/dist/components/DataCodeSection.es.js +1 -1
  39. package/dist/components/DataDetailsPanel.cjs.js +4 -4
  40. package/dist/components/DataDetailsPanel.cjs.js.map +1 -1
  41. package/dist/components/DataDetailsPanel.es.js +4 -4
  42. package/dist/components/DataDetailsPanel.es.js.map +1 -1
  43. package/dist/components/DataPanel.cjs.js +1 -1
  44. package/dist/components/DataPanel.es.js +1 -1
  45. package/dist/components/DateTimePicker.cjs.js +1 -1
  46. package/dist/components/DateTimePicker.es.js +1 -1
  47. package/dist/components/Drawer.cjs.js +1 -1
  48. package/dist/components/Drawer.es.js +1 -1
  49. package/dist/components/Entity.cjs.js +1 -1
  50. package/dist/components/Entity.es.js +1 -1
  51. package/dist/components/EntityHeader.cjs.js +1 -1
  52. package/dist/components/EntityHeader.es.js +1 -1
  53. package/dist/components/Entry.cjs.js +1 -1
  54. package/dist/components/Entry.es.js +1 -1
  55. package/dist/components/EnvironmentVariablesEditor.cjs.js +2 -2
  56. package/dist/components/EnvironmentVariablesEditor.es.js +2 -2
  57. package/dist/components/FormFieldBlocks.cjs.js +4 -4
  58. package/dist/components/FormFieldBlocks.es.js +4 -4
  59. package/dist/components/Header.cjs.js +1 -1
  60. package/dist/components/Header.es.js +1 -1
  61. package/dist/components/JSONSchemaForm.cjs.js +2 -2
  62. package/dist/components/JSONSchemaForm.es.js +2 -2
  63. package/dist/components/ListSearch.cjs.js +1 -1
  64. package/dist/components/ListSearch.es.js +1 -1
  65. package/dist/components/MainContent.cjs.js +3 -3
  66. package/dist/components/MainContent.cjs.js.map +1 -1
  67. package/dist/components/MainContent.es.js +3 -3
  68. package/dist/components/MainContent.es.js.map +1 -1
  69. package/dist/components/MainSidebar.cjs.js +1 -1
  70. package/dist/components/MainSidebar.es.js +1 -1
  71. package/dist/components/PrevNextNav.cjs.js +1 -1
  72. package/dist/components/PrevNextNav.es.js +1 -1
  73. package/dist/components/PropertyFilter.cjs.js +1 -1
  74. package/dist/components/PropertyFilter.es.js +2 -2
  75. package/dist/components/SankeyChart.cjs.js +68 -75
  76. package/dist/components/SankeyChart.cjs.js.map +1 -1
  77. package/dist/components/SankeyChart.es.js +60 -71
  78. package/dist/components/SankeyChart.es.js.map +1 -1
  79. package/dist/components/SideDialog.cjs.js +2 -2
  80. package/dist/components/SideDialog.es.js +2 -2
  81. package/dist/components/Table.cjs.js +1 -1
  82. package/dist/components/Table.es.js +1 -1
  83. package/dist/components/ThreadList.cjs.js +1 -1
  84. package/dist/components/ThreadList.es.js +1 -1
  85. package/dist/components/Toaster.cjs.js +1 -0
  86. package/dist/components/Toaster.cjs.js.map +1 -1
  87. package/dist/components/Toaster.es.js +1 -1
  88. package/dist/components/Truncate.cjs.js +1 -1
  89. package/dist/components/Truncate.es.js +1 -1
  90. package/dist/components/Txt.cjs.js +1 -1
  91. package/dist/components/Txt.es.js +1 -1
  92. package/dist/components/ai/ask-user.cjs.js +147 -0
  93. package/dist/components/ai/ask-user.cjs.js.map +1 -0
  94. package/dist/components/ai/ask-user.d.ts +2 -0
  95. package/dist/components/ai/ask-user.es.js +136 -0
  96. package/dist/components/ai/ask-user.es.js.map +1 -0
  97. package/dist/components/ai/plan.cjs.js +1 -1
  98. package/dist/components/ai/plan.es.js +1 -1
  99. package/dist/components/ai/task-list.cjs.js +90 -0
  100. package/dist/components/ai/task-list.cjs.js.map +1 -0
  101. package/dist/components/ai/task-list.d.ts +2 -0
  102. package/dist/components/ai/task-list.es.js +80 -0
  103. package/dist/components/ai/task-list.es.js.map +1 -0
  104. package/dist/{data-code-section-Crs5wpnX.js → data-code-section-BjqDCzy3.js} +3 -3
  105. package/dist/{data-code-section-Crs5wpnX.js.map → data-code-section-BjqDCzy3.js.map} +1 -1
  106. package/dist/{data-code-section-DYy_n9I1.cjs → data-code-section-D0BwpqvV.cjs} +3 -3
  107. package/dist/{data-code-section-DYy_n9I1.cjs.map → data-code-section-D0BwpqvV.cjs.map} +1 -1
  108. package/dist/{data-panel-Otc4qdKL.js → data-panel-BGpCzY5K.js} +3 -3
  109. package/dist/{data-panel-Otc4qdKL.js.map → data-panel-BGpCzY5K.js.map} +1 -1
  110. package/dist/{data-panel-CAbxKoPF.cjs → data-panel-CsonAnlK.cjs} +3 -3
  111. package/dist/{data-panel-CAbxKoPF.cjs.map → data-panel-CsonAnlK.cjs.map} +1 -1
  112. package/dist/domains/logs/components/log-details-view.cjs.js +1 -1
  113. package/dist/domains/logs/components/log-details-view.es.js +1 -1
  114. package/dist/domains/logs/components/logs-toolbar.cjs.js +1 -1
  115. package/dist/domains/logs/components/logs-toolbar.es.js +1 -1
  116. package/dist/domains/memory/components/memory-studio-panel.cjs.js +1 -1
  117. package/dist/domains/memory/components/memory-studio-panel.es.js +1 -1
  118. package/dist/domains/traces/components/span-data-panel-view.cjs.js +2 -2
  119. package/dist/domains/traces/components/span-data-panel-view.es.js +2 -2
  120. package/dist/domains/traces/components/trace-data-panel-view.cjs.js +2 -2
  121. package/dist/domains/traces/components/trace-data-panel-view.es.js +2 -2
  122. package/dist/domains/traces/components/traces-toolbar.cjs.js +1 -1
  123. package/dist/domains/traces/components/traces-toolbar.es.js +1 -1
  124. package/dist/{drawer-DtEZQBXj.cjs → drawer-DvuUmhic.cjs} +3 -3
  125. package/dist/{drawer-DtEZQBXj.cjs.map → drawer-DvuUmhic.cjs.map} +1 -1
  126. package/dist/{drawer-Djerm1Lo.js → drawer-Dyx25o_o.js} +3 -3
  127. package/dist/{drawer-Djerm1Lo.js.map → drawer-Dyx25o_o.js.map} +1 -1
  128. package/dist/ee/signals/components/signals-empty-state.cjs.js +152 -0
  129. package/dist/ee/signals/components/signals-empty-state.cjs.js.map +1 -0
  130. package/dist/ee/signals/components/signals-empty-state.d.ts +2 -0
  131. package/dist/ee/signals/components/signals-empty-state.es.js +148 -0
  132. package/dist/ee/signals/components/signals-empty-state.es.js.map +1 -0
  133. package/dist/ee/signals/components/signals-overview-page.cjs.js +3 -201
  134. package/dist/ee/signals/components/signals-overview-page.cjs.js.map +1 -1
  135. package/dist/ee/signals/components/signals-overview-page.es.js +5 -201
  136. package/dist/ee/signals/components/signals-overview-page.es.js.map +1 -1
  137. package/dist/ee/signals/components.cjs.js +0 -10
  138. package/dist/ee/signals/components.cjs.js.map +1 -1
  139. package/dist/ee/signals/components.es.js +1 -3
  140. package/dist/ee/signals/components.es.js.map +1 -1
  141. package/dist/ee/signals/signal-colors.cjs.js +28 -0
  142. package/dist/ee/signals/signal-colors.cjs.js.map +1 -0
  143. package/dist/ee/signals/signal-colors.d.ts +2 -0
  144. package/dist/ee/signals/signal-colors.es.js +23 -0
  145. package/dist/ee/signals/signal-colors.es.js.map +1 -0
  146. package/dist/ee/signals.cjs.js +3 -27
  147. package/dist/ee/signals.cjs.js.map +1 -1
  148. package/dist/ee/signals.es.js +2 -7
  149. package/dist/ee/signals.es.js.map +1 -1
  150. package/dist/{field-block-CC_EYPWe.js → field-block-CBdMcT-i.js} +2 -2
  151. package/dist/{field-block-CC_EYPWe.js.map → field-block-CBdMcT-i.js.map} +1 -1
  152. package/dist/{field-block-Dx-fDIP9.cjs → field-block-CEbnWKc0.cjs} +2 -2
  153. package/dist/{field-block-Dx-fDIP9.cjs.map → field-block-CEbnWKc0.cjs.map} +1 -1
  154. package/dist/hooks/use-is-clamped.cjs.js +36 -0
  155. package/dist/hooks/use-is-clamped.cjs.js.map +1 -0
  156. package/dist/hooks/use-is-clamped.d.ts +2 -0
  157. package/dist/hooks/use-is-clamped.es.js +32 -0
  158. package/dist/hooks/use-is-clamped.es.js.map +1 -0
  159. package/dist/primitives/portal-container.cjs.js.map +1 -1
  160. package/dist/primitives/portal-container.es.js.map +1 -1
  161. package/dist/{property-filter-applied-Ca0UdU5P.js → property-filter-applied-Bs1Ck691.js} +2 -2
  162. package/dist/{property-filter-applied-Ca0UdU5P.js.map → property-filter-applied-Bs1Ck691.js.map} +1 -1
  163. package/dist/{property-filter-applied-BYKTDczo.cjs → property-filter-applied-DgmkZVbl.cjs} +2 -2
  164. package/dist/{property-filter-applied-BYKTDczo.cjs.map → property-filter-applied-DgmkZVbl.cjs.map} +1 -1
  165. package/dist/resize/panel-drawer.cjs.js +1 -1
  166. package/dist/resize/panel-drawer.es.js +1 -1
  167. package/dist/sankeyColor-CQ5nkgtL.js +48 -0
  168. package/dist/sankeyColor-CQ5nkgtL.js.map +1 -0
  169. package/dist/sankeyColor-DONd5cg9.cjs +53 -0
  170. package/dist/sankeyColor-DONd5cg9.cjs.map +1 -0
  171. package/dist/{search-field-block-e9qthuwY.js → search-field-block-CMoQ9fjl.js} +4 -3
  172. package/dist/search-field-block-CMoQ9fjl.js.map +1 -0
  173. package/dist/{search-field-block-C4njnmUx.cjs → search-field-block-DmqZsrrI.cjs} +4 -3
  174. package/dist/search-field-block-DmqZsrrI.cjs.map +1 -0
  175. package/dist/{select-field-block-dq1ZmZVb.cjs → select-field-block-BI_NZs2R.cjs} +2 -2
  176. package/dist/{select-field-block-dq1ZmZVb.cjs.map → select-field-block-BI_NZs2R.cjs.map} +1 -1
  177. package/dist/{select-field-block-BWuqWh4k.js → select-field-block-BSlngEHK.js} +2 -2
  178. package/dist/{select-field-block-BWuqWh4k.js.map → select-field-block-BSlngEHK.js.map} +1 -1
  179. package/dist/signals-empty-state.css +54 -0
  180. package/dist/src/ds/components/Card/Card.d.ts +15 -2
  181. package/dist/src/ds/components/Card/index.d.ts +2 -2
  182. package/dist/src/ds/components/ClampedText/clamped-text.d.ts +20 -0
  183. package/dist/src/ds/components/ClampedText/clamped-text.stories.d.ts +8 -0
  184. package/dist/src/ds/components/ClampedText/index.d.ts +1 -0
  185. package/dist/src/ds/components/Composer/composer.d.ts +5 -1
  186. package/dist/src/ds/components/Composer/index.d.ts +1 -1
  187. package/dist/src/ds/components/SankeyChart/index.d.ts +2 -1
  188. package/dist/src/ds/components/SankeyChart/sankey-chart-utils.d.ts +2 -1
  189. package/dist/src/ds/components/SankeyChart/sankey-chart.d.ts +4 -2
  190. package/dist/src/ds/components/SankeyChart/sankey-context.d.ts +3 -1
  191. package/dist/src/ds/components/Toaster/index.d.ts +1 -1
  192. package/dist/src/ds/components/Txt/Txt.d.ts +3 -2
  193. package/dist/src/ds/components/ai/ask-user/ask-user.d.ts +42 -0
  194. package/dist/src/ds/components/ai/ask-user/ask-user.stories.d.ts +11 -0
  195. package/dist/src/ds/components/ai/ask-user/index.d.ts +1 -0
  196. package/dist/src/ds/components/ai/task-list/index.d.ts +1 -0
  197. package/dist/src/ds/components/ai/task-list/task-list.d.ts +31 -0
  198. package/dist/src/ds/components/ai/task-list/task-list.stories.d.ts +9 -0
  199. package/dist/src/ee/signals/components/index.d.ts +0 -2
  200. package/dist/src/ee/signals/components/signals-empty-state.d.ts +7 -0
  201. package/dist/src/ee/signals/components/signals-overview-page.d.ts +2 -22
  202. package/dist/src/ee/signals/index.d.ts +1 -4
  203. package/dist/src/ee/signals/signal-colors.d.ts +7 -0
  204. package/dist/src/hooks/use-is-clamped.d.ts +11 -0
  205. package/dist/style.css +289 -40
  206. package/dist/{text-field-block-CpKq1NCV.cjs → text-field-block-BUvxjW9m.cjs} +2 -2
  207. package/dist/{text-field-block-CpKq1NCV.cjs.map → text-field-block-BUvxjW9m.cjs.map} +1 -1
  208. package/dist/{text-field-block-CrFqgdKx.js → text-field-block-DxtR1Ft4.js} +2 -2
  209. package/dist/{text-field-block-CrFqgdKx.js.map → text-field-block-DxtR1Ft4.js.map} +1 -1
  210. package/package.json +10 -10
  211. package/theme.css +1 -0
  212. package/dist/Txt-BT8_EkuZ.cjs.map +0 -1
  213. package/dist/Txt-p33XTnu8.js.map +0 -1
  214. package/dist/ee/signals/components/signal-details-page.cjs.js +0 -288
  215. package/dist/ee/signals/components/signal-details-page.cjs.js.map +0 -1
  216. package/dist/ee/signals/components/signal-details-page.d.ts +0 -2
  217. package/dist/ee/signals/components/signal-details-page.es.js +0 -280
  218. package/dist/ee/signals/components/signal-details-page.es.js.map +0 -1
  219. package/dist/ee/signals/components/signals-entity-filter.cjs.js +0 -27
  220. package/dist/ee/signals/components/signals-entity-filter.cjs.js.map +0 -1
  221. package/dist/ee/signals/components/signals-entity-filter.d.ts +0 -2
  222. package/dist/ee/signals/components/signals-entity-filter.es.js +0 -23
  223. package/dist/ee/signals/components/signals-entity-filter.es.js.map +0 -1
  224. package/dist/ee/signals/hooks/use-entity-learning-config.cjs.js +0 -35
  225. package/dist/ee/signals/hooks/use-entity-learning-config.cjs.js.map +0 -1
  226. package/dist/ee/signals/hooks/use-entity-learning-config.d.ts +0 -2
  227. package/dist/ee/signals/hooks/use-entity-learning-config.es.js +0 -31
  228. package/dist/ee/signals/hooks/use-entity-learning-config.es.js.map +0 -1
  229. package/dist/ee/signals/hooks/use-entity-learning.cjs.js +0 -96
  230. package/dist/ee/signals/hooks/use-entity-learning.cjs.js.map +0 -1
  231. package/dist/ee/signals/hooks/use-entity-learning.d.ts +0 -2
  232. package/dist/ee/signals/hooks/use-entity-learning.es.js +0 -84
  233. package/dist/ee/signals/hooks/use-entity-learning.es.js.map +0 -1
  234. package/dist/ee/signals/hooks.cjs.js +0 -20
  235. package/dist/ee/signals/hooks.cjs.js.map +0 -1
  236. package/dist/ee/signals/hooks.d.ts +0 -2
  237. package/dist/ee/signals/hooks.es.js +0 -3
  238. package/dist/ee/signals/hooks.es.js.map +0 -1
  239. package/dist/ee/signals/services/entity-learning-service.cjs.js +0 -88
  240. package/dist/ee/signals/services/entity-learning-service.cjs.js.map +0 -1
  241. package/dist/ee/signals/services/entity-learning-service.d.ts +0 -2
  242. package/dist/ee/signals/services/entity-learning-service.es.js +0 -84
  243. package/dist/ee/signals/services/entity-learning-service.es.js.map +0 -1
  244. package/dist/ee/signals/services/entity-learning-types.cjs.js +0 -3
  245. package/dist/ee/signals/services/entity-learning-types.cjs.js.map +0 -1
  246. package/dist/ee/signals/services/entity-learning-types.d.ts +0 -1
  247. package/dist/ee/signals/services/entity-learning-types.es.js +0 -2
  248. package/dist/ee/signals/services/entity-learning-types.es.js.map +0 -1
  249. package/dist/ee/signals/services.cjs.js +0 -10
  250. package/dist/ee/signals/services.cjs.js.map +0 -1
  251. package/dist/ee/signals/services.d.ts +0 -2
  252. package/dist/ee/signals/services.es.js +0 -2
  253. package/dist/ee/signals/services.es.js.map +0 -1
  254. package/dist/ee/signals/signals-data.cjs.js +0 -53
  255. package/dist/ee/signals/signals-data.cjs.js.map +0 -1
  256. package/dist/ee/signals/signals-data.d.ts +0 -2
  257. package/dist/ee/signals/signals-data.es.js +0 -48
  258. package/dist/ee/signals/signals-data.es.js.map +0 -1
  259. package/dist/ee/signals/types.cjs.js +0 -3
  260. package/dist/ee/signals/types.cjs.js.map +0 -1
  261. package/dist/ee/signals/types.d.ts +0 -1
  262. package/dist/ee/signals/types.es.js +0 -2
  263. package/dist/ee/signals/types.es.js.map +0 -1
  264. package/dist/search-field-block-C4njnmUx.cjs.map +0 -1
  265. package/dist/search-field-block-e9qthuwY.js.map +0 -1
  266. package/dist/src/ee/signals/components/signal-details-page.d.ts +0 -40
  267. package/dist/src/ee/signals/components/signals-entity-filter.d.ts +0 -13
  268. package/dist/src/ee/signals/hooks/index.d.ts +0 -2
  269. package/dist/src/ee/signals/hooks/use-entity-learning-config.d.ts +0 -14
  270. package/dist/src/ee/signals/hooks/use-entity-learning.d.ts +0 -24
  271. package/dist/src/ee/signals/services/entity-learning-service.d.ts +0 -43
  272. package/dist/src/ee/signals/services/entity-learning-types.d.ts +0 -123
  273. package/dist/src/ee/signals/services/index.d.ts +0 -2
  274. package/dist/src/ee/signals/signals-data.d.ts +0 -10
  275. package/dist/src/ee/signals/types.d.ts +0 -15
@@ -0,0 +1,147 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const jsxRuntime = require('react/jsx-runtime');
6
+ const React = require('react');
7
+ const Badge = require('../../Badge-BlJpI3fY.cjs');
8
+ const Button = require('../../Button-B5RnKrGb.cjs');
9
+ const input = require('../../input-0R-fQTCF.cjs');
10
+ const utils_cn = require('../../cn-vA5sWo9W.cjs');
11
+
12
+ const AskUserContainer = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: utils_cn.cn("rounded-lg border border-border1 bg-surface2 p-3 text-sm", className), ...props });
13
+ const AskUserQuestion = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("legend", { className: utils_cn.cn("mb-3 font-medium text-neutral6", className), ...props });
14
+ const AskUserOptionDescription = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: utils_cn.cn("block text-ui-xs font-normal text-neutral3", className), ...props });
15
+ const AskUserOptionControl = ({ type, label, description, className, ...props }) => /* @__PURE__ */ jsxRuntime.jsxs(
16
+ "label",
17
+ {
18
+ className: utils_cn.cn(
19
+ "flex cursor-pointer items-start gap-2 rounded-md border border-border1 bg-surface3 px-3 py-2 text-neutral5 transition-colors hover:bg-surface4 has-[:checked]:border-border2 has-[:checked]:bg-surface4 has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50",
20
+ className
21
+ ),
22
+ children: [
23
+ /* @__PURE__ */ jsxRuntime.jsx("input", { type, className: "mt-0.5 accent-current", ...props }),
24
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
25
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block", children: label }),
26
+ description ? /* @__PURE__ */ jsxRuntime.jsx(AskUserOptionDescription, { children: description }) : null
27
+ ] })
28
+ ]
29
+ }
30
+ );
31
+ const AskUserSubmit = ({ children = "Submit answer", ...props }) => /* @__PURE__ */ jsxRuntime.jsx(Button.Button, { type: "button", size: "sm", variant: "primary", ...props, children });
32
+ const AskUserPending = ({ children = "Submitting…", className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("span", { role: "status", className: utils_cn.cn("text-ui-xs text-neutral3", className), ...props, children });
33
+ const AskUserOutput = ({ result, className, ...props }) => /* @__PURE__ */ jsxRuntime.jsxs(
34
+ "div",
35
+ {
36
+ role: result.isError ? "alert" : "status",
37
+ className: utils_cn.cn("space-y-2 rounded-md bg-surface3 p-3 text-neutral5", result.isError && "text-error", className),
38
+ ...props,
39
+ children: [
40
+ /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { size: "xs", variant: result.isError ? "error" : "success", children: result.isError ? "Error" : "Answered" }),
41
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: result.content })
42
+ ]
43
+ }
44
+ );
45
+ const validOptions = (options) => options?.filter(
46
+ (option) => Boolean(option && typeof option.label === "string" && option.label)
47
+ ) ?? [];
48
+ const AskUserInput = ({
49
+ payload,
50
+ options,
51
+ result,
52
+ isAnswered = false,
53
+ isSubmitting = false,
54
+ onSubmit,
55
+ footer,
56
+ ...props
57
+ }) => {
58
+ const inputId = React.useId();
59
+ const [text, setText] = React.useState("");
60
+ const [selected, setSelected] = React.useState([]);
61
+ if (result || isAnswered) {
62
+ return /* @__PURE__ */ jsxRuntime.jsxs(AskUserContainer, { "data-testid": "ask-user", ...props, children: [
63
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mb-2 font-medium text-neutral6", children: payload.question }),
64
+ result ? /* @__PURE__ */ jsxRuntime.jsx(AskUserOutput, { result }) : /* @__PURE__ */ jsxRuntime.jsx(Badge.Badge, { variant: "success", children: "Answered" })
65
+ ] });
66
+ }
67
+ const submitText = () => {
68
+ const answer = text.trim();
69
+ if (answer && !isSubmitting) onSubmit(answer);
70
+ };
71
+ const handleTextKeyDown = (event) => {
72
+ if (event.key === "Enter") {
73
+ event.preventDefault();
74
+ submitText();
75
+ }
76
+ };
77
+ if (options.length === 0) {
78
+ return /* @__PURE__ */ jsxRuntime.jsxs(AskUserContainer, { "data-testid": "ask-user", ...props, children: [
79
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "mb-2 block font-medium text-neutral6", htmlFor: inputId, children: payload.question }),
80
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
81
+ /* @__PURE__ */ jsxRuntime.jsx(
82
+ input.Input,
83
+ {
84
+ id: inputId,
85
+ value: text,
86
+ onChange: (event) => setText(event.target.value),
87
+ onKeyDown: handleTextKeyDown,
88
+ placeholder: "Type your answer...",
89
+ disabled: isSubmitting,
90
+ size: "sm"
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsxRuntime.jsx(AskUserSubmit, { "aria-label": "Submit answer", disabled: isSubmitting || !text.trim(), onClick: submitText, children: "Submit" })
94
+ ] }),
95
+ isSubmitting ? /* @__PURE__ */ jsxRuntime.jsx(AskUserPending, { className: "mt-2 block" }) : null,
96
+ footer
97
+ ] });
98
+ }
99
+ const isMulti = payload.selectionMode === "multi_select";
100
+ return /* @__PURE__ */ jsxRuntime.jsx(AskUserContainer, { "data-testid": "ask-user", ...props, children: /* @__PURE__ */ jsxRuntime.jsxs("fieldset", { disabled: isSubmitting, className: "space-y-2", children: [
101
+ /* @__PURE__ */ jsxRuntime.jsx(AskUserQuestion, { children: payload.question }),
102
+ options.map((option) => {
103
+ const checked = selected.includes(option.label);
104
+ return /* @__PURE__ */ jsxRuntime.jsx(
105
+ AskUserOptionControl,
106
+ {
107
+ type: isMulti ? "checkbox" : "radio",
108
+ name: inputId,
109
+ label: option.label,
110
+ description: option.description,
111
+ disabled: isSubmitting,
112
+ checked,
113
+ onChange: () => {
114
+ if (isSubmitting) return;
115
+ if (!isMulti) {
116
+ setSelected([option.label]);
117
+ onSubmit(option.label);
118
+ return;
119
+ }
120
+ setSelected(
121
+ (current) => current.includes(option.label) ? current.filter((selectedLabel) => selectedLabel !== option.label) : [...current, option.label]
122
+ );
123
+ }
124
+ },
125
+ option.label
126
+ );
127
+ }),
128
+ isMulti ? /* @__PURE__ */ jsxRuntime.jsx(AskUserSubmit, { disabled: isSubmitting || selected.length === 0, onClick: () => onSubmit(selected), children: "Submit answer" }) : null,
129
+ isSubmitting ? /* @__PURE__ */ jsxRuntime.jsx(AskUserPending, {}) : null,
130
+ footer
131
+ ] }) });
132
+ };
133
+ const AskUser = ({ payload, ...props }) => {
134
+ const options = validOptions(payload.options);
135
+ const payloadKey = JSON.stringify([payload.question, options.map((option) => option.label), payload.selectionMode]);
136
+ return /* @__PURE__ */ jsxRuntime.jsx(AskUserInput, { payload, options, ...props }, payloadKey);
137
+ };
138
+
139
+ exports.AskUser = AskUser;
140
+ exports.AskUserContainer = AskUserContainer;
141
+ exports.AskUserOptionControl = AskUserOptionControl;
142
+ exports.AskUserOptionDescription = AskUserOptionDescription;
143
+ exports.AskUserOutput = AskUserOutput;
144
+ exports.AskUserPending = AskUserPending;
145
+ exports.AskUserQuestion = AskUserQuestion;
146
+ exports.AskUserSubmit = AskUserSubmit;
147
+ //# sourceMappingURL=ask-user.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-user.cjs.js","sources":["../../../src/ds/components/ai/ask-user/ask-user.tsx"],"sourcesContent":["import { useId, useState } from 'react';\nimport type { ComponentProps, KeyboardEvent, ReactNode } from 'react';\nimport { Badge } from '@/ds/components/Badge';\nimport { Button } from '@/ds/components/Button';\nimport { Input } from '@/ds/components/Input';\nimport { cn } from '@/lib/utils';\n\nexport type AskUserSelectionMode = 'single_select' | 'multi_select';\nexport type AskUserAnswer = string | string[];\n\nexport interface AskUserOption {\n label: string;\n description?: string;\n}\n\nexport interface AskUserPayload {\n question: string;\n options?: AskUserOption[];\n selectionMode?: AskUserSelectionMode;\n}\n\nexport interface AskUserResult {\n content: string;\n isError?: boolean;\n}\n\nexport const AskUserContainer = ({ className, ...props }: ComponentProps<'div'>) => (\n <div className={cn('rounded-lg border border-border1 bg-surface2 p-3 text-sm', className)} {...props} />\n);\n\nexport const AskUserQuestion = ({ className, ...props }: ComponentProps<'legend'>) => (\n <legend className={cn('mb-3 font-medium text-neutral6', className)} {...props} />\n);\n\nexport const AskUserOptionDescription = ({ className, ...props }: ComponentProps<'span'>) => (\n <span className={cn('block text-ui-xs font-normal text-neutral3', className)} {...props} />\n);\n\ninterface AskUserOptionControlProps extends Omit<ComponentProps<'input'>, 'type'> {\n type: 'radio' | 'checkbox';\n label: string;\n description?: string;\n}\n\nexport const AskUserOptionControl = ({ type, label, description, className, ...props }: AskUserOptionControlProps) => (\n <label\n className={cn(\n 'flex cursor-pointer items-start gap-2 rounded-md border border-border1 bg-surface3 px-3 py-2 text-neutral5 transition-colors hover:bg-surface4 has-[:checked]:border-border2 has-[:checked]:bg-surface4 has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50',\n className,\n )}\n >\n <input type={type} className=\"mt-0.5 accent-current\" {...props} />\n <span>\n <span className=\"block\">{label}</span>\n {description ? <AskUserOptionDescription>{description}</AskUserOptionDescription> : null}\n </span>\n </label>\n);\n\nexport const AskUserSubmit = ({ children = 'Submit answer', ...props }: ComponentProps<typeof Button>) => (\n <Button type=\"button\" size=\"sm\" variant=\"primary\" {...props}>\n {children}\n </Button>\n);\n\nexport const AskUserPending = ({ children = 'Submitting…', className, ...props }: ComponentProps<'span'>) => (\n <span role=\"status\" className={cn('text-ui-xs text-neutral3', className)} {...props}>\n {children}\n </span>\n);\n\nexport interface AskUserOutputProps extends ComponentProps<'div'> {\n result: AskUserResult;\n}\n\nexport const AskUserOutput = ({ result, className, ...props }: AskUserOutputProps) => (\n <div\n role={result.isError ? 'alert' : 'status'}\n className={cn('space-y-2 rounded-md bg-surface3 p-3 text-neutral5', result.isError && 'text-error', className)}\n {...props}\n >\n <Badge size=\"xs\" variant={result.isError ? 'error' : 'success'}>\n {result.isError ? 'Error' : 'Answered'}\n </Badge>\n <p>{result.content}</p>\n </div>\n);\n\nexport interface AskUserProps extends Omit<ComponentProps<typeof AskUserContainer>, 'children' | 'onSubmit'> {\n payload: AskUserPayload;\n result?: AskUserResult;\n isAnswered?: boolean;\n isSubmitting?: boolean;\n onSubmit: (answer: AskUserAnswer) => void;\n footer?: ReactNode;\n}\n\nconst validOptions = (options: AskUserPayload['options']): AskUserOption[] =>\n options?.filter((option): option is AskUserOption =>\n Boolean(option && typeof option.label === 'string' && option.label),\n ) ?? [];\n\ninterface AskUserInputProps extends AskUserProps {\n options: AskUserOption[];\n}\n\nconst AskUserInput = ({\n payload,\n options,\n result,\n isAnswered = false,\n isSubmitting = false,\n onSubmit,\n footer,\n ...props\n}: AskUserInputProps) => {\n const inputId = useId();\n const [text, setText] = useState('');\n const [selected, setSelected] = useState<string[]>([]);\n\n if (result || isAnswered) {\n return (\n <AskUserContainer data-testid=\"ask-user\" {...props}>\n <p className=\"mb-2 font-medium text-neutral6\">{payload.question}</p>\n {result ? <AskUserOutput result={result} /> : <Badge variant=\"success\">Answered</Badge>}\n </AskUserContainer>\n );\n }\n\n const submitText = () => {\n const answer = text.trim();\n if (answer && !isSubmitting) onSubmit(answer);\n };\n\n const handleTextKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n submitText();\n }\n };\n\n if (options.length === 0) {\n return (\n <AskUserContainer data-testid=\"ask-user\" {...props}>\n <label className=\"mb-2 block font-medium text-neutral6\" htmlFor={inputId}>\n {payload.question}\n </label>\n <div className=\"flex items-center gap-2\">\n <Input\n id={inputId}\n value={text}\n onChange={event => setText(event.target.value)}\n onKeyDown={handleTextKeyDown}\n placeholder=\"Type your answer...\"\n disabled={isSubmitting}\n size=\"sm\"\n />\n <AskUserSubmit aria-label=\"Submit answer\" disabled={isSubmitting || !text.trim()} onClick={submitText}>\n Submit\n </AskUserSubmit>\n </div>\n {isSubmitting ? <AskUserPending className=\"mt-2 block\" /> : null}\n {footer}\n </AskUserContainer>\n );\n }\n\n const isMulti = payload.selectionMode === 'multi_select';\n return (\n <AskUserContainer data-testid=\"ask-user\" {...props}>\n <fieldset disabled={isSubmitting} className=\"space-y-2\">\n <AskUserQuestion>{payload.question}</AskUserQuestion>\n {options.map(option => {\n const checked = selected.includes(option.label);\n return (\n <AskUserOptionControl\n key={option.label}\n type={isMulti ? 'checkbox' : 'radio'}\n name={inputId}\n label={option.label}\n description={option.description}\n disabled={isSubmitting}\n checked={checked}\n onChange={() => {\n if (isSubmitting) return;\n if (!isMulti) {\n setSelected([option.label]);\n onSubmit(option.label);\n return;\n }\n setSelected(current =>\n current.includes(option.label)\n ? current.filter(selectedLabel => selectedLabel !== option.label)\n : [...current, option.label],\n );\n }}\n />\n );\n })}\n {isMulti ? (\n <AskUserSubmit disabled={isSubmitting || selected.length === 0} onClick={() => onSubmit(selected)}>\n Submit answer\n </AskUserSubmit>\n ) : null}\n {isSubmitting ? <AskUserPending /> : null}\n {footer}\n </fieldset>\n </AskUserContainer>\n );\n};\n\nexport const AskUser = ({ payload, ...props }: AskUserProps) => {\n const options = validOptions(payload.options);\n const payloadKey = JSON.stringify([payload.question, options.map(option => option.label), payload.selectionMode]);\n\n return <AskUserInput key={payloadKey} payload={payload} options={options} {...props} />;\n};\n"],"names":["jsx","cn","jsxs","Button","Badge","useId","useState","Input"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from '../../src/ds/components/ai/ask-user/index'
2
+ export {}
@@ -0,0 +1,136 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useId, useState } from 'react';
3
+ import { B as Badge } from '../../Badge-woV6OD8k.js';
4
+ import { B as Button } from '../../Button-Dh5CZ6Ir.js';
5
+ import { I as Input } from '../../input-DVZ0-3KP.js';
6
+ import { c as cn } from '../../cn-BakJzhuv.js';
7
+
8
+ const AskUserContainer = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: cn("rounded-lg border border-border1 bg-surface2 p-3 text-sm", className), ...props });
9
+ const AskUserQuestion = ({ className, ...props }) => /* @__PURE__ */ jsx("legend", { className: cn("mb-3 font-medium text-neutral6", className), ...props });
10
+ const AskUserOptionDescription = ({ className, ...props }) => /* @__PURE__ */ jsx("span", { className: cn("block text-ui-xs font-normal text-neutral3", className), ...props });
11
+ const AskUserOptionControl = ({ type, label, description, className, ...props }) => /* @__PURE__ */ jsxs(
12
+ "label",
13
+ {
14
+ className: cn(
15
+ "flex cursor-pointer items-start gap-2 rounded-md border border-border1 bg-surface3 px-3 py-2 text-neutral5 transition-colors hover:bg-surface4 has-[:checked]:border-border2 has-[:checked]:bg-surface4 has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50",
16
+ className
17
+ ),
18
+ children: [
19
+ /* @__PURE__ */ jsx("input", { type, className: "mt-0.5 accent-current", ...props }),
20
+ /* @__PURE__ */ jsxs("span", { children: [
21
+ /* @__PURE__ */ jsx("span", { className: "block", children: label }),
22
+ description ? /* @__PURE__ */ jsx(AskUserOptionDescription, { children: description }) : null
23
+ ] })
24
+ ]
25
+ }
26
+ );
27
+ const AskUserSubmit = ({ children = "Submit answer", ...props }) => /* @__PURE__ */ jsx(Button, { type: "button", size: "sm", variant: "primary", ...props, children });
28
+ const AskUserPending = ({ children = "Submitting…", className, ...props }) => /* @__PURE__ */ jsx("span", { role: "status", className: cn("text-ui-xs text-neutral3", className), ...props, children });
29
+ const AskUserOutput = ({ result, className, ...props }) => /* @__PURE__ */ jsxs(
30
+ "div",
31
+ {
32
+ role: result.isError ? "alert" : "status",
33
+ className: cn("space-y-2 rounded-md bg-surface3 p-3 text-neutral5", result.isError && "text-error", className),
34
+ ...props,
35
+ children: [
36
+ /* @__PURE__ */ jsx(Badge, { size: "xs", variant: result.isError ? "error" : "success", children: result.isError ? "Error" : "Answered" }),
37
+ /* @__PURE__ */ jsx("p", { children: result.content })
38
+ ]
39
+ }
40
+ );
41
+ const validOptions = (options) => options?.filter(
42
+ (option) => Boolean(option && typeof option.label === "string" && option.label)
43
+ ) ?? [];
44
+ const AskUserInput = ({
45
+ payload,
46
+ options,
47
+ result,
48
+ isAnswered = false,
49
+ isSubmitting = false,
50
+ onSubmit,
51
+ footer,
52
+ ...props
53
+ }) => {
54
+ const inputId = useId();
55
+ const [text, setText] = useState("");
56
+ const [selected, setSelected] = useState([]);
57
+ if (result || isAnswered) {
58
+ return /* @__PURE__ */ jsxs(AskUserContainer, { "data-testid": "ask-user", ...props, children: [
59
+ /* @__PURE__ */ jsx("p", { className: "mb-2 font-medium text-neutral6", children: payload.question }),
60
+ result ? /* @__PURE__ */ jsx(AskUserOutput, { result }) : /* @__PURE__ */ jsx(Badge, { variant: "success", children: "Answered" })
61
+ ] });
62
+ }
63
+ const submitText = () => {
64
+ const answer = text.trim();
65
+ if (answer && !isSubmitting) onSubmit(answer);
66
+ };
67
+ const handleTextKeyDown = (event) => {
68
+ if (event.key === "Enter") {
69
+ event.preventDefault();
70
+ submitText();
71
+ }
72
+ };
73
+ if (options.length === 0) {
74
+ return /* @__PURE__ */ jsxs(AskUserContainer, { "data-testid": "ask-user", ...props, children: [
75
+ /* @__PURE__ */ jsx("label", { className: "mb-2 block font-medium text-neutral6", htmlFor: inputId, children: payload.question }),
76
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
77
+ /* @__PURE__ */ jsx(
78
+ Input,
79
+ {
80
+ id: inputId,
81
+ value: text,
82
+ onChange: (event) => setText(event.target.value),
83
+ onKeyDown: handleTextKeyDown,
84
+ placeholder: "Type your answer...",
85
+ disabled: isSubmitting,
86
+ size: "sm"
87
+ }
88
+ ),
89
+ /* @__PURE__ */ jsx(AskUserSubmit, { "aria-label": "Submit answer", disabled: isSubmitting || !text.trim(), onClick: submitText, children: "Submit" })
90
+ ] }),
91
+ isSubmitting ? /* @__PURE__ */ jsx(AskUserPending, { className: "mt-2 block" }) : null,
92
+ footer
93
+ ] });
94
+ }
95
+ const isMulti = payload.selectionMode === "multi_select";
96
+ return /* @__PURE__ */ jsx(AskUserContainer, { "data-testid": "ask-user", ...props, children: /* @__PURE__ */ jsxs("fieldset", { disabled: isSubmitting, className: "space-y-2", children: [
97
+ /* @__PURE__ */ jsx(AskUserQuestion, { children: payload.question }),
98
+ options.map((option) => {
99
+ const checked = selected.includes(option.label);
100
+ return /* @__PURE__ */ jsx(
101
+ AskUserOptionControl,
102
+ {
103
+ type: isMulti ? "checkbox" : "radio",
104
+ name: inputId,
105
+ label: option.label,
106
+ description: option.description,
107
+ disabled: isSubmitting,
108
+ checked,
109
+ onChange: () => {
110
+ if (isSubmitting) return;
111
+ if (!isMulti) {
112
+ setSelected([option.label]);
113
+ onSubmit(option.label);
114
+ return;
115
+ }
116
+ setSelected(
117
+ (current) => current.includes(option.label) ? current.filter((selectedLabel) => selectedLabel !== option.label) : [...current, option.label]
118
+ );
119
+ }
120
+ },
121
+ option.label
122
+ );
123
+ }),
124
+ isMulti ? /* @__PURE__ */ jsx(AskUserSubmit, { disabled: isSubmitting || selected.length === 0, onClick: () => onSubmit(selected), children: "Submit answer" }) : null,
125
+ isSubmitting ? /* @__PURE__ */ jsx(AskUserPending, {}) : null,
126
+ footer
127
+ ] }) });
128
+ };
129
+ const AskUser = ({ payload, ...props }) => {
130
+ const options = validOptions(payload.options);
131
+ const payloadKey = JSON.stringify([payload.question, options.map((option) => option.label), payload.selectionMode]);
132
+ return /* @__PURE__ */ jsx(AskUserInput, { payload, options, ...props }, payloadKey);
133
+ };
134
+
135
+ export { AskUser, AskUserContainer, AskUserOptionControl, AskUserOptionDescription, AskUserOutput, AskUserPending, AskUserQuestion, AskUserSubmit };
136
+ //# sourceMappingURL=ask-user.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-user.es.js","sources":["../../../src/ds/components/ai/ask-user/ask-user.tsx"],"sourcesContent":["import { useId, useState } from 'react';\nimport type { ComponentProps, KeyboardEvent, ReactNode } from 'react';\nimport { Badge } from '@/ds/components/Badge';\nimport { Button } from '@/ds/components/Button';\nimport { Input } from '@/ds/components/Input';\nimport { cn } from '@/lib/utils';\n\nexport type AskUserSelectionMode = 'single_select' | 'multi_select';\nexport type AskUserAnswer = string | string[];\n\nexport interface AskUserOption {\n label: string;\n description?: string;\n}\n\nexport interface AskUserPayload {\n question: string;\n options?: AskUserOption[];\n selectionMode?: AskUserSelectionMode;\n}\n\nexport interface AskUserResult {\n content: string;\n isError?: boolean;\n}\n\nexport const AskUserContainer = ({ className, ...props }: ComponentProps<'div'>) => (\n <div className={cn('rounded-lg border border-border1 bg-surface2 p-3 text-sm', className)} {...props} />\n);\n\nexport const AskUserQuestion = ({ className, ...props }: ComponentProps<'legend'>) => (\n <legend className={cn('mb-3 font-medium text-neutral6', className)} {...props} />\n);\n\nexport const AskUserOptionDescription = ({ className, ...props }: ComponentProps<'span'>) => (\n <span className={cn('block text-ui-xs font-normal text-neutral3', className)} {...props} />\n);\n\ninterface AskUserOptionControlProps extends Omit<ComponentProps<'input'>, 'type'> {\n type: 'radio' | 'checkbox';\n label: string;\n description?: string;\n}\n\nexport const AskUserOptionControl = ({ type, label, description, className, ...props }: AskUserOptionControlProps) => (\n <label\n className={cn(\n 'flex cursor-pointer items-start gap-2 rounded-md border border-border1 bg-surface3 px-3 py-2 text-neutral5 transition-colors hover:bg-surface4 has-[:checked]:border-border2 has-[:checked]:bg-surface4 has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50',\n className,\n )}\n >\n <input type={type} className=\"mt-0.5 accent-current\" {...props} />\n <span>\n <span className=\"block\">{label}</span>\n {description ? <AskUserOptionDescription>{description}</AskUserOptionDescription> : null}\n </span>\n </label>\n);\n\nexport const AskUserSubmit = ({ children = 'Submit answer', ...props }: ComponentProps<typeof Button>) => (\n <Button type=\"button\" size=\"sm\" variant=\"primary\" {...props}>\n {children}\n </Button>\n);\n\nexport const AskUserPending = ({ children = 'Submitting…', className, ...props }: ComponentProps<'span'>) => (\n <span role=\"status\" className={cn('text-ui-xs text-neutral3', className)} {...props}>\n {children}\n </span>\n);\n\nexport interface AskUserOutputProps extends ComponentProps<'div'> {\n result: AskUserResult;\n}\n\nexport const AskUserOutput = ({ result, className, ...props }: AskUserOutputProps) => (\n <div\n role={result.isError ? 'alert' : 'status'}\n className={cn('space-y-2 rounded-md bg-surface3 p-3 text-neutral5', result.isError && 'text-error', className)}\n {...props}\n >\n <Badge size=\"xs\" variant={result.isError ? 'error' : 'success'}>\n {result.isError ? 'Error' : 'Answered'}\n </Badge>\n <p>{result.content}</p>\n </div>\n);\n\nexport interface AskUserProps extends Omit<ComponentProps<typeof AskUserContainer>, 'children' | 'onSubmit'> {\n payload: AskUserPayload;\n result?: AskUserResult;\n isAnswered?: boolean;\n isSubmitting?: boolean;\n onSubmit: (answer: AskUserAnswer) => void;\n footer?: ReactNode;\n}\n\nconst validOptions = (options: AskUserPayload['options']): AskUserOption[] =>\n options?.filter((option): option is AskUserOption =>\n Boolean(option && typeof option.label === 'string' && option.label),\n ) ?? [];\n\ninterface AskUserInputProps extends AskUserProps {\n options: AskUserOption[];\n}\n\nconst AskUserInput = ({\n payload,\n options,\n result,\n isAnswered = false,\n isSubmitting = false,\n onSubmit,\n footer,\n ...props\n}: AskUserInputProps) => {\n const inputId = useId();\n const [text, setText] = useState('');\n const [selected, setSelected] = useState<string[]>([]);\n\n if (result || isAnswered) {\n return (\n <AskUserContainer data-testid=\"ask-user\" {...props}>\n <p className=\"mb-2 font-medium text-neutral6\">{payload.question}</p>\n {result ? <AskUserOutput result={result} /> : <Badge variant=\"success\">Answered</Badge>}\n </AskUserContainer>\n );\n }\n\n const submitText = () => {\n const answer = text.trim();\n if (answer && !isSubmitting) onSubmit(answer);\n };\n\n const handleTextKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter') {\n event.preventDefault();\n submitText();\n }\n };\n\n if (options.length === 0) {\n return (\n <AskUserContainer data-testid=\"ask-user\" {...props}>\n <label className=\"mb-2 block font-medium text-neutral6\" htmlFor={inputId}>\n {payload.question}\n </label>\n <div className=\"flex items-center gap-2\">\n <Input\n id={inputId}\n value={text}\n onChange={event => setText(event.target.value)}\n onKeyDown={handleTextKeyDown}\n placeholder=\"Type your answer...\"\n disabled={isSubmitting}\n size=\"sm\"\n />\n <AskUserSubmit aria-label=\"Submit answer\" disabled={isSubmitting || !text.trim()} onClick={submitText}>\n Submit\n </AskUserSubmit>\n </div>\n {isSubmitting ? <AskUserPending className=\"mt-2 block\" /> : null}\n {footer}\n </AskUserContainer>\n );\n }\n\n const isMulti = payload.selectionMode === 'multi_select';\n return (\n <AskUserContainer data-testid=\"ask-user\" {...props}>\n <fieldset disabled={isSubmitting} className=\"space-y-2\">\n <AskUserQuestion>{payload.question}</AskUserQuestion>\n {options.map(option => {\n const checked = selected.includes(option.label);\n return (\n <AskUserOptionControl\n key={option.label}\n type={isMulti ? 'checkbox' : 'radio'}\n name={inputId}\n label={option.label}\n description={option.description}\n disabled={isSubmitting}\n checked={checked}\n onChange={() => {\n if (isSubmitting) return;\n if (!isMulti) {\n setSelected([option.label]);\n onSubmit(option.label);\n return;\n }\n setSelected(current =>\n current.includes(option.label)\n ? current.filter(selectedLabel => selectedLabel !== option.label)\n : [...current, option.label],\n );\n }}\n />\n );\n })}\n {isMulti ? (\n <AskUserSubmit disabled={isSubmitting || selected.length === 0} onClick={() => onSubmit(selected)}>\n Submit answer\n </AskUserSubmit>\n ) : null}\n {isSubmitting ? <AskUserPending /> : null}\n {footer}\n </fieldset>\n </AskUserContainer>\n );\n};\n\nexport const AskUser = ({ payload, ...props }: AskUserProps) => {\n const options = validOptions(payload.options);\n const payloadKey = JSON.stringify([payload.question, options.map(option => option.label), payload.selectionMode]);\n\n return <AskUserInput key={payloadKey} payload={payload} options={options} {...props} />;\n};\n"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@ const React = require('react');
8
8
  const Badge = require('../../Badge-BlJpI3fY.cjs');
9
9
  const Button = require('../../Button-B5RnKrGb.cjs');
10
10
  const markdownRenderer = require('../../markdown-renderer-DRnUrMmF.cjs');
11
- const Txt = require('../../Txt-BT8_EkuZ.cjs');
11
+ const Txt = require('../../Txt-I5lK8zy7.cjs');
12
12
  const icons_Icon = require('../../icons/Icon.cjs.js');
13
13
  const hooks_useCopyToClipboard = require('../../hooks/use-copy-to-clipboard.cjs.js');
14
14
  const utils_cn = require('../../cn-vA5sWo9W.cjs');
@@ -4,7 +4,7 @@ import { useState, createContext, useContext } from 'react';
4
4
  import { B as Badge } from '../../Badge-woV6OD8k.js';
5
5
  import { B as Button } from '../../Button-Dh5CZ6Ir.js';
6
6
  import { M as MarkdownRenderer } from '../../markdown-renderer-ZzJcwfS3.js';
7
- import { T as Txt } from '../../Txt-p33XTnu8.js';
7
+ import { T as Txt } from '../../Txt-Df42XG5p.js';
8
8
  import { Icon } from '../../icons/Icon.es.js';
9
9
  import { useCopyToClipboard } from '../../hooks/use-copy-to-clipboard.es.js';
10
10
  import { c as cn } from '../../cn-BakJzhuv.js';
@@ -0,0 +1,90 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
4
+
5
+ const jsxRuntime = require('react/jsx-runtime');
6
+ const lucideReact = require('lucide-react');
7
+ const React = require('react');
8
+ const utils_cn = require('../../cn-vA5sWo9W.cjs');
9
+
10
+ const TaskListContainer = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("section", { className: utils_cn.cn("rounded-2xl border border-border2/40 bg-surface3 px-3 py-2.5", className), ...props });
11
+ const TaskListHeader = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("header", { className: utils_cn.cn("mb-2 flex items-center gap-2", className), ...props });
12
+ const TaskListCount = ({ completed, total, className, ...props }) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: utils_cn.cn("ml-auto text-ui-xs text-neutral4 tabular-nums", className), ...props, children: [
13
+ completed,
14
+ "/",
15
+ total,
16
+ " completed"
17
+ ] });
18
+ const TaskListProgress = ({ completed, total, className, ...props }) => {
19
+ const percentage = total === 0 ? 0 : completed / total * 100;
20
+ return /* @__PURE__ */ jsxRuntime.jsx(
21
+ "div",
22
+ {
23
+ role: "progressbar",
24
+ "aria-label": "Task completion",
25
+ "aria-valuemin": 0,
26
+ "aria-valuemax": total,
27
+ "aria-valuenow": completed,
28
+ className: utils_cn.cn("mb-2.5 h-1 w-full rounded-full bg-surface4", className),
29
+ ...props,
30
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full rounded-full bg-accent6 transition-all duration-300", style: { width: `${percentage}%` } })
31
+ }
32
+ );
33
+ };
34
+ const icons = {
35
+ completed: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CheckCircle2, { className: "size-3.5 shrink-0 text-positive1" }),
36
+ in_progress: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "size-3.5 shrink-0 text-warning1 motion-safe:animate-spin" }),
37
+ pending: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Circle, { className: "size-3.5 shrink-0 text-neutral4" })
38
+ };
39
+ const statusLabels = {
40
+ completed: "Completed",
41
+ in_progress: "In progress",
42
+ pending: "Pending"
43
+ };
44
+ const textClasses = {
45
+ completed: "text-neutral4 line-through",
46
+ in_progress: "font-medium text-warning1",
47
+ pending: "text-neutral5"
48
+ };
49
+ const TaskListStatusIcon = ({ status, className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-label": statusLabels[status], className: utils_cn.cn("pt-0.5", className), ...props, children: icons[status] });
50
+ const TaskListRow = ({ task, className, ...props }) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: utils_cn.cn("flex items-start gap-2 py-0.5", className), ...props, children: [
51
+ /* @__PURE__ */ jsxRuntime.jsx(TaskListStatusIcon, { status: task.status }),
52
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: utils_cn.cn("text-ui-sm leading-ui-sm", textClasses[task.status]), children: task.status === "in_progress" ? task.activeForm : task.content })
53
+ ] });
54
+ const TaskList = ({
55
+ tasks,
56
+ title = "Tasks",
57
+ hideWhenEmpty = true,
58
+ hideWhenComplete = true,
59
+ scrollActiveIntoView = true,
60
+ ...props
61
+ }) => {
62
+ const activeTaskRef = React.useRef(null);
63
+ const activeTaskId = tasks.find((task) => task.status === "in_progress")?.id;
64
+ const completed = tasks.filter((task) => task.status === "completed").length;
65
+ const total = tasks.length;
66
+ React.useEffect(() => {
67
+ if (!scrollActiveIntoView || !activeTaskRef.current || typeof activeTaskRef.current.scrollIntoView !== "function")
68
+ return;
69
+ activeTaskRef.current.scrollIntoView({ block: "nearest" });
70
+ }, [activeTaskId, scrollActiveIntoView]);
71
+ if (hideWhenEmpty && total === 0 || hideWhenComplete && total > 0 && completed === total) return null;
72
+ return /* @__PURE__ */ jsxRuntime.jsxs(TaskListContainer, { "aria-label": "Task list", "data-testid": "task-list", ...props, children: [
73
+ /* @__PURE__ */ jsxRuntime.jsxs(TaskListHeader, { children: [
74
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListChecks, { className: "size-4 shrink-0 text-accent6" }),
75
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-ui-sm leading-ui-sm font-medium text-neutral6", children: title }),
76
+ /* @__PURE__ */ jsxRuntime.jsx(TaskListCount, { completed, total })
77
+ ] }),
78
+ /* @__PURE__ */ jsxRuntime.jsx(TaskListProgress, { completed, total }),
79
+ /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "max-h-32 space-y-1 overflow-y-auto pr-1", children: tasks.map((task) => /* @__PURE__ */ jsxRuntime.jsx(TaskListRow, { ref: task.id === activeTaskId ? activeTaskRef : void 0, task }, task.id)) })
80
+ ] });
81
+ };
82
+
83
+ exports.TaskList = TaskList;
84
+ exports.TaskListContainer = TaskListContainer;
85
+ exports.TaskListCount = TaskListCount;
86
+ exports.TaskListHeader = TaskListHeader;
87
+ exports.TaskListProgress = TaskListProgress;
88
+ exports.TaskListRow = TaskListRow;
89
+ exports.TaskListStatusIcon = TaskListStatusIcon;
90
+ //# sourceMappingURL=task-list.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-list.cjs.js","sources":["../../../src/ds/components/ai/task-list/task-list.tsx"],"sourcesContent":["import type { TaskItem } from '@mastra/core/signals';\nimport { CheckCircle2, Circle, ListChecks, Loader2 } from 'lucide-react';\nimport { useEffect, useRef } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport type TaskListItem = TaskItem;\n\nexport const TaskListContainer = ({ className, ...props }: ComponentProps<'section'>) => (\n <section className={cn('rounded-2xl border border-border2/40 bg-surface3 px-3 py-2.5', className)} {...props} />\n);\n\nexport const TaskListHeader = ({ className, ...props }: ComponentProps<'header'>) => (\n <header className={cn('mb-2 flex items-center gap-2', className)} {...props} />\n);\n\nexport interface TaskListCountProps extends ComponentProps<'span'> {\n completed: number;\n total: number;\n}\n\nexport const TaskListCount = ({ completed, total, className, ...props }: TaskListCountProps) => (\n <span className={cn('ml-auto text-ui-xs text-neutral4 tabular-nums', className)} {...props}>\n {completed}/{total} completed\n </span>\n);\n\nexport interface TaskListProgressProps extends Omit<ComponentProps<'div'>, 'children'> {\n completed: number;\n total: number;\n}\n\nexport const TaskListProgress = ({ completed, total, className, ...props }: TaskListProgressProps) => {\n const percentage = total === 0 ? 0 : (completed / total) * 100;\n return (\n <div\n role=\"progressbar\"\n aria-label=\"Task completion\"\n aria-valuemin={0}\n aria-valuemax={total}\n aria-valuenow={completed}\n className={cn('mb-2.5 h-1 w-full rounded-full bg-surface4', className)}\n {...props}\n >\n <div className=\"h-full rounded-full bg-accent6 transition-all duration-300\" style={{ width: `${percentage}%` }} />\n </div>\n );\n};\n\nconst icons: Record<TaskListItem['status'], ReactNode> = {\n completed: <CheckCircle2 className=\"size-3.5 shrink-0 text-positive1\" />,\n in_progress: <Loader2 className=\"size-3.5 shrink-0 text-warning1 motion-safe:animate-spin\" />,\n pending: <Circle className=\"size-3.5 shrink-0 text-neutral4\" />,\n};\n\nconst statusLabels: Record<TaskListItem['status'], string> = {\n completed: 'Completed',\n in_progress: 'In progress',\n pending: 'Pending',\n};\n\nconst textClasses: Record<TaskListItem['status'], string> = {\n completed: 'text-neutral4 line-through',\n in_progress: 'font-medium text-warning1',\n pending: 'text-neutral5',\n};\n\nexport interface TaskListStatusIconProps extends ComponentProps<'span'> {\n status: TaskListItem['status'];\n}\n\nexport const TaskListStatusIcon = ({ status, className, ...props }: TaskListStatusIconProps) => (\n <span aria-label={statusLabels[status]} className={cn('pt-0.5', className)} {...props}>\n {icons[status]}\n </span>\n);\n\nexport interface TaskListRowProps extends ComponentProps<'li'> {\n task: TaskListItem;\n}\n\nexport const TaskListRow = ({ task, className, ...props }: TaskListRowProps) => (\n <li className={cn('flex items-start gap-2 py-0.5', className)} {...props}>\n <TaskListStatusIcon status={task.status} />\n <span className={cn('text-ui-sm leading-ui-sm', textClasses[task.status])}>\n {task.status === 'in_progress' ? task.activeForm : task.content}\n </span>\n </li>\n);\n\nexport interface TaskListProps extends Omit<ComponentProps<typeof TaskListContainer>, 'children' | 'title'> {\n tasks: TaskListItem[];\n title?: ReactNode;\n hideWhenEmpty?: boolean;\n hideWhenComplete?: boolean;\n scrollActiveIntoView?: boolean;\n}\n\nexport const TaskList = ({\n tasks,\n title = 'Tasks',\n hideWhenEmpty = true,\n hideWhenComplete = true,\n scrollActiveIntoView = true,\n ...props\n}: TaskListProps) => {\n const activeTaskRef = useRef<HTMLLIElement | null>(null);\n const activeTaskId = tasks.find(task => task.status === 'in_progress')?.id;\n const completed = tasks.filter(task => task.status === 'completed').length;\n const total = tasks.length;\n\n useEffect(() => {\n if (!scrollActiveIntoView || !activeTaskRef.current || typeof activeTaskRef.current.scrollIntoView !== 'function')\n return;\n activeTaskRef.current.scrollIntoView({ block: 'nearest' });\n }, [activeTaskId, scrollActiveIntoView]);\n\n if ((hideWhenEmpty && total === 0) || (hideWhenComplete && total > 0 && completed === total)) return null;\n\n return (\n <TaskListContainer aria-label=\"Task list\" data-testid=\"task-list\" {...props}>\n <TaskListHeader>\n <ListChecks className=\"size-4 shrink-0 text-accent6\" />\n <h2 className=\"text-ui-sm leading-ui-sm font-medium text-neutral6\">{title}</h2>\n <TaskListCount completed={completed} total={total} />\n </TaskListHeader>\n <TaskListProgress completed={completed} total={total} />\n <ul className=\"max-h-32 space-y-1 overflow-y-auto pr-1\">\n {tasks.map(task => (\n <TaskListRow key={task.id} ref={task.id === activeTaskId ? activeTaskRef : undefined} task={task} />\n ))}\n </ul>\n </TaskListContainer>\n );\n};\n"],"names":["jsx","cn","jsxs","CheckCircle2","Loader2","Circle","useRef","useEffect","ListChecks"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export * from '../../src/ds/components/ai/task-list/index'
2
+ export {}
@@ -0,0 +1,80 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { ListChecks, Circle, Loader2, CheckCircle2 } from 'lucide-react';
3
+ import { useRef, useEffect } from 'react';
4
+ import { c as cn } from '../../cn-BakJzhuv.js';
5
+
6
+ const TaskListContainer = ({ className, ...props }) => /* @__PURE__ */ jsx("section", { className: cn("rounded-2xl border border-border2/40 bg-surface3 px-3 py-2.5", className), ...props });
7
+ const TaskListHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("header", { className: cn("mb-2 flex items-center gap-2", className), ...props });
8
+ const TaskListCount = ({ completed, total, className, ...props }) => /* @__PURE__ */ jsxs("span", { className: cn("ml-auto text-ui-xs text-neutral4 tabular-nums", className), ...props, children: [
9
+ completed,
10
+ "/",
11
+ total,
12
+ " completed"
13
+ ] });
14
+ const TaskListProgress = ({ completed, total, className, ...props }) => {
15
+ const percentage = total === 0 ? 0 : completed / total * 100;
16
+ return /* @__PURE__ */ jsx(
17
+ "div",
18
+ {
19
+ role: "progressbar",
20
+ "aria-label": "Task completion",
21
+ "aria-valuemin": 0,
22
+ "aria-valuemax": total,
23
+ "aria-valuenow": completed,
24
+ className: cn("mb-2.5 h-1 w-full rounded-full bg-surface4", className),
25
+ ...props,
26
+ children: /* @__PURE__ */ jsx("div", { className: "h-full rounded-full bg-accent6 transition-all duration-300", style: { width: `${percentage}%` } })
27
+ }
28
+ );
29
+ };
30
+ const icons = {
31
+ completed: /* @__PURE__ */ jsx(CheckCircle2, { className: "size-3.5 shrink-0 text-positive1" }),
32
+ in_progress: /* @__PURE__ */ jsx(Loader2, { className: "size-3.5 shrink-0 text-warning1 motion-safe:animate-spin" }),
33
+ pending: /* @__PURE__ */ jsx(Circle, { className: "size-3.5 shrink-0 text-neutral4" })
34
+ };
35
+ const statusLabels = {
36
+ completed: "Completed",
37
+ in_progress: "In progress",
38
+ pending: "Pending"
39
+ };
40
+ const textClasses = {
41
+ completed: "text-neutral4 line-through",
42
+ in_progress: "font-medium text-warning1",
43
+ pending: "text-neutral5"
44
+ };
45
+ const TaskListStatusIcon = ({ status, className, ...props }) => /* @__PURE__ */ jsx("span", { "aria-label": statusLabels[status], className: cn("pt-0.5", className), ...props, children: icons[status] });
46
+ const TaskListRow = ({ task, className, ...props }) => /* @__PURE__ */ jsxs("li", { className: cn("flex items-start gap-2 py-0.5", className), ...props, children: [
47
+ /* @__PURE__ */ jsx(TaskListStatusIcon, { status: task.status }),
48
+ /* @__PURE__ */ jsx("span", { className: cn("text-ui-sm leading-ui-sm", textClasses[task.status]), children: task.status === "in_progress" ? task.activeForm : task.content })
49
+ ] });
50
+ const TaskList = ({
51
+ tasks,
52
+ title = "Tasks",
53
+ hideWhenEmpty = true,
54
+ hideWhenComplete = true,
55
+ scrollActiveIntoView = true,
56
+ ...props
57
+ }) => {
58
+ const activeTaskRef = useRef(null);
59
+ const activeTaskId = tasks.find((task) => task.status === "in_progress")?.id;
60
+ const completed = tasks.filter((task) => task.status === "completed").length;
61
+ const total = tasks.length;
62
+ useEffect(() => {
63
+ if (!scrollActiveIntoView || !activeTaskRef.current || typeof activeTaskRef.current.scrollIntoView !== "function")
64
+ return;
65
+ activeTaskRef.current.scrollIntoView({ block: "nearest" });
66
+ }, [activeTaskId, scrollActiveIntoView]);
67
+ if (hideWhenEmpty && total === 0 || hideWhenComplete && total > 0 && completed === total) return null;
68
+ return /* @__PURE__ */ jsxs(TaskListContainer, { "aria-label": "Task list", "data-testid": "task-list", ...props, children: [
69
+ /* @__PURE__ */ jsxs(TaskListHeader, { children: [
70
+ /* @__PURE__ */ jsx(ListChecks, { className: "size-4 shrink-0 text-accent6" }),
71
+ /* @__PURE__ */ jsx("h2", { className: "text-ui-sm leading-ui-sm font-medium text-neutral6", children: title }),
72
+ /* @__PURE__ */ jsx(TaskListCount, { completed, total })
73
+ ] }),
74
+ /* @__PURE__ */ jsx(TaskListProgress, { completed, total }),
75
+ /* @__PURE__ */ jsx("ul", { className: "max-h-32 space-y-1 overflow-y-auto pr-1", children: tasks.map((task) => /* @__PURE__ */ jsx(TaskListRow, { ref: task.id === activeTaskId ? activeTaskRef : void 0, task }, task.id)) })
76
+ ] });
77
+ };
78
+
79
+ export { TaskList, TaskListContainer, TaskListCount, TaskListHeader, TaskListProgress, TaskListRow, TaskListStatusIcon };
80
+ //# sourceMappingURL=task-list.es.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-list.es.js","sources":["../../../src/ds/components/ai/task-list/task-list.tsx"],"sourcesContent":["import type { TaskItem } from '@mastra/core/signals';\nimport { CheckCircle2, Circle, ListChecks, Loader2 } from 'lucide-react';\nimport { useEffect, useRef } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport type TaskListItem = TaskItem;\n\nexport const TaskListContainer = ({ className, ...props }: ComponentProps<'section'>) => (\n <section className={cn('rounded-2xl border border-border2/40 bg-surface3 px-3 py-2.5', className)} {...props} />\n);\n\nexport const TaskListHeader = ({ className, ...props }: ComponentProps<'header'>) => (\n <header className={cn('mb-2 flex items-center gap-2', className)} {...props} />\n);\n\nexport interface TaskListCountProps extends ComponentProps<'span'> {\n completed: number;\n total: number;\n}\n\nexport const TaskListCount = ({ completed, total, className, ...props }: TaskListCountProps) => (\n <span className={cn('ml-auto text-ui-xs text-neutral4 tabular-nums', className)} {...props}>\n {completed}/{total} completed\n </span>\n);\n\nexport interface TaskListProgressProps extends Omit<ComponentProps<'div'>, 'children'> {\n completed: number;\n total: number;\n}\n\nexport const TaskListProgress = ({ completed, total, className, ...props }: TaskListProgressProps) => {\n const percentage = total === 0 ? 0 : (completed / total) * 100;\n return (\n <div\n role=\"progressbar\"\n aria-label=\"Task completion\"\n aria-valuemin={0}\n aria-valuemax={total}\n aria-valuenow={completed}\n className={cn('mb-2.5 h-1 w-full rounded-full bg-surface4', className)}\n {...props}\n >\n <div className=\"h-full rounded-full bg-accent6 transition-all duration-300\" style={{ width: `${percentage}%` }} />\n </div>\n );\n};\n\nconst icons: Record<TaskListItem['status'], ReactNode> = {\n completed: <CheckCircle2 className=\"size-3.5 shrink-0 text-positive1\" />,\n in_progress: <Loader2 className=\"size-3.5 shrink-0 text-warning1 motion-safe:animate-spin\" />,\n pending: <Circle className=\"size-3.5 shrink-0 text-neutral4\" />,\n};\n\nconst statusLabels: Record<TaskListItem['status'], string> = {\n completed: 'Completed',\n in_progress: 'In progress',\n pending: 'Pending',\n};\n\nconst textClasses: Record<TaskListItem['status'], string> = {\n completed: 'text-neutral4 line-through',\n in_progress: 'font-medium text-warning1',\n pending: 'text-neutral5',\n};\n\nexport interface TaskListStatusIconProps extends ComponentProps<'span'> {\n status: TaskListItem['status'];\n}\n\nexport const TaskListStatusIcon = ({ status, className, ...props }: TaskListStatusIconProps) => (\n <span aria-label={statusLabels[status]} className={cn('pt-0.5', className)} {...props}>\n {icons[status]}\n </span>\n);\n\nexport interface TaskListRowProps extends ComponentProps<'li'> {\n task: TaskListItem;\n}\n\nexport const TaskListRow = ({ task, className, ...props }: TaskListRowProps) => (\n <li className={cn('flex items-start gap-2 py-0.5', className)} {...props}>\n <TaskListStatusIcon status={task.status} />\n <span className={cn('text-ui-sm leading-ui-sm', textClasses[task.status])}>\n {task.status === 'in_progress' ? task.activeForm : task.content}\n </span>\n </li>\n);\n\nexport interface TaskListProps extends Omit<ComponentProps<typeof TaskListContainer>, 'children' | 'title'> {\n tasks: TaskListItem[];\n title?: ReactNode;\n hideWhenEmpty?: boolean;\n hideWhenComplete?: boolean;\n scrollActiveIntoView?: boolean;\n}\n\nexport const TaskList = ({\n tasks,\n title = 'Tasks',\n hideWhenEmpty = true,\n hideWhenComplete = true,\n scrollActiveIntoView = true,\n ...props\n}: TaskListProps) => {\n const activeTaskRef = useRef<HTMLLIElement | null>(null);\n const activeTaskId = tasks.find(task => task.status === 'in_progress')?.id;\n const completed = tasks.filter(task => task.status === 'completed').length;\n const total = tasks.length;\n\n useEffect(() => {\n if (!scrollActiveIntoView || !activeTaskRef.current || typeof activeTaskRef.current.scrollIntoView !== 'function')\n return;\n activeTaskRef.current.scrollIntoView({ block: 'nearest' });\n }, [activeTaskId, scrollActiveIntoView]);\n\n if ((hideWhenEmpty && total === 0) || (hideWhenComplete && total > 0 && completed === total)) return null;\n\n return (\n <TaskListContainer aria-label=\"Task list\" data-testid=\"task-list\" {...props}>\n <TaskListHeader>\n <ListChecks className=\"size-4 shrink-0 text-accent6\" />\n <h2 className=\"text-ui-sm leading-ui-sm font-medium text-neutral6\">{title}</h2>\n <TaskListCount completed={completed} total={total} />\n </TaskListHeader>\n <TaskListProgress completed={completed} total={total} />\n <ul className=\"max-h-32 space-y-1 overflow-y-auto pr-1\">\n {tasks.map(task => (\n <TaskListRow key={task.id} ref={task.id === activeTaskId ? activeTaskRef : undefined} task={task} />\n ))}\n </ul>\n </TaskListContainer>\n );\n};\n"],"names":[],"mappings":"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"}
@@ -10,11 +10,11 @@ import ReactCodeMirror from '@uiw/react-codemirror';
10
10
  import { AlignLeftIcon, AlignJustifyIcon, ExpandIcon, XIcon } from 'lucide-react';
11
11
  import { useState, useRef, useMemo, useCallback } from 'react';
12
12
  import { B as Button } from './Button-Dh5CZ6Ir.js';
13
- import { B as ButtonsGroup } from './buttons-group-b6an6uao.js';
13
+ import { B as ButtonsGroup } from './buttons-group-DJh4wnMs.js';
14
14
  import { C as CopyButton } from './copy-button-BuIpvUI7.js';
15
15
  import { c as cn } from './cn-BakJzhuv.js';
16
16
  import { D as Dialog, c as DialogContent, f as DialogHeader, i as DialogTitle, d as DialogDescription, b as DialogClose } from './dialog-DhjOHEDT.js';
17
- import { S as SearchFieldBlock } from './search-field-block-e9qthuwY.js';
17
+ import { S as SearchFieldBlock } from './search-field-block-CMoQ9fjl.js';
18
18
  import { u as useTheme } from './theme-provider-C9ih9jSS.js';
19
19
 
20
20
  function DataPanelSectionHeading({ icon, className, children }) {
@@ -329,4 +329,4 @@ function containsInnerNewline(obj) {
329
329
  }
330
330
 
331
331
  export { DataCodeSection as D, DataPanelSectionHeading as a };
332
- //# sourceMappingURL=data-code-section-Crs5wpnX.js.map
332
+ //# sourceMappingURL=data-code-section-BjqDCzy3.js.map