sparkdesign 0.0.1 → 0.2.6

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 (403) hide show
  1. package/README.md +279 -5
  2. package/cli/dist/commands/add.js +84 -0
  3. package/cli/dist/commands/diff.js +54 -0
  4. package/cli/dist/commands/init.js +96 -0
  5. package/cli/dist/commands/list.js +25 -0
  6. package/cli/dist/index.js +37 -0
  7. package/cli/dist/utils/config.js +53 -0
  8. package/cli/dist/utils/registry.js +34 -0
  9. package/cli/dist/utils/tokens.js +90 -0
  10. package/cli/dist/utils/transform.js +19 -0
  11. package/cli/registry/basic/alert-dialog.tsx +180 -0
  12. package/cli/registry/basic/avatar.tsx +120 -0
  13. package/cli/registry/basic/button.tsx +100 -0
  14. package/cli/registry/basic/collapse.tsx +94 -0
  15. package/cli/registry/basic/collapsible-card.tsx +230 -0
  16. package/cli/registry/basic/collapsible.tsx +21 -0
  17. package/cli/registry/basic/dropdown-menu.tsx +254 -0
  18. package/cli/registry/basic/icon-button.tsx +66 -0
  19. package/cli/registry/basic/icons-inline.tsx +206 -0
  20. package/cli/registry/basic/kbd.tsx +50 -0
  21. package/cli/registry/basic/option-list.tsx +125 -0
  22. package/cli/registry/basic/pagination.tsx +132 -0
  23. package/cli/registry/basic/progress.tsx +42 -0
  24. package/cli/registry/basic/radio-group.tsx +69 -0
  25. package/cli/registry/basic/resizable.tsx +67 -0
  26. package/cli/registry/basic/scrollbar.tsx +114 -0
  27. package/cli/registry/basic/select.tsx +177 -0
  28. package/cli/registry/basic/skeleton.tsx +33 -0
  29. package/cli/registry/basic/slider.tsx +55 -0
  30. package/cli/registry/basic/sonner.tsx +104 -0
  31. package/cli/registry/basic/spinner.tsx +17 -0
  32. package/cli/registry/basic/switch.tsx +49 -0
  33. package/cli/registry/basic/table.tsx +117 -0
  34. package/cli/registry/basic/tabs.tsx +85 -0
  35. package/cli/registry/basic/tag.tsx +161 -0
  36. package/cli/registry/basic/theme-from-document.ts +10 -0
  37. package/cli/registry/basic/toggle.tsx +223 -0
  38. package/cli/registry/basic/tooltip.tsx +80 -0
  39. package/cli/registry/basic/typography.tsx +201 -0
  40. package/cli/registry/chat/browser-use-part.tsx +166 -0
  41. package/cli/registry/chat/chat-input/chat-input-folder-selector.tsx +185 -0
  42. package/cli/registry/chat/chat-input/chat-input-model-switcher.tsx +131 -0
  43. package/cli/registry/chat/chat-input/chat-input-textarea.tsx +67 -0
  44. package/cli/registry/chat/chat-input/compound.tsx +334 -0
  45. package/cli/registry/chat/chat-input/context.tsx +189 -0
  46. package/cli/registry/chat/chat-input/folder-permission-dialog.tsx +61 -0
  47. package/cli/registry/chat/chat-input/index.tsx +123 -0
  48. package/cli/registry/chat/chat-input/types.ts +77 -0
  49. package/cli/registry/chat/chat-input/useAutoResizeTextarea.ts +20 -0
  50. package/cli/registry/chat/code-block-part.tsx +151 -0
  51. package/cli/registry/chat/file-attachment.tsx +44 -0
  52. package/cli/registry/chat/file-card.tsx +68 -0
  53. package/cli/registry/chat/file-review-part.tsx +259 -0
  54. package/cli/registry/chat/folder-button.tsx +169 -0
  55. package/cli/registry/chat/generated-images-grid.tsx +56 -0
  56. package/cli/registry/chat/generation-status-bar.tsx +72 -0
  57. package/cli/registry/chat/image-attachment.tsx +166 -0
  58. package/cli/registry/chat/image-generating.tsx +281 -0
  59. package/cli/registry/chat/markdown.tsx +146 -0
  60. package/cli/registry/chat/mermaid-part.tsx +90 -0
  61. package/cli/registry/chat/permission-card.tsx +178 -0
  62. package/cli/registry/chat/plan-part.tsx +168 -0
  63. package/cli/registry/chat/question-part.tsx +70 -0
  64. package/cli/registry/chat/queue-indicator.tsx +234 -0
  65. package/cli/registry/chat/reasoning-step.tsx +358 -0
  66. package/cli/registry/chat/related-prompts.tsx +91 -0
  67. package/cli/registry/chat/request.tsx +38 -0
  68. package/cli/registry/chat/response.tsx +271 -0
  69. package/cli/registry/chat/send-button.tsx +94 -0
  70. package/cli/registry/chat/sidebar-menu.tsx +177 -0
  71. package/cli/registry/chat/streaming-markdown-block.tsx +111 -0
  72. package/cli/registry/chat/suggestion-part.tsx +165 -0
  73. package/cli/registry/chat/task-part.tsx +109 -0
  74. package/cli/registry/chat/terminal-code-block-part.tsx +69 -0
  75. package/cli/registry/chat/thinking-indicator.tsx +91 -0
  76. package/cli/registry/chat/tool-invocation-card.tsx +132 -0
  77. package/cli/registry/chat/user-question/UserQuestionCard.tsx +198 -0
  78. package/cli/registry/chat/user-question/UserQuestionFooter.tsx +66 -0
  79. package/cli/registry/chat/user-question/UserQuestionHeader.tsx +64 -0
  80. package/cli/registry/chat/user-question/index.tsx +340 -0
  81. package/cli/registry/chat/user-question/types.ts +61 -0
  82. package/cli/registry/chat/user-question/useUserQuestionKeyboard.ts +127 -0
  83. package/cli/registry/chat/user-question/useUserQuestionState.ts +165 -0
  84. package/cli/registry/chat/user-question-answer.tsx +62 -0
  85. package/cli/registry/lib/file-icon-maps.ts +150 -0
  86. package/cli/registry/lib/use-mermaid-render.ts +76 -0
  87. package/cli/registry/lib/utils.ts +6 -0
  88. package/cli/registry/meta.json +1 -0
  89. package/cli/registry/tokens/scale.css +299 -0
  90. package/cli/registry/tokens/theme.css +633 -0
  91. package/dist/_basePickBy-DnQN8w3y.js +151 -0
  92. package/dist/_basePickBy-a-kPMlkg.cjs +1 -0
  93. package/dist/_baseUniq-B-N2NQ50.js +614 -0
  94. package/dist/_baseUniq-Cc_zbSif.cjs +1 -0
  95. package/dist/arc-BQBhijZ6.js +83 -0
  96. package/dist/arc-mWQt0Yph.cjs +1 -0
  97. package/dist/architectureDiagram-VXUJARFQ-BMZEucno.cjs +36 -0
  98. package/dist/architectureDiagram-VXUJARFQ-DTdjD3Bp.js +4661 -0
  99. package/dist/blockDiagram-VD42YOAC-CzHn0yob.js +2256 -0
  100. package/dist/blockDiagram-VD42YOAC-DDxdHAlz.cjs +122 -0
  101. package/dist/c4Diagram-YG6GDRKO-4Gz0I4gj.cjs +10 -0
  102. package/dist/c4Diagram-YG6GDRKO-BIy--yVN.js +1580 -0
  103. package/dist/channel-BQn0o8bs.js +5 -0
  104. package/dist/channel-DaN7XniJ.cjs +1 -0
  105. package/dist/chunk-4BX2VUAB-BlQFTQqz.cjs +1 -0
  106. package/dist/chunk-4BX2VUAB-Czitj3Kc.js +8 -0
  107. package/dist/chunk-55IACEB6-DXacNZbO.js +8 -0
  108. package/dist/chunk-55IACEB6-DnDxpye9.cjs +1 -0
  109. package/dist/chunk-B4BG7PRW-CBdN0q_V.js +1375 -0
  110. package/dist/chunk-B4BG7PRW-DbGvUkGO.cjs +165 -0
  111. package/dist/chunk-DI55MBZ5-D1YJMs6x.cjs +220 -0
  112. package/dist/chunk-DI55MBZ5-NCQTvayw.js +1370 -0
  113. package/dist/chunk-FMBD7UC4-CsGMbrtr.js +19 -0
  114. package/dist/chunk-FMBD7UC4-Di7cUUh5.cjs +15 -0
  115. package/dist/chunk-QN33PNHL-0j5LC8Lm.cjs +1 -0
  116. package/dist/chunk-QN33PNHL-3GERZBRm.js +19 -0
  117. package/dist/chunk-QZHKN3VN-AVEY9ImQ.js +15 -0
  118. package/dist/chunk-QZHKN3VN-s8Z0a8mc.cjs +1 -0
  119. package/dist/chunk-TZMSLE5B-CAf87HPt.cjs +1 -0
  120. package/dist/chunk-TZMSLE5B-sbiflal0.js +64 -0
  121. package/dist/classDiagram-2ON5EDUG-Ct9JLIN2.cjs +1 -0
  122. package/dist/classDiagram-2ON5EDUG-Dzfrft3a.js +16 -0
  123. package/dist/classDiagram-v2-WZHVMYZB-Ct9JLIN2.cjs +1 -0
  124. package/dist/classDiagram-v2-WZHVMYZB-Dzfrft3a.js +16 -0
  125. package/dist/clone-Cde_NQ8V.js +8 -0
  126. package/dist/clone-DCNjWuM2.cjs +1 -0
  127. package/dist/cose-bilkent-S5V4N54A-0uLijMro.cjs +1 -0
  128. package/dist/cose-bilkent-S5V4N54A-Bb08N431.js +2608 -0
  129. package/dist/cytoscape.esm-CNUX3VTg.cjs +321 -0
  130. package/dist/cytoscape.esm-Cvf3sx9F.js +18704 -0
  131. package/dist/dagre-6UL2VRFP-CY_Wz5Zd.js +444 -0
  132. package/dist/dagre-6UL2VRFP-Dxe7_qZc.cjs +4 -0
  133. package/dist/defaultLocale-BgPVtth8.js +171 -0
  134. package/dist/defaultLocale-C4wbwF1n.cjs +1 -0
  135. package/dist/diagram-PSM6KHXK-D2bdb7MT.js +531 -0
  136. package/dist/diagram-PSM6KHXK-YF69SUjY.cjs +24 -0
  137. package/dist/diagram-QEK2KX5R-BpUSoh0-.js +217 -0
  138. package/dist/diagram-QEK2KX5R-DZPGteon.cjs +43 -0
  139. package/dist/diagram-S2PKOQOG-ht-zdvFG.cjs +24 -0
  140. package/dist/diagram-S2PKOQOG-zFeLJ50Z.js +142 -0
  141. package/dist/erDiagram-Q2GNP2WA-B38iJ6ts.js +841 -0
  142. package/dist/erDiagram-Q2GNP2WA-RgS80DDU.cjs +60 -0
  143. package/dist/flowDiagram-NV44I4VS-BHilOs2p.cjs +162 -0
  144. package/dist/flowDiagram-NV44I4VS-BrBJcoce.js +1620 -0
  145. package/dist/fonts/KaTeX_AMS-Regular.ttf +0 -0
  146. package/dist/fonts/KaTeX_AMS-Regular.woff +0 -0
  147. package/dist/fonts/KaTeX_AMS-Regular.woff2 +0 -0
  148. package/dist/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
  149. package/dist/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
  150. package/dist/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
  151. package/dist/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
  152. package/dist/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
  153. package/dist/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
  154. package/dist/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
  155. package/dist/fonts/KaTeX_Fraktur-Bold.woff +0 -0
  156. package/dist/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
  157. package/dist/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
  158. package/dist/fonts/KaTeX_Fraktur-Regular.woff +0 -0
  159. package/dist/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
  160. package/dist/fonts/KaTeX_Main-Bold.ttf +0 -0
  161. package/dist/fonts/KaTeX_Main-Bold.woff +0 -0
  162. package/dist/fonts/KaTeX_Main-Bold.woff2 +0 -0
  163. package/dist/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
  164. package/dist/fonts/KaTeX_Main-BoldItalic.woff +0 -0
  165. package/dist/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
  166. package/dist/fonts/KaTeX_Main-Italic.ttf +0 -0
  167. package/dist/fonts/KaTeX_Main-Italic.woff +0 -0
  168. package/dist/fonts/KaTeX_Main-Italic.woff2 +0 -0
  169. package/dist/fonts/KaTeX_Main-Regular.ttf +0 -0
  170. package/dist/fonts/KaTeX_Main-Regular.woff +0 -0
  171. package/dist/fonts/KaTeX_Main-Regular.woff2 +0 -0
  172. package/dist/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
  173. package/dist/fonts/KaTeX_Math-BoldItalic.woff +0 -0
  174. package/dist/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
  175. package/dist/fonts/KaTeX_Math-Italic.ttf +0 -0
  176. package/dist/fonts/KaTeX_Math-Italic.woff +0 -0
  177. package/dist/fonts/KaTeX_Math-Italic.woff2 +0 -0
  178. package/dist/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
  179. package/dist/fonts/KaTeX_SansSerif-Bold.woff +0 -0
  180. package/dist/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
  181. package/dist/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
  182. package/dist/fonts/KaTeX_SansSerif-Italic.woff +0 -0
  183. package/dist/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
  184. package/dist/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
  185. package/dist/fonts/KaTeX_SansSerif-Regular.woff +0 -0
  186. package/dist/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
  187. package/dist/fonts/KaTeX_Script-Regular.ttf +0 -0
  188. package/dist/fonts/KaTeX_Script-Regular.woff +0 -0
  189. package/dist/fonts/KaTeX_Script-Regular.woff2 +0 -0
  190. package/dist/fonts/KaTeX_Size1-Regular.ttf +0 -0
  191. package/dist/fonts/KaTeX_Size1-Regular.woff +0 -0
  192. package/dist/fonts/KaTeX_Size1-Regular.woff2 +0 -0
  193. package/dist/fonts/KaTeX_Size2-Regular.ttf +0 -0
  194. package/dist/fonts/KaTeX_Size2-Regular.woff +0 -0
  195. package/dist/fonts/KaTeX_Size2-Regular.woff2 +0 -0
  196. package/dist/fonts/KaTeX_Size3-Regular.ttf +0 -0
  197. package/dist/fonts/KaTeX_Size3-Regular.woff +0 -0
  198. package/dist/fonts/KaTeX_Size3-Regular.woff2 +0 -0
  199. package/dist/fonts/KaTeX_Size4-Regular.ttf +0 -0
  200. package/dist/fonts/KaTeX_Size4-Regular.woff +0 -0
  201. package/dist/fonts/KaTeX_Size4-Regular.woff2 +0 -0
  202. package/dist/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
  203. package/dist/fonts/KaTeX_Typewriter-Regular.woff +0 -0
  204. package/dist/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
  205. package/dist/ganttDiagram-JELNMOA3-pZiJeFio.cjs +267 -0
  206. package/dist/ganttDiagram-JELNMOA3-tw6FhkWJ.js +2670 -0
  207. package/dist/gitGraphDiagram-V2S2FVAM-BWn5uIK5.js +699 -0
  208. package/dist/gitGraphDiagram-V2S2FVAM-DKKeG-9R.cjs +65 -0
  209. package/dist/graph-DIbblrZP.cjs +1 -0
  210. package/dist/graph-DPcK91G3.js +247 -0
  211. package/dist/infoDiagram-HS3SLOUP-B8gwwhct.cjs +2 -0
  212. package/dist/infoDiagram-HS3SLOUP-D47PNcP_.js +24 -0
  213. package/dist/init-CHZsXQcr.cjs +1 -0
  214. package/dist/init-DjUOC4st.js +16 -0
  215. package/dist/journeyDiagram-XKPGCS4Q-BG3cfhyU.js +834 -0
  216. package/dist/journeyDiagram-XKPGCS4Q-D8DVLJof.cjs +139 -0
  217. package/dist/kanban-definition-3W4ZIXB7-4OCnEouP.cjs +89 -0
  218. package/dist/kanban-definition-3W4ZIXB7-CWi_ssF9.js +719 -0
  219. package/dist/katex.css +1 -0
  220. package/dist/layout-Byuh8f-J.cjs +1 -0
  221. package/dist/layout-CdLdvj1j.js +1335 -0
  222. package/dist/linear-C2Q_PI9B.js +259 -0
  223. package/dist/linear-C69aPBW1.cjs +1 -0
  224. package/dist/mermaid.core-DBwAx_jp.cjs +249 -0
  225. package/dist/mermaid.core-gFR0XUlD.js +15300 -0
  226. package/dist/mindmap-definition-VGOIOE7T-8P7obVV4.cjs +68 -0
  227. package/dist/mindmap-definition-VGOIOE7T-DnOa7WJ9.js +784 -0
  228. package/dist/ordinal-B6-f3MAq.js +61 -0
  229. package/dist/ordinal-CagbB1m8.cjs +1 -0
  230. package/dist/pieDiagram-ADFJNKIX-5NAlvhMo.js +161 -0
  231. package/dist/pieDiagram-ADFJNKIX-CQBG4yR9.cjs +30 -0
  232. package/dist/qoder-design.css +2 -0
  233. package/dist/quadrantDiagram-AYHSOK5B-Oe4y7RZ0.cjs +7 -0
  234. package/dist/quadrantDiagram-AYHSOK5B-rh2DPEP1.js +1022 -0
  235. package/dist/registry/basic/alert-dialog.d.ts +40 -0
  236. package/dist/registry/basic/avatar.d.ts +30 -0
  237. package/dist/registry/basic/button.d.ts +16 -0
  238. package/dist/registry/basic/collapse.d.ts +22 -0
  239. package/dist/registry/basic/collapsible-card.d.ts +34 -0
  240. package/dist/registry/basic/collapsible.d.ts +15 -0
  241. package/dist/registry/basic/dropdown-menu.d.ts +52 -0
  242. package/dist/registry/basic/icon-button.d.ts +12 -0
  243. package/dist/registry/basic/icons-inline.d.ts +51 -0
  244. package/dist/registry/basic/kbd.d.ts +23 -0
  245. package/dist/registry/basic/option-list.d.ts +16 -0
  246. package/dist/registry/basic/pagination.d.ts +33 -0
  247. package/dist/registry/basic/progress.d.ts +18 -0
  248. package/dist/registry/basic/radio-group.d.ts +25 -0
  249. package/dist/registry/basic/resizable.d.ts +318 -0
  250. package/dist/registry/basic/scrollbar.d.ts +12 -0
  251. package/dist/registry/basic/select.d.ts +35 -0
  252. package/dist/registry/basic/skeleton.d.ts +10 -0
  253. package/dist/registry/basic/slider.d.ts +16 -0
  254. package/dist/registry/basic/sonner.d.ts +23 -0
  255. package/dist/registry/basic/spinner.d.ts +5 -0
  256. package/dist/registry/basic/switch.d.ts +20 -0
  257. package/dist/registry/basic/table.d.ts +18 -0
  258. package/dist/registry/basic/tabs.d.ts +29 -0
  259. package/dist/registry/basic/tag.d.ts +23 -0
  260. package/dist/registry/basic/theme-from-document.d.ts +10 -0
  261. package/dist/registry/basic/toggle.d.ts +29 -0
  262. package/dist/registry/basic/tooltip.d.ts +34 -0
  263. package/dist/registry/basic/typography.d.ts +76 -0
  264. package/dist/registry/chat/browser-use-part.d.ts +28 -0
  265. package/dist/registry/chat/chat-input/chat-input-folder-selector.d.ts +22 -0
  266. package/dist/registry/chat/chat-input/chat-input-model-switcher.d.ts +12 -0
  267. package/dist/registry/chat/chat-input/chat-input-textarea.d.ts +9 -0
  268. package/dist/registry/chat/chat-input/compound.d.ts +97 -0
  269. package/dist/registry/chat/chat-input/context.d.ts +64 -0
  270. package/dist/registry/chat/chat-input/folder-permission-dialog.d.ts +11 -0
  271. package/dist/registry/chat/chat-input/index.d.ts +34 -0
  272. package/dist/registry/chat/chat-input/types.d.ts +79 -0
  273. package/dist/registry/chat/chat-input/useAutoResizeTextarea.d.ts +7 -0
  274. package/dist/registry/chat/code-block-part.d.ts +23 -0
  275. package/dist/registry/chat/file-attachment.d.ts +19 -0
  276. package/dist/registry/chat/file-card.d.ts +10 -0
  277. package/dist/registry/chat/file-review-part.d.ts +30 -0
  278. package/dist/registry/chat/folder-button.d.ts +20 -0
  279. package/dist/registry/chat/generated-images-grid.d.ts +15 -0
  280. package/dist/registry/chat/generation-status-bar.d.ts +19 -0
  281. package/dist/registry/chat/image-attachment.d.ts +19 -0
  282. package/dist/registry/chat/image-generating.d.ts +15 -0
  283. package/dist/registry/chat/markdown.d.ts +8 -0
  284. package/dist/registry/chat/mermaid-part.d.ts +17 -0
  285. package/dist/registry/chat/permission-card.d.ts +24 -0
  286. package/dist/registry/chat/plan-part.d.ts +30 -0
  287. package/dist/registry/chat/question-part.d.ts +24 -0
  288. package/dist/registry/chat/queue-indicator.d.ts +27 -0
  289. package/dist/registry/chat/reasoning-step.d.ts +35 -0
  290. package/dist/registry/chat/related-prompts.d.ts +23 -0
  291. package/dist/registry/chat/request.d.ts +6 -0
  292. package/dist/registry/chat/response.d.ts +28 -0
  293. package/dist/registry/chat/send-button.d.ts +17 -0
  294. package/dist/registry/chat/sidebar-menu.d.ts +23 -0
  295. package/dist/registry/chat/streaming-markdown-block.d.ts +8 -0
  296. package/dist/registry/chat/suggestion-part.d.ts +28 -0
  297. package/dist/registry/chat/task-part.d.ts +28 -0
  298. package/dist/registry/chat/terminal-code-block-part.d.ts +18 -0
  299. package/dist/registry/chat/thinking-indicator.d.ts +14 -0
  300. package/dist/registry/chat/tool-invocation-card.d.ts +20 -0
  301. package/dist/registry/chat/user-question/UserQuestionCard.d.ts +30 -0
  302. package/dist/registry/chat/user-question/UserQuestionFooter.d.ts +18 -0
  303. package/dist/registry/chat/user-question/UserQuestionHeader.d.ts +20 -0
  304. package/dist/registry/chat/user-question/index.d.ts +7 -0
  305. package/dist/registry/chat/user-question/types.d.ts +52 -0
  306. package/dist/registry/chat/user-question/useUserQuestionKeyboard.d.ts +18 -0
  307. package/dist/registry/chat/user-question/useUserQuestionState.d.ts +26 -0
  308. package/dist/registry/chat/user-question-answer.d.ts +13 -0
  309. package/dist/registry/lib/file-icon-maps.d.ts +20 -0
  310. package/dist/registry/lib/use-mermaid-render.d.ts +5 -0
  311. package/dist/registry/lib/utils.d.ts +11 -0
  312. package/dist/requirementDiagram-UZGBJVZJ-DcWaCuXr.js +850 -0
  313. package/dist/requirementDiagram-UZGBJVZJ-gfdlrFiq.cjs +64 -0
  314. package/dist/sankeyDiagram-TZEHDZUN-CQIKFwD0.js +810 -0
  315. package/dist/sankeyDiagram-TZEHDZUN-DvPtzQvC.cjs +10 -0
  316. package/dist/scale.css +307 -0
  317. package/dist/sequenceDiagram-WL72ISMW-BNrsMagL.cjs +145 -0
  318. package/dist/sequenceDiagram-WL72ISMW-iCX3ckKx.js +2511 -0
  319. package/dist/spark-design.cjs.js +265 -0
  320. package/dist/spark-design.es.js +13207 -0
  321. package/dist/src/components/chat/BrowserUsePart/index.d.ts +7 -0
  322. package/dist/src/components/chat/ChatInput/index.d.ts +29 -0
  323. package/dist/src/components/chat/CodeBlockPart/index.d.ts +7 -0
  324. package/dist/src/components/chat/CollapsibleCard/index.d.ts +7 -0
  325. package/dist/src/components/chat/FileAttachment/index.d.ts +3 -0
  326. package/dist/src/components/chat/FileCard/index.d.ts +3 -0
  327. package/dist/src/components/chat/FileReviewPart/index.d.ts +7 -0
  328. package/dist/src/components/chat/FolderButton/index.d.ts +5 -0
  329. package/dist/src/components/chat/GeneratedImagesGrid/index.d.ts +7 -0
  330. package/dist/src/components/chat/GenerationStatusBar/index.d.ts +7 -0
  331. package/dist/src/components/chat/ImageAttachment/index.d.ts +3 -0
  332. package/dist/src/components/chat/ImageGenerating/index.d.ts +6 -0
  333. package/dist/src/components/chat/Markdown/demo-content.d.ts +1 -0
  334. package/dist/src/components/chat/Markdown/index.d.ts +7 -0
  335. package/dist/src/components/chat/MermaidPart/index.d.ts +6 -0
  336. package/dist/src/components/chat/PermissionCard/index.d.ts +4 -0
  337. package/dist/src/components/chat/PlanPart/index.d.ts +6 -0
  338. package/dist/src/components/chat/QuestionPart/index.d.ts +6 -0
  339. package/dist/src/components/chat/QueueIndicator/index.d.ts +4 -0
  340. package/dist/src/components/chat/ReasoningStep/index.d.ts +7 -0
  341. package/dist/src/components/chat/RelatedPrompts/index.d.ts +6 -0
  342. package/dist/src/components/chat/Request/index.d.ts +7 -0
  343. package/dist/src/components/chat/Response/StreamingMarkdownBlock.d.ts +6 -0
  344. package/dist/src/components/chat/Response/index.d.ts +6 -0
  345. package/dist/src/components/chat/SendButton/index.d.ts +5 -0
  346. package/dist/src/components/chat/SidebarMenu/index.d.ts +4 -0
  347. package/dist/src/components/chat/SuggestionPart/index.d.ts +6 -0
  348. package/dist/src/components/chat/TaskPart/index.d.ts +7 -0
  349. package/dist/src/components/chat/TerminalCodeBlockPart/index.d.ts +6 -0
  350. package/dist/src/components/chat/ThinkingIndicator/index.d.ts +6 -0
  351. package/dist/src/components/chat/ToolInvocationCard/index.d.ts +4 -0
  352. package/dist/src/components/chat/UserQuestion/index.d.ts +5 -0
  353. package/dist/src/components/chat/UserQuestionAnswer/index.d.ts +3 -0
  354. package/dist/src/components/foundation/AlertDialog/index.d.ts +20 -0
  355. package/dist/src/components/foundation/Avatar/index.d.ts +7 -0
  356. package/dist/src/components/foundation/Button/index.d.ts +7 -0
  357. package/dist/src/components/foundation/Collapse/index.d.ts +15 -0
  358. package/dist/src/components/foundation/Collapsible/index.d.ts +7 -0
  359. package/dist/src/components/foundation/CollapsibleSection/index.d.ts +43 -0
  360. package/dist/src/components/foundation/DropdownMenu/index.d.ts +19 -0
  361. package/dist/src/components/foundation/EllipsisText/index.d.ts +53 -0
  362. package/dist/src/components/foundation/IconButton/index.d.ts +7 -0
  363. package/dist/src/components/foundation/Kbd/index.d.ts +7 -0
  364. package/dist/src/components/foundation/OptionList/index.d.ts +7 -0
  365. package/dist/src/components/foundation/Pagination/index.d.ts +7 -0
  366. package/dist/src/components/foundation/Progress/index.d.ts +7 -0
  367. package/dist/src/components/foundation/RadioGroup/index.d.ts +7 -0
  368. package/dist/src/components/foundation/Resizable/index.d.ts +7 -0
  369. package/dist/src/components/foundation/Scrollbar/index.d.ts +7 -0
  370. package/dist/src/components/foundation/Select/index.d.ts +17 -0
  371. package/dist/src/components/foundation/Skeleton/index.d.ts +7 -0
  372. package/dist/src/components/foundation/Slider/index.d.ts +7 -0
  373. package/dist/src/components/foundation/Spinner/index.d.ts +7 -0
  374. package/dist/src/components/foundation/Switch/index.d.ts +38 -0
  375. package/dist/src/components/foundation/Table/index.d.ts +7 -0
  376. package/dist/src/components/foundation/Tabs/index.d.ts +7 -0
  377. package/dist/src/components/foundation/Tag/index.d.ts +10 -0
  378. package/dist/src/components/foundation/Toast/index.d.ts +12 -0
  379. package/dist/src/components/foundation/Toggle/index.d.ts +7 -0
  380. package/dist/src/components/foundation/Tooltip/index.d.ts +21 -0
  381. package/dist/src/components/foundation/Typography/index.d.ts +7 -0
  382. package/dist/src/components/index.d.ts +136 -0
  383. package/dist/src/icons/context.d.ts +26 -0
  384. package/dist/src/icons/types.d.ts +18 -0
  385. package/dist/src/lib/ThemeStyleContext.d.ts +21 -0
  386. package/dist/src/lib/file-icon.d.ts +16 -0
  387. package/dist/src/lib/i18n.d.ts +12 -0
  388. package/dist/src/lib/index.d.ts +10 -0
  389. package/dist/src/lib/motion.d.ts +22 -0
  390. package/dist/src/lib/utils.d.ts +11 -0
  391. package/dist/stateDiagram-FKZM4ZOC-DBvJ_eeL.cjs +1 -0
  392. package/dist/stateDiagram-FKZM4ZOC-ZVsJlaHJ.js +263 -0
  393. package/dist/stateDiagram-v2-4FDKWEC3-CB_nTHcE.js +16 -0
  394. package/dist/stateDiagram-v2-4FDKWEC3-Xkx17v6T.cjs +1 -0
  395. package/dist/theme.css +804 -0
  396. package/dist/timeline-definition-IT6M3QCI-BmGkYQiz.cjs +61 -0
  397. package/dist/timeline-definition-IT6M3QCI-Ck8zTt6w.js +795 -0
  398. package/dist/treemap-GDKQZRPO-B9sfERx8.js +17922 -0
  399. package/dist/treemap-GDKQZRPO-BVfJRs0Z.cjs +160 -0
  400. package/dist/xychartDiagram-PRI3JC2R-By_S8NzN.js +1340 -0
  401. package/dist/xychartDiagram-PRI3JC2R-CNfDrGxM.cjs +7 -0
  402. package/package.json +111 -9
  403. package/index.js +0 -5
@@ -0,0 +1,178 @@
1
+ import { forwardRef, useState } from 'react'
2
+ import type { HTMLAttributes, ButtonHTMLAttributes } from 'react'
3
+ import { cn } from '@/lib/utils'
4
+ import type { ReactNode } from 'react'
5
+ import { Button } from '../basic/button'
6
+ import { CloseLine, WarningLine } from '../basic/icons-inline'
7
+ import { Scrollbar } from '../basic/scrollbar'
8
+
9
+ export interface PermissionCardAction extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children'> {
10
+ label: string
11
+ }
12
+
13
+ export interface PermissionCardProps extends HTMLAttributes<HTMLDivElement> {
14
+ title?: string
15
+ description?: string
16
+ command: string
17
+ commandIntent?: string
18
+ isLoadingIntent?: boolean
19
+ onClose?: () => void
20
+ actions?: {
21
+ deny?: PermissionCardAction
22
+ allowOnce?: PermissionCardAction
23
+ }
24
+ closeIcon?: ReactNode
25
+ warningIcon?: ReactNode
26
+ /** 主库 i18n:展开/折叠按钮文案 */
27
+ expandLabel?: string
28
+ collapseLabel?: string
29
+ commaLabel?: string
30
+ }
31
+
32
+ const COMMAND_COLLAPSE_THRESHOLD = 80
33
+
34
+ function omitLabel(a: PermissionCardAction | undefined): Omit<PermissionCardAction, 'label'> {
35
+ if (!a) return {}
36
+ const { label: _label, ...rest } = a
37
+ void _label
38
+ return rest
39
+ }
40
+
41
+ const defaultTitle = 'Permission required'
42
+ const defaultDescription = 'This action requires your permission.'
43
+ const defaultExpand = 'Expand'
44
+ const defaultCollapse = 'Collapse'
45
+ const defaultComma = ', '
46
+
47
+ export const PermissionCard = forwardRef<HTMLDivElement, PermissionCardProps>(
48
+ (
49
+ {
50
+ title,
51
+ description,
52
+ command,
53
+ commandIntent,
54
+ isLoadingIntent = false,
55
+ onClose,
56
+ actions,
57
+ className,
58
+ closeIcon,
59
+ warningIcon,
60
+ expandLabel = defaultExpand,
61
+ collapseLabel = defaultCollapse,
62
+ commaLabel = defaultComma,
63
+ ...props
64
+ },
65
+ ref
66
+ ) => {
67
+ const displayTitle = title ?? defaultTitle
68
+ const displayDescription = description ?? defaultDescription
69
+ const shouldCollapse = command.length > COMMAND_COLLAPSE_THRESHOLD
70
+ const [isExpanded, setIsExpanded] = useState(!shouldCollapse)
71
+ const defaultClose = closeIcon ?? <CloseLine className="h-3.5 w-3.5" />
72
+ const defaultWarning = warningIcon ?? <WarningLine className="h-4 w-4" />
73
+
74
+ return (
75
+ <div
76
+ ref={ref}
77
+ className={cn(
78
+ 'relative rounded-lg border border-border-tertiary bg-bg-base p-3',
79
+ className
80
+ )}
81
+ {...props}
82
+ >
83
+ {onClose && (
84
+ <button
85
+ type="button"
86
+ onClick={onClose}
87
+ className="absolute top-3 right-3 flex h-4 w-4 cursor-pointer items-center justify-center text-text-secondary transition-colors duration-200 hover:text-text"
88
+ aria-label="Close"
89
+ >
90
+ {defaultClose}
91
+ </button>
92
+ )}
93
+
94
+ <div className="mb-1 flex items-center gap-2">
95
+ <div className="flex h-4 w-4 shrink-0 items-center justify-center text-warning">
96
+ {defaultWarning}
97
+ </div>
98
+ <h3 className="min-w-0 flex-1 text-base leading-base font-semibold text-text">
99
+ {displayTitle}
100
+ </h3>
101
+ </div>
102
+
103
+ <p className="mb-2 ml-6 text-xs leading-xs text-text-tertiary">
104
+ {isLoadingIntent ? (
105
+ <span className="inline-flex items-center gap-1.5">
106
+ <div className="inline-block h-3 w-3 animate-spin rounded-full border-2 border-text-tertiary border-t-transparent" />
107
+ <span>{displayDescription}</span>
108
+ </span>
109
+ ) : (
110
+ <>
111
+ {displayDescription}
112
+ {commandIntent && <span>{commaLabel}{commandIntent}</span>}
113
+ </>
114
+ )}
115
+ </p>
116
+
117
+ <div className="mb-4 ml-6">
118
+ <div className="rounded p-2 bg-fill-tertiary">
119
+ {isExpanded || !shouldCollapse ? (
120
+ <div title={command}>
121
+ <Scrollbar
122
+ scrollbarVisibility="auto"
123
+ maxHeight={240}
124
+ className="text-xs leading-xs font-medium text-text break-all"
125
+ style={{ fontFamily: 'Fira Code, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace' }}
126
+ >
127
+ {command}
128
+ </Scrollbar>
129
+ </div>
130
+ ) : (
131
+ <div
132
+ className="text-xs leading-xs font-medium text-text break-all line-clamp-2 overflow-hidden"
133
+ style={{ fontFamily: 'Fira Code, ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace' }}
134
+ title={command}
135
+ >
136
+ {command}
137
+ </div>
138
+ )}
139
+ {shouldCollapse && (
140
+ <button
141
+ type="button"
142
+ onClick={() => setIsExpanded(!isExpanded)}
143
+ className="mt-1 flex items-center gap-1 text-xs leading-xs text-text-tertiary hover:text-text transition-colors"
144
+ >
145
+ {isExpanded ? collapseLabel : expandLabel}
146
+ </button>
147
+ )}
148
+ </div>
149
+ </div>
150
+
151
+ <div className="flex items-center justify-end gap-2">
152
+ {actions?.deny && (
153
+ <Button variant="ghost" {...omitLabel(actions.deny)}>
154
+ {actions.deny.label}
155
+ </Button>
156
+ )}
157
+ {actions?.allowOnce && (
158
+ <button
159
+ type="button"
160
+ className={cn(
161
+ 'rounded-full inline-flex items-center justify-center',
162
+ 'px-3 py-1 text-sm leading-sm font-medium',
163
+ 'text-text-on-primary bg-error',
164
+ 'cursor-pointer hover:opacity-90 active:opacity-95 transition-opacity',
165
+ 'disabled:opacity-50 disabled:cursor-not-allowed'
166
+ )}
167
+ {...omitLabel(actions.allowOnce)}
168
+ >
169
+ {actions.allowOnce.label}
170
+ </button>
171
+ )}
172
+ </div>
173
+ </div>
174
+ )
175
+ }
176
+ )
177
+
178
+ PermissionCard.displayName = 'PermissionCard'
@@ -0,0 +1,168 @@
1
+ import type { ReactNode } from 'react'
2
+ import { cn } from '@/lib/utils'
3
+ import { CollapsibleCard } from '../basic/collapsible-card'
4
+ import { Button } from '../basic/button'
5
+ import { IconButton } from '../basic/icon-button'
6
+ import { FileList2Line, CheckLine, DownloadLine } from '../basic/icons-inline'
7
+
8
+ const ICON_CLASS = 'w-[var(--font-size-sm)] h-[var(--font-size-sm)] shrink-0'
9
+
10
+ export interface PlanPartProps {
11
+ title?: string
12
+ description?: string
13
+ content: string
14
+ viewText?: string
15
+ buildText?: string
16
+ builtText?: string
17
+ isBuilt?: boolean
18
+ isGenerating?: boolean
19
+ onView?: () => void
20
+ onBuild?: () => void
21
+ onDownload?: () => void
22
+ defaultExpanded?: boolean
23
+ contentMaxHeight?: number
24
+ collapsible?: boolean
25
+ className?: string
26
+ headerIcon?: ReactNode
27
+ downloadIcon?: ReactNode
28
+ builtIcon?: ReactNode
29
+ }
30
+
31
+ const defaultHeaderIcon = <FileList2Line className={`${ICON_CLASS} text-text-secondary`} />
32
+ const defaultDownloadIcon = <DownloadLine className={ICON_CLASS} />
33
+ const defaultBuiltIcon = <CheckLine className={cn(ICON_CLASS, 'text-success')} />
34
+
35
+ export function PlanPart({
36
+ title = 'Plan',
37
+ description,
38
+ content,
39
+ viewText = 'View',
40
+ buildText = 'Build ⌘⏎',
41
+ builtText = 'Built',
42
+ isBuilt = false,
43
+ isGenerating = false,
44
+ onView,
45
+ onBuild,
46
+ onDownload,
47
+ defaultExpanded = true,
48
+ contentMaxHeight,
49
+ collapsible = false,
50
+ className,
51
+ headerIcon,
52
+ downloadIcon,
53
+ builtIcon,
54
+ }: PlanPartProps) {
55
+ const lines = content.split('\n')
56
+ const hasTitle = lines.length > 1 && lines[1].trim() === ''
57
+ const contentTitle = hasTitle ? lines[0] : null
58
+ const contentBody = hasTitle ? lines.slice(2).join('\n') : content
59
+
60
+ return (
61
+ <CollapsibleCard
62
+ headerIcon={headerIcon ?? defaultHeaderIcon}
63
+ headerTitle={
64
+ <div className="flex items-center gap-2 flex-1 min-w-0">
65
+ {isGenerating ? (
66
+ <span className="text-left">Planning...</span>
67
+ ) : (
68
+ <>
69
+ <span className="text-left">{title}</span>
70
+ {description != null && (
71
+ <span className="text-left flex-1 truncate text-text-quaternary">{description}</span>
72
+ )}
73
+ </>
74
+ )}
75
+ </div>
76
+ }
77
+ titleShimmer={isGenerating}
78
+ headerRight={
79
+ !isGenerating && onDownload ? (
80
+ <IconButton
81
+ variant="iconOnly"
82
+ size="sm"
83
+ icon={downloadIcon ?? defaultDownloadIcon}
84
+ onClick={(e) => { e.stopPropagation(); onDownload?.() }}
85
+ title="Download as Markdown"
86
+ aria-label="Download"
87
+ className="!min-h-0 !min-w-0 h-[var(--font-size-sm)] w-[var(--font-size-sm)] text-text-secondary hover:text-text [&_svg]:w-[var(--font-size-sm)] [&_svg]:h-[var(--font-size-sm)]"
88
+ />
89
+ ) : undefined
90
+ }
91
+ contentPadding="var(--spacing-1\.5) var(--spacing-2)"
92
+ defaultExpanded={defaultExpanded}
93
+ contentMaxHeight={contentMaxHeight}
94
+ collapsible={collapsible}
95
+ footer={
96
+ !isGenerating ? (
97
+ <>
98
+ <Button variant="text" size="sm" onClick={onView}>
99
+ {viewText}
100
+ </Button>
101
+ <div className="flex-1" />
102
+ {isBuilt ? (
103
+ <div className="flex items-center gap-1 text-xs text-success [&>svg]:w-[var(--font-size-sm)] [&>svg]:h-[var(--font-size-sm)]">
104
+ <span>{builtText}</span>
105
+ {builtIcon ?? defaultBuiltIcon}
106
+ </div>
107
+ ) : (
108
+ <Button variant="secondary" size="sm" onClick={onBuild}>
109
+ {buildText}
110
+ </Button>
111
+ )}
112
+ </>
113
+ ) : undefined
114
+ }
115
+ className={className}
116
+ >
117
+ {isGenerating ? (
118
+ <div className="flex flex-col gap-1 relative overflow-hidden min-h-[var(--spacing-14)]">
119
+ {/* 点阵背景层 - 基础灰色点(与 QodeChatPanel PlanPart 一致) */}
120
+ <div
121
+ className="absolute inset-0 pointer-events-none"
122
+ style={{
123
+ backgroundImage: 'radial-gradient(circle, var(--color-text-tertiary) 1px, transparent 1px)',
124
+ backgroundSize: '16px 16px',
125
+ backgroundRepeat: 'repeat',
126
+ opacity: 0.25,
127
+ }}
128
+ />
129
+ {/* 逐行点亮的点阵层 - 高亮带的竖向移动动画(与 QodeChatPanel 一致) */}
130
+ <div
131
+ className="absolute inset-0 pointer-events-none plan-part-shimmer-layer"
132
+ style={{
133
+ backgroundImage: 'radial-gradient(circle, var(--color-text-tertiary) 1px, transparent 1px)',
134
+ backgroundSize: '16px 16px',
135
+ backgroundRepeat: 'repeat',
136
+ maskImage: 'linear-gradient(to bottom, transparent 0%, var(--color-mask-shimmer-weak) 15%, var(--color-mask-shimmer-strong) 30%, var(--color-mask-shimmer-full) 50%, var(--color-mask-shimmer-strong) 70%, var(--color-mask-shimmer-weak) 85%, transparent 100%)',
137
+ maskSize: '100% 64px',
138
+ WebkitMaskImage: 'linear-gradient(to bottom, transparent 0%, var(--color-mask-shimmer-weak) 15%, var(--color-mask-shimmer-strong) 30%, var(--color-mask-shimmer-full) 50%, var(--color-mask-shimmer-strong) 70%, var(--color-mask-shimmer-weak) 85%, transparent 100%)',
139
+ WebkitMaskSize: '100% 64px',
140
+ }}
141
+ />
142
+ <style>{`
143
+ @keyframes plan-part-shimmer {
144
+ 0% { mask-position: 0 -64px; -webkit-mask-position: 0 -64px; }
145
+ 100% { mask-position: 0 calc(100% + 64px); -webkit-mask-position: 0 calc(100% + 64px); }
146
+ }
147
+ .plan-part-shimmer-layer {
148
+ animation: plan-part-shimmer 3s linear infinite;
149
+ }
150
+ `}</style>
151
+ </div>
152
+ ) : (
153
+ <div className="flex flex-col gap-1">
154
+ {contentTitle != null && (
155
+ <div className="text-sm font-medium text-text">{contentTitle}</div>
156
+ )}
157
+ {contentBody != null && contentBody !== '' && (
158
+ <span className="text-xs leading-xs text-text whitespace-pre-wrap break-words">
159
+ {contentBody}
160
+ </span>
161
+ )}
162
+ </div>
163
+ )}
164
+ </CollapsibleCard>
165
+ )
166
+ }
167
+
168
+ PlanPart.displayName = 'PlanPart'
@@ -0,0 +1,70 @@
1
+ import type { ReactNode } from 'react'
2
+ import { CollapsibleCard } from '../basic/collapsible-card'
3
+ import { Button } from '../basic/button'
4
+ import { QuestionnaireLine, ArrowDownSLine } from '../basic/icons-inline'
5
+
6
+ const ICON_CLASS = 'w-[var(--font-size-sm)] h-[var(--font-size-sm)] shrink-0 text-text-secondary'
7
+
8
+ export interface QuestionPartProps {
9
+ title?: string
10
+ question: string
11
+ skipText?: string
12
+ runText?: string
13
+ askTimeText?: string
14
+ onSkip?: () => void
15
+ onRun?: () => void
16
+ onAskTimeChange?: (value: string) => void
17
+ contentMaxHeight?: number
18
+ collapsible?: boolean
19
+ className?: string
20
+ headerIcon?: ReactNode
21
+ }
22
+
23
+ const defaultHeaderIcon = <QuestionnaireLine className={ICON_CLASS} />
24
+
25
+ export function QuestionPart({
26
+ title = 'Initializing agent…',
27
+ question,
28
+ skipText = 'Skip ⌘⌫',
29
+ runText = 'Run ⌘⏎',
30
+ askTimeText = 'Ask any time',
31
+ onSkip,
32
+ onRun,
33
+ contentMaxHeight,
34
+ collapsible = true,
35
+ className,
36
+ headerIcon,
37
+ }: QuestionPartProps) {
38
+ return (
39
+ <CollapsibleCard
40
+ headerIcon={headerIcon ?? defaultHeaderIcon}
41
+ headerTitle={<span className="text-left">{title}</span>}
42
+ contentPadding="var(--spacing-1\.5) var(--spacing-2)"
43
+ defaultExpanded
44
+ contentMaxHeight={contentMaxHeight}
45
+ collapsible={collapsible}
46
+ footer={
47
+ <>
48
+ <Button variant="ghost" size="sm" className="gap-1 py-0.5 px-0 text-text-secondary hover:text-text">
49
+ <span className="text-xs">{askTimeText}</span>
50
+ <ArrowDownSLine className="w-[var(--font-size-sm)] h-[var(--font-size-sm)] shrink-0" />
51
+ </Button>
52
+ <div className="flex-1" />
53
+ <Button variant="ghost" size="sm" onClick={onSkip} className="bg-fill text-text-tertiary hover:bg-fill-secondary hover:text-text-secondary">
54
+ {skipText}
55
+ </Button>
56
+ <Button variant="secondary" size="sm" onClick={onRun}>
57
+ {runText}
58
+ </Button>
59
+ </>
60
+ }
61
+ className={className}
62
+ >
63
+ <div className="text-sm text-left">
64
+ <span className="text-text">{question}</span>
65
+ </div>
66
+ </CollapsibleCard>
67
+ )
68
+ }
69
+
70
+ QuestionPart.displayName = 'QuestionPart'
@@ -0,0 +1,234 @@
1
+ import { memo, useState, useCallback, useEffect } from 'react'
2
+ import type { ReactNode } from 'react'
3
+ import { cn } from '@/lib/utils'
4
+ import { motion, AnimatePresence } from 'framer-motion'
5
+ import { Tooltip } from '../basic/tooltip'
6
+ import { IconButton } from '../basic/icon-button'
7
+ import { ArrowUpLine, CloseLine, ArrowDownSLine } from '../basic/icons-inline'
8
+ import { Scrollbar } from '../basic/scrollbar'
9
+
10
+ export interface QueueIndicatorItem {
11
+ id: string
12
+ label: ReactNode
13
+ attachmentCount?: number
14
+ }
15
+
16
+ export interface QueueIndicatorLabels {
17
+ title?: string
18
+ sendNowTip?: string
19
+ removeTip?: string
20
+ fileLabel?: string
21
+ filesLabel?: string
22
+ }
23
+
24
+ const DEFAULT_LABELS: Required<QueueIndicatorLabels> = {
25
+ title: 'In queue',
26
+ sendNowTip: 'Send now',
27
+ removeTip: 'Remove',
28
+ fileLabel: 'file',
29
+ filesLabel: 'files',
30
+ }
31
+
32
+ export interface QueueIndicatorProps {
33
+ items: QueueIndicatorItem[]
34
+ onRemoveItem?: (itemId: string) => void
35
+ onSendNow?: (itemId: string) => void
36
+ isStreaming?: boolean
37
+ hasStatusCardBelow?: boolean
38
+ labels?: QueueIndicatorLabels
39
+ defaultExpanded?: boolean
40
+ storageKey?: string
41
+ arrowUpIcon?: ReactNode
42
+ closeIcon?: ReactNode
43
+ arrowDownSIcon?: ReactNode
44
+ }
45
+
46
+ const arrowUpClass = 'w-3.5 h-3.5'
47
+ const closeClass = 'w-3.5 h-3.5'
48
+ const arrowDownClass = 'w-4 h-4 text-text-tertiary transition-transform duration-200'
49
+
50
+ const QueueItemRow = memo(function QueueItemRow({
51
+ item,
52
+ onRemove,
53
+ onSendNow,
54
+ labels,
55
+ arrowUpIcon,
56
+ closeIcon,
57
+ }: {
58
+ item: QueueIndicatorItem
59
+ onRemove?: (itemId: string) => void
60
+ onSendNow?: (itemId: string) => void
61
+ labels: Required<QueueIndicatorLabels>
62
+ arrowUpIcon: ReactNode
63
+ closeIcon: ReactNode
64
+ }) {
65
+ const handleRemove = useCallback(
66
+ (e: React.MouseEvent) => {
67
+ e.stopPropagation()
68
+ onRemove?.(item.id)
69
+ },
70
+ [item.id, onRemove]
71
+ )
72
+
73
+ const handleSendNow = useCallback(
74
+ (e: React.MouseEvent) => {
75
+ e.stopPropagation()
76
+ onSendNow?.(item.id)
77
+ },
78
+ [item.id, onSendNow]
79
+ )
80
+
81
+ const attachmentCount = item.attachmentCount ?? 0
82
+ const fileWord = attachmentCount === 1 ? labels.fileLabel : labels.filesLabel
83
+
84
+ return (
85
+ <div className="flex items-center gap-2 px-3 py-1.5 text-xs leading-xs hover:bg-fill-tertiary transition-colors cursor-default">
86
+ <span className="truncate flex-1 text-text">{item.label}</span>
87
+ {attachmentCount > 0 && (
88
+ <span className="shrink-0 text-xs leading-xs text-text-tertiary">
89
+ +{attachmentCount} {fileWord}
90
+ </span>
91
+ )}
92
+ <div className="flex items-center gap-0.5">
93
+ {onSendNow && (
94
+ <Tooltip content={labels.sendNowTip} side="top">
95
+ <IconButton
96
+ size="sm"
97
+ variant="ghost"
98
+ icon={arrowUpIcon}
99
+ aria-label={labels.sendNowTip}
100
+ className="shrink-0"
101
+ onClick={handleSendNow}
102
+ />
103
+ </Tooltip>
104
+ )}
105
+ {onRemove && (
106
+ <Tooltip content={labels.removeTip} side="top">
107
+ <IconButton
108
+ size="sm"
109
+ variant="ghost"
110
+ icon={closeIcon}
111
+ aria-label={labels.removeTip}
112
+ className="shrink-0"
113
+ onClick={handleRemove}
114
+ />
115
+ </Tooltip>
116
+ )}
117
+ </div>
118
+ </div>
119
+ )
120
+ })
121
+
122
+ export const QueueIndicator = memo(function QueueIndicator({
123
+ items,
124
+ onRemoveItem,
125
+ onSendNow,
126
+ isStreaming = false,
127
+ hasStatusCardBelow = false,
128
+ labels: labelsProp,
129
+ defaultExpanded = true,
130
+ storageKey,
131
+ arrowUpIcon,
132
+ closeIcon,
133
+ arrowDownSIcon,
134
+ }: QueueIndicatorProps) {
135
+ const labels = { ...DEFAULT_LABELS, ...labelsProp }
136
+
137
+ const defaultArrowUp = arrowUpIcon ?? <ArrowUpLine className={arrowUpClass} />
138
+ const defaultClose = closeIcon ?? <CloseLine className={closeClass} />
139
+ const defaultArrowDown =
140
+ arrowDownSIcon ?? <ArrowDownSLine className={arrowDownClass} />
141
+
142
+ const [isExpanded, setIsExpanded] = useState(() => {
143
+ if (typeof window === 'undefined') return defaultExpanded
144
+ if (storageKey) {
145
+ const saved = localStorage.getItem(storageKey)
146
+ return saved !== null ? saved === 'true' : defaultExpanded
147
+ }
148
+ return defaultExpanded
149
+ })
150
+
151
+ useEffect(() => {
152
+ if (storageKey) {
153
+ localStorage.setItem(storageKey, String(isExpanded))
154
+ }
155
+ }, [storageKey, isExpanded])
156
+
157
+ if (items.length === 0) return null
158
+
159
+ const containerStyles = cn(
160
+ 'w-full overflow-hidden flex flex-col',
161
+ 'border border-b-0 border-border border-border-tertiary bg-bg-base',
162
+ !hasStatusCardBelow && 'rounded-t-xl'
163
+ )
164
+
165
+ return (
166
+ <motion.div
167
+ initial={{ opacity: 0, y: 8 }}
168
+ animate={{ opacity: 1, y: 0 }}
169
+ transition={{ duration: 0.2, ease: [0.16, 1, 0.3, 1] }}
170
+ className={containerStyles}
171
+ >
172
+ <div
173
+ role="button"
174
+ tabIndex={0}
175
+ onClick={() => setIsExpanded(!isExpanded)}
176
+ onKeyDown={(e) => {
177
+ if (e.key === 'Enter' || e.key === ' ') {
178
+ e.preventDefault()
179
+ setIsExpanded(!isExpanded)
180
+ }
181
+ }}
182
+ aria-expanded={isExpanded}
183
+ aria-label={`${isExpanded ? 'Collapse' : 'Expand'} queue`}
184
+ className="flex items-center justify-between px-3 py-1 h-7 cursor-pointer bg-fill-tertiary hover:bg-fill-secondary transition-colors duration-150 focus:outline-none"
185
+ >
186
+ <div className="flex items-center gap-2 flex-1 min-w-0">
187
+ <span
188
+ className={cn(
189
+ 'inline-flex items-center justify-center',
190
+ !isExpanded && '-rotate-90'
191
+ )}
192
+ >
193
+ {defaultArrowDown}
194
+ </span>
195
+ <span className="text-xs leading-xs font-medium text-text-secondary">
196
+ {labels.title}
197
+ </span>
198
+ </div>
199
+ </div>
200
+
201
+ <AnimatePresence initial={false}>
202
+ {isExpanded && (
203
+ <motion.div
204
+ initial={{ height: 0, opacity: 0 }}
205
+ animate={{ height: 'auto', opacity: 1 }}
206
+ exit={{ height: 0, opacity: 0 }}
207
+ transition={{ duration: 0.2, ease: [0.23, 1, 0.32, 1] }}
208
+ className="overflow-hidden"
209
+ >
210
+ <Scrollbar
211
+ scrollbarVisibility="auto"
212
+ maxHeight={208}
213
+ className="border-t border-border-tertiary scroll-smooth"
214
+ >
215
+ {items.map((item) => (
216
+ <QueueItemRow
217
+ key={item.id}
218
+ item={item}
219
+ onRemove={onRemoveItem}
220
+ onSendNow={onSendNow}
221
+ labels={labels}
222
+ arrowUpIcon={defaultArrowUp}
223
+ closeIcon={defaultClose}
224
+ />
225
+ ))}
226
+ </Scrollbar>
227
+ </motion.div>
228
+ )}
229
+ </AnimatePresence>
230
+ </motion.div>
231
+ )
232
+ })
233
+
234
+ QueueIndicator.displayName = 'QueueIndicator'