@signalflare-ai/ui 1.2.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (318) hide show
  1. package/CHANGELOG.md +154 -1
  2. package/ai/component-registry.json +208 -550
  3. package/ai/component-registry.md +3042 -3115
  4. package/ai/schemas.ts +504 -96
  5. package/dist/.build-complete +1 -1
  6. package/dist/ai/schemas.d.ts.map +1 -1
  7. package/dist/{ai-actions-BdUZI3Gk.js → ai-actions-CBfz5XEf.js} +4 -4
  8. package/dist/{ai-actions-BdUZI3Gk.js.map → ai-actions-CBfz5XEf.js.map} +1 -1
  9. package/dist/{ai-agent-card-BR2NIYhi.js → ai-agent-card-CByAUe0q.js} +3 -3
  10. package/dist/ai-agent-card-CByAUe0q.js.map +1 -0
  11. package/dist/{ai-approval-Ba7mrKba.js → ai-approval-Ci8N70a7.js} +4 -3
  12. package/dist/{ai-approval-Ba7mrKba.js.map → ai-approval-Ci8N70a7.js.map} +1 -1
  13. package/dist/{ai-code-block-CZtoL73R.js → ai-code-block-P9TJHvaC.js} +37 -39
  14. package/dist/ai-code-block-P9TJHvaC.js.map +1 -0
  15. package/dist/{ai-conversation-Cc7WlaBg.js → ai-conversation-Qslfdi1t.js} +28 -42
  16. package/dist/ai-conversation-Qslfdi1t.js.map +1 -0
  17. package/dist/{ai-info-banner-C7EWPBj7.js → ai-info-banner-B_9vtGK3.js} +3 -3
  18. package/dist/{ai-info-banner-C7EWPBj7.js.map → ai-info-banner-B_9vtGK3.js.map} +1 -1
  19. package/dist/{ai-message-Bp7L68U_.js → ai-message-Ci3gwM7G.js} +6 -6
  20. package/dist/{ai-message-Bp7L68U_.js.map → ai-message-Ci3gwM7G.js.map} +1 -1
  21. package/dist/{ai-mission-header-TiCJfTNt.js → ai-mission-header-CaBc19-t.js} +2 -2
  22. package/dist/{ai-mission-header-TiCJfTNt.js.map → ai-mission-header-CaBc19-t.js.map} +1 -1
  23. package/dist/{ai-part-group-DNb9I446.js → ai-part-group-Dx1Mr92B.js} +5 -4
  24. package/dist/ai-part-group-Dx1Mr92B.js.map +1 -0
  25. package/dist/{ai-prompt-input-BVvov_KF.js → ai-prompt-input-Bm4XoSj2.js} +19 -17
  26. package/dist/ai-prompt-input-Bm4XoSj2.js.map +1 -0
  27. package/dist/{ai-question-GPPMk7YM.js → ai-question-OyJovxGe.js} +4 -3
  28. package/dist/{ai-question-GPPMk7YM.js.map → ai-question-OyJovxGe.js.map} +1 -1
  29. package/dist/{ai-reasoning-_feFjk56.js → ai-reasoning-BLfBXx3F.js} +9 -5
  30. package/dist/ai-reasoning-BLfBXx3F.js.map +1 -0
  31. package/dist/{ai-response-CvjV3WhV.js → ai-response-hbVCZJmo.js} +2 -2
  32. package/dist/{ai-response-CvjV3WhV.js.map → ai-response-hbVCZJmo.js.map} +1 -1
  33. package/dist/{ai-shimmer-j6lKIrjj.js → ai-shimmer-BamNMNK3.js} +2 -2
  34. package/dist/{ai-shimmer-j6lKIrjj.js.map → ai-shimmer-BamNMNK3.js.map} +1 -1
  35. package/dist/{ai-status-badge-CSU_QOdz.js → ai-status-badge-BZLczdkI.js} +2 -2
  36. package/dist/{ai-status-badge-CSU_QOdz.js.map → ai-status-badge-BZLczdkI.js.map} +1 -1
  37. package/dist/{ai-streaming-text-IWW1BhvZ.js → ai-streaming-text-DgYu64UH.js} +1 -1
  38. package/dist/{ai-streaming-text-IWW1BhvZ.js.map → ai-streaming-text-DgYu64UH.js.map} +1 -1
  39. package/dist/{ai-subagent-JA4iIMW3.js → ai-subagent-p97AI1h9.js} +3 -3
  40. package/dist/{ai-subagent-JA4iIMW3.js.map → ai-subagent-p97AI1h9.js.map} +1 -1
  41. package/dist/{ai-suggestion-BdO6MBuH.js → ai-suggestion-Bj6vF7CT.js} +3 -3
  42. package/dist/{ai-suggestion-BdO6MBuH.js.map → ai-suggestion-Bj6vF7CT.js.map} +1 -1
  43. package/dist/{ai-task-list-DYw4R1FA.js → ai-task-list-C_UQYpk9.js} +6 -4
  44. package/dist/{ai-task-list-DYw4R1FA.js.map → ai-task-list-C_UQYpk9.js.map} +1 -1
  45. package/dist/{ai-timeline-C42tOUT8.js → ai-timeline-CePL1LOU.js} +3 -3
  46. package/dist/ai-timeline-CePL1LOU.js.map +1 -0
  47. package/dist/{ai-tool-03jOTwUI.js → ai-tool-CfRcwmHT.js} +17 -11
  48. package/dist/ai-tool-CfRcwmHT.js.map +1 -0
  49. package/dist/{ai-usage-bar-BRf5LC_b.js → ai-usage-bar-45pVRCGA.js} +2 -2
  50. package/dist/{ai-usage-bar-BRf5LC_b.js.map → ai-usage-bar-45pVRCGA.js.map} +1 -1
  51. package/dist/{badge-BheXjMc8.js → badge-Beb-6uut.js} +5 -5
  52. package/dist/{badge-BheXjMc8.js.map → badge-Beb-6uut.js.map} +1 -1
  53. package/dist/{banner-CcsjunJg.js → banner-CCEksxPg.js} +3 -3
  54. package/dist/{banner-CcsjunJg.js.map → banner-CCEksxPg.js.map} +1 -1
  55. package/dist/{breadcrumbs-CouSyy3H.js → breadcrumbs-HiTmgaZ4.js} +5 -5
  56. package/dist/{breadcrumbs-CouSyy3H.js.map → breadcrumbs-HiTmgaZ4.js.map} +1 -1
  57. package/dist/{button-CO6-qPax.js → button-BHOgXJRU.js} +4 -4
  58. package/dist/{button-CO6-qPax.js.map → button-BHOgXJRU.js.map} +1 -1
  59. package/dist/catalog.js +1 -1
  60. package/dist/catalog.js.map +1 -1
  61. package/dist/{chart-Dg0qUeSc.js → chart-B9FfZdKs.js} +7 -7
  62. package/dist/chart-B9FfZdKs.js.map +1 -0
  63. package/dist/{checkbox-D7p4QKsC.js → checkbox-Cy_OCyay.js} +3 -3
  64. package/dist/{checkbox-D7p4QKsC.js.map → checkbox-Cy_OCyay.js.map} +1 -1
  65. package/dist/{clipboard-text-kLaMogs3.js → clipboard-text-CKSvNp9L.js} +6 -5
  66. package/dist/clipboard-text-CKSvNp9L.js.map +1 -0
  67. package/dist/{cn-YROP2_ox.js → cn-CmAOpn49.js} +2 -2
  68. package/dist/{cn-YROP2_ox.js.map → cn-CmAOpn49.js.map} +1 -1
  69. package/dist/{code-BN8InC0G.js → code-JsQz-0G_.js} +4 -4
  70. package/dist/{code-BN8InC0G.js.map → code-JsQz-0G_.js.map} +1 -1
  71. package/dist/{collapsible-D_ueZ0jz.js → collapsible-1kOZ-89L.js} +2 -2
  72. package/dist/{collapsible-D_ueZ0jz.js.map → collapsible-1kOZ-89L.js.map} +1 -1
  73. package/dist/{combobox-B7TOK0U2.js → combobox-CQwDmqgA.js} +4 -4
  74. package/dist/{combobox-B7TOK0U2.js.map → combobox-CQwDmqgA.js.map} +1 -1
  75. package/dist/command-line/cli.js +3 -3
  76. package/dist/{command-palette-CuNUyJca.js → command-palette-Bkuv3e6o.js} +20 -5
  77. package/dist/command-palette-Bkuv3e6o.js.map +1 -0
  78. package/dist/components/ai-actions.js +1 -1
  79. package/dist/components/ai-agent-card.js +1 -1
  80. package/dist/components/ai-approval.js +1 -1
  81. package/dist/components/ai-code-block.js +1 -1
  82. package/dist/components/ai-conversation.js +1 -1
  83. package/dist/components/ai-info-banner.js +1 -1
  84. package/dist/components/ai-message.js +1 -1
  85. package/dist/components/ai-mission-header.js +1 -1
  86. package/dist/components/ai-part-group.js +1 -1
  87. package/dist/components/ai-prompt-input.js +1 -1
  88. package/dist/components/ai-question.js +1 -1
  89. package/dist/components/ai-reasoning.js +1 -1
  90. package/dist/components/ai-response.js +1 -1
  91. package/dist/components/ai-shimmer.js +1 -1
  92. package/dist/components/ai-status-badge.js +1 -1
  93. package/dist/components/ai-streaming-text.js +1 -1
  94. package/dist/components/ai-subagent.js +1 -1
  95. package/dist/components/ai-suggestion.js +1 -1
  96. package/dist/components/ai-task-list.js +1 -1
  97. package/dist/components/ai-timeline.js +1 -1
  98. package/dist/components/ai-tool.js +1 -1
  99. package/dist/components/ai-usage-bar.js +1 -1
  100. package/dist/components/badge.js +1 -1
  101. package/dist/components/banner.js +1 -1
  102. package/dist/components/breadcrumbs.js +1 -1
  103. package/dist/components/button.js +1 -1
  104. package/dist/components/chart.js +2 -2
  105. package/dist/components/checkbox.js +1 -1
  106. package/dist/components/clipboard-text.js +1 -1
  107. package/dist/components/code.js +1 -1
  108. package/dist/components/collapsible.js +1 -1
  109. package/dist/components/combobox.js +1 -1
  110. package/dist/components/command-palette.js +1 -1
  111. package/dist/components/data-grid.js +1 -1
  112. package/dist/components/date-picker.js +1 -1
  113. package/dist/components/date-range-picker.js +1 -1
  114. package/dist/components/dialog.js +1 -1
  115. package/dist/components/dropdown.js +1 -1
  116. package/dist/components/empty.js +1 -1
  117. package/dist/components/field.js +1 -1
  118. package/dist/components/filters.js +1 -1
  119. package/dist/components/flow.js +1 -1
  120. package/dist/components/grid.js +1 -1
  121. package/dist/components/input.js +2 -2
  122. package/dist/components/label.js +1 -1
  123. package/dist/components/layer-card.js +1 -1
  124. package/dist/components/link.js +3 -3
  125. package/dist/components/link.js.map +1 -1
  126. package/dist/components/loader.js +2 -2
  127. package/dist/components/menubar.js +1 -1
  128. package/dist/components/meter.js +1 -1
  129. package/dist/components/pagination.js +1 -1
  130. package/dist/components/popover.js +1 -1
  131. package/dist/components/radio.js +1 -1
  132. package/dist/components/select.js +1 -1
  133. package/dist/components/sensitive-input.js +1 -1
  134. package/dist/components/sidebar.js +1 -1
  135. package/dist/components/signalflare-ai-logo.js +1 -1
  136. package/dist/components/sparkline.js +1 -1
  137. package/dist/components/stat-card.js +1 -1
  138. package/dist/components/surface.js +1 -1
  139. package/dist/components/switch.js +1 -1
  140. package/dist/components/table.js +1 -1
  141. package/dist/components/tabs.js +1 -1
  142. package/dist/components/text-roll.js +1 -1
  143. package/dist/components/text.js +1 -1
  144. package/dist/components/theme-toggle.js +1 -1
  145. package/dist/components/toast.js +1 -1
  146. package/dist/components/tooltip.js +1 -1
  147. package/dist/components/use-agent-harness.js +1 -1
  148. package/dist/data-grid-DrguJq_H.js +395 -0
  149. package/dist/data-grid-DrguJq_H.js.map +1 -0
  150. package/dist/{date-picker--ox89RBy.js → date-picker-O34AqG3f.js} +2 -2
  151. package/dist/{date-picker--ox89RBy.js.map → date-picker-O34AqG3f.js.map} +1 -1
  152. package/dist/{date-range-picker-DVa7QBqE.js → date-range-picker-YKYvum_r.js} +29 -39
  153. package/dist/{date-range-picker-DVa7QBqE.js.map → date-range-picker-YKYvum_r.js.map} +1 -1
  154. package/dist/{dialog-Bv1oSFOd.js → dialog-DYqu4aDO.js} +3 -3
  155. package/dist/{dialog-Bv1oSFOd.js.map → dialog-DYqu4aDO.js.map} +1 -1
  156. package/dist/{dist-B6iWiWwp.js → dist-6AtBsaJE.js} +153 -47
  157. package/dist/dist-6AtBsaJE.js.map +1 -0
  158. package/dist/{dropdown-B_nrGXjV.js → dropdown-XzbnRLYR.js} +15 -5
  159. package/dist/dropdown-XzbnRLYR.js.map +1 -0
  160. package/dist/{echart-CdOUaT-r.js → echart-DGBIVAv1.js} +23 -57
  161. package/dist/{echart-CdOUaT-r.js.map → echart-DGBIVAv1.js.map} +1 -1
  162. package/dist/{empty-DZnN0zKX.js → empty-C1tAkawe.js} +6 -6
  163. package/dist/{empty-DZnN0zKX.js.map → empty-C1tAkawe.js.map} +1 -1
  164. package/dist/{field-B_yVof52.js → field-DBpFzzBS.js} +3 -3
  165. package/dist/{field-B_yVof52.js.map → field-DBpFzzBS.js.map} +1 -1
  166. package/dist/{filters-cpJCY21R.js → filters-SmEl93za.js} +10 -10
  167. package/dist/filters-SmEl93za.js.map +1 -0
  168. package/dist/{flow-B4v198ot.js → flow-BLzgbq1T.js} +6 -6
  169. package/dist/flow-BLzgbq1T.js.map +1 -0
  170. package/dist/genui.js +2 -2
  171. package/dist/genui.js.map +1 -1
  172. package/dist/{grid-CEd64Lnh.js → grid-CifjQL-5.js} +2 -2
  173. package/dist/{grid-CEd64Lnh.js.map → grid-CifjQL-5.js.map} +1 -1
  174. package/dist/{highlight-to-react-D0Yav4jk.js → highlight-to-react-DN9dUCS2.js} +9 -15
  175. package/dist/highlight-to-react-DN9dUCS2.js.map +1 -0
  176. package/dist/index.js +71 -71
  177. package/dist/index.js.map +1 -1
  178. package/dist/{input-ClB_E4Lb.js → input-COmx2M_R.js} +5 -5
  179. package/dist/{input-ClB_E4Lb.js.map → input-COmx2M_R.js.map} +1 -1
  180. package/dist/{input-B2bbijRh.js → input-GkfMQZC_.js} +3 -3
  181. package/dist/{input-B2bbijRh.js.map → input-GkfMQZC_.js.map} +1 -1
  182. package/dist/{label-DUv_urO1.js → label-CiGZ464N.js} +3 -3
  183. package/dist/{label-DUv_urO1.js.map → label-CiGZ464N.js.map} +1 -1
  184. package/dist/{layer-card-BK7eYfwn.js → layer-card-8l8GuLQr.js} +2 -2
  185. package/dist/{layer-card-BK7eYfwn.js.map → layer-card-8l8GuLQr.js.map} +1 -1
  186. package/dist/{layout-DJHMMap2.js → layout-CWBE0qwx.js} +258 -154
  187. package/dist/layout-CWBE0qwx.js.map +1 -0
  188. package/dist/{link-provider-BUZKXaNE.js → link-provider-BSn8YJon.js} +2 -2
  189. package/dist/link-provider-BSn8YJon.js.map +1 -0
  190. package/dist/{loader-DAcc-Uag.js → loader-BEMz8pJO.js} +1 -1
  191. package/dist/{loader-DAcc-Uag.js.map → loader-BEMz8pJO.js.map} +1 -1
  192. package/dist/{measured-text-BI3dTJmH.js → measured-text-CXkdw9Yr.js} +45 -30
  193. package/dist/measured-text-CXkdw9Yr.js.map +1 -0
  194. package/dist/{menubar-Cxf3xeAt.js → menubar-CoOr4ocj.js} +3 -3
  195. package/dist/{menubar-Cxf3xeAt.js.map → menubar-CoOr4ocj.js.map} +1 -1
  196. package/dist/{meter-BFFe9l5b.js → meter-Pf_VOl59.js} +2 -2
  197. package/dist/{meter-BFFe9l5b.js.map → meter-Pf_VOl59.js.map} +1 -1
  198. package/dist/{pagination-yS372Tr4.js → pagination-DSY279Ta.js} +2 -2
  199. package/dist/{pagination-yS372Tr4.js.map → pagination-DSY279Ta.js.map} +1 -1
  200. package/dist/{popover-SRoJaCZr.js → popover-BY-e9co1.js} +2 -2
  201. package/dist/{popover-SRoJaCZr.js.map → popover-BY-e9co1.js.map} +1 -1
  202. package/dist/{radio-BcwhwYNB.js → radio-DZwL13j0.js} +2 -2
  203. package/dist/{radio-BcwhwYNB.js.map → radio-DZwL13j0.js.map} +1 -1
  204. package/dist/{select-DMhdoHMa.js → select-BFifYqHA.js} +6 -6
  205. package/dist/{select-DMhdoHMa.js.map → select-BFifYqHA.js.map} +1 -1
  206. package/dist/{sensitive-input-CJUpIRal.js → sensitive-input-DHLZcM73.js} +4 -4
  207. package/dist/{sensitive-input-CJUpIRal.js.map → sensitive-input-DHLZcM73.js.map} +1 -1
  208. package/dist/{sidebar-D4zrlYpn.js → sidebar-odGsdvG4.js} +6 -7
  209. package/dist/sidebar-odGsdvG4.js.map +1 -0
  210. package/dist/{signalflare-ai-logo-Bipogceq.js → signalflare-ai-logo-CNaDT_w8.js} +2 -2
  211. package/dist/{signalflare-ai-logo-Bipogceq.js.map → signalflare-ai-logo-CNaDT_w8.js.map} +1 -1
  212. package/dist/{skeleton-line-CH1-h6e2.js → skeleton-line-CxxYVTO2.js} +2 -2
  213. package/dist/{skeleton-line-CH1-h6e2.js.map → skeleton-line-CxxYVTO2.js.map} +1 -1
  214. package/dist/{sparkline-DHmgj1d0.js → sparkline-BQ-4j2W2.js} +2 -2
  215. package/dist/{sparkline-DHmgj1d0.js.map → sparkline-BQ-4j2W2.js.map} +1 -1
  216. package/dist/src/blocks/agent-harness/agent-harness.tsx +11 -11
  217. package/dist/src/blocks/commander/commander.tsx +15 -15
  218. package/dist/src/blocks/map-block/map-block.d.ts.map +1 -1
  219. package/dist/src/blocks/map-block/map-block.tsx +11 -7
  220. package/dist/src/components/ai-approval/ai-approval.d.ts.map +1 -1
  221. package/dist/src/components/ai-code-block/ai-code-block.d.ts +14 -13
  222. package/dist/src/components/ai-code-block/ai-code-block.d.ts.map +1 -1
  223. package/dist/src/components/ai-conversation/ai-conversation.d.ts.map +1 -1
  224. package/dist/src/components/ai-part-group/ai-part-group.d.ts.map +1 -1
  225. package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts.map +1 -1
  226. package/dist/src/components/ai-prompt-input/controller.d.ts.map +1 -1
  227. package/dist/src/components/ai-prompt-input/types.d.ts.map +1 -1
  228. package/dist/src/components/ai-question/ai-question.d.ts.map +1 -1
  229. package/dist/src/components/ai-reasoning/ai-reasoning.d.ts.map +1 -1
  230. package/dist/src/components/ai-response/ai-response.d.ts.map +1 -1
  231. package/dist/src/components/ai-subagent/ai-subagent.d.ts.map +1 -1
  232. package/dist/src/components/ai-tool/ai-tool.d.ts.map +1 -1
  233. package/dist/src/components/chart/echart.d.ts.map +1 -1
  234. package/dist/src/components/clipboard-text/clipboard-text.d.ts.map +1 -1
  235. package/dist/src/components/data-grid/data-grid.d.ts +2 -1
  236. package/dist/src/components/data-grid/data-grid.d.ts.map +1 -1
  237. package/dist/src/components/data-grid/features.d.ts +20 -0
  238. package/dist/src/components/data-grid/features.d.ts.map +1 -0
  239. package/dist/src/components/data-grid/types.d.ts +38 -7
  240. package/dist/src/components/data-grid/types.d.ts.map +1 -1
  241. package/dist/src/components/filters/filters.d.ts.map +1 -1
  242. package/dist/src/components/flow/use-children.d.ts +1 -1
  243. package/dist/src/components/link/link.d.ts.map +1 -1
  244. package/dist/src/components/sidebar/sidebar.d.ts +1 -1
  245. package/dist/src/components/signalflare-ai-logo/signalflare-ai-logo.d.ts.map +1 -1
  246. package/dist/src/components/text/text.d.ts +2 -1
  247. package/dist/src/components/text/text.d.ts.map +1 -1
  248. package/dist/src/components/text-roll/text-roll.d.ts.map +1 -1
  249. package/dist/src/components/theme-toggle/theme-toggle.d.ts.map +1 -1
  250. package/dist/src/components/toast/toast.d.ts.map +1 -1
  251. package/dist/src/utils/highlight-to-react.d.ts.map +1 -1
  252. package/dist/src/utils/measured-text.d.ts.map +1 -1
  253. package/dist/src/utils/use-measured-text.d.ts.map +1 -1
  254. package/dist/{stat-card-Ew-ofzEm.js → stat-card-Bspk4XFr.js} +4 -4
  255. package/dist/stat-card-Bspk4XFr.js.map +1 -0
  256. package/dist/styles/sf-standalone.css +1 -1
  257. package/dist/styles/theme-fedramp.css +3 -12
  258. package/dist/styles/theme-minimal.css +26 -104
  259. package/dist/styles/theme-sf.css +37 -142
  260. package/dist/{surface-DGwRlC0o.js → surface-CWdSFVUx.js} +3 -3
  261. package/dist/{surface-DGwRlC0o.js.map → surface-CWdSFVUx.js.map} +1 -1
  262. package/dist/{switch-BxAMfHdt.js → switch-TA4cByCJ.js} +5 -5
  263. package/dist/switch-TA4cByCJ.js.map +1 -0
  264. package/dist/{table-BBeAtYVZ.js → table-BM8JBGBs.js} +3 -3
  265. package/dist/{table-BBeAtYVZ.js.map → table-BM8JBGBs.js.map} +1 -1
  266. package/dist/{tabs-CeHu7Scn.js → tabs-bnH2vGLv.js} +2 -2
  267. package/dist/{tabs-CeHu7Scn.js.map → tabs-bnH2vGLv.js.map} +1 -1
  268. package/dist/{text-Cqryz7rk.js → text-iQ0YUFNg.js} +4 -5
  269. package/dist/{text-Cqryz7rk.js.map → text-iQ0YUFNg.js.map} +1 -1
  270. package/dist/{text-roll-Ch52hcQj.js → text-roll-C3U2jd2u.js} +5 -2
  271. package/dist/text-roll-C3U2jd2u.js.map +1 -0
  272. package/dist/{theme-toggle-LDfIKEqx.js → theme-toggle-BTVxD-fD.js} +10 -9
  273. package/dist/theme-toggle-BTVxD-fD.js.map +1 -0
  274. package/dist/{toast-CaFQNYng.js → toast-CgZVaAkw.js} +3 -3
  275. package/dist/{toast-CaFQNYng.js.map → toast-CgZVaAkw.js.map} +1 -1
  276. package/dist/{tooltip-g9lFsvcT.js → tooltip-uobk6Oh-.js} +3 -3
  277. package/dist/{tooltip-g9lFsvcT.js.map → tooltip-uobk6Oh-.js.map} +1 -1
  278. package/dist/{use-agent-harness-BTcNJdw4.js → use-agent-harness-Dl8w6X5O.js} +3 -3
  279. package/dist/{use-agent-harness-BTcNJdw4.js.map → use-agent-harness-Dl8w6X5O.js.map} +1 -1
  280. package/dist/utils.js +3 -3
  281. package/package.json +27 -25
  282. package/scripts/component-registry/discovery.ts +11 -10
  283. package/scripts/component-registry/example-cleanup.ts +8 -8
  284. package/scripts/component-registry/index.ts +6 -6
  285. package/scripts/component-registry/schema-generator.ts +1 -1
  286. package/scripts/component-registry/sub-components.ts +35 -23
  287. package/scripts/component-registry/utils.ts +11 -11
  288. package/scripts/component-registry/variant-parser.ts +17 -15
  289. package/scripts/convert-demos-to-stories.ts +5 -5
  290. package/scripts/theme-generator/config.ts +1 -5
  291. package/scripts/theme-generator/generate-css.ts +1 -1
  292. package/scripts/theme-generator/migrate.ts +3 -3
  293. package/dist/ai-agent-card-BR2NIYhi.js.map +0 -1
  294. package/dist/ai-code-block-CZtoL73R.js.map +0 -1
  295. package/dist/ai-conversation-Cc7WlaBg.js.map +0 -1
  296. package/dist/ai-part-group-DNb9I446.js.map +0 -1
  297. package/dist/ai-prompt-input-BVvov_KF.js.map +0 -1
  298. package/dist/ai-reasoning-_feFjk56.js.map +0 -1
  299. package/dist/ai-timeline-C42tOUT8.js.map +0 -1
  300. package/dist/ai-tool-03jOTwUI.js.map +0 -1
  301. package/dist/chart-Dg0qUeSc.js.map +0 -1
  302. package/dist/clipboard-text-kLaMogs3.js.map +0 -1
  303. package/dist/command-palette-CuNUyJca.js.map +0 -1
  304. package/dist/data-grid-DGHmU0w3.js +0 -305
  305. package/dist/data-grid-DGHmU0w3.js.map +0 -1
  306. package/dist/dist-B6iWiWwp.js.map +0 -1
  307. package/dist/dropdown-B_nrGXjV.js.map +0 -1
  308. package/dist/filters-cpJCY21R.js.map +0 -1
  309. package/dist/flow-B4v198ot.js.map +0 -1
  310. package/dist/highlight-to-react-D0Yav4jk.js.map +0 -1
  311. package/dist/layout-DJHMMap2.js.map +0 -1
  312. package/dist/link-provider-BUZKXaNE.js.map +0 -1
  313. package/dist/measured-text-BI3dTJmH.js.map +0 -1
  314. package/dist/sidebar-D4zrlYpn.js.map +0 -1
  315. package/dist/stat-card-Ew-ofzEm.js.map +0 -1
  316. package/dist/switch-BxAMfHdt.js.map +0 -1
  317. package/dist/text-roll-Ch52hcQj.js.map +0 -1
  318. package/dist/theme-toggle-LDfIKEqx.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-tool-CfRcwmHT.js","names":[],"sources":["../src/components/ai-tool/ai-tool.tsx"],"sourcesContent":["\"use client\";\n\nimport { Collapsible as BaseCollapsible } from \"@base-ui/react/collapsible\";\nimport {\n CaretDownIcon,\n CheckIcon,\n CircleIcon,\n CodeIcon,\n DatabaseIcon,\n FileTextIcon,\n GearIcon,\n GlobeIcon,\n ImageIcon,\n LightningIcon,\n MagnifyingGlassIcon,\n ChatCircleIcon,\n SpinnerGapIcon,\n TerminalIcon,\n WarningCircleIcon,\n XCircleIcon,\n ShieldWarningIcon,\n BrainIcon,\n} from \"@phosphor-icons/react\";\nimport type { ComponentProps, ElementType } from \"react\";\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { AiStatusBadge, type AiStatusBadgeStatus } from \"../ai-status-badge\";\nimport { Button } from \"../button\";\nimport { Text } from \"../text\";\nimport { Tooltip } from \"../tooltip\";\n\n// ─── Variants ────────────────────────────────────────────────────────────────\n\nexport const SF_AI_TOOL_VARIANTS = {\n variant: {\n default: {\n classes: \"\",\n description: \"Expandable card with collapsible input/output sections\",\n },\n inline: {\n classes: \"\",\n description: \"Compact single-line display with left accent border\",\n },\n minimal: {\n classes: \"\",\n description: \"Pill-shaped status badge\",\n },\n ephemeral: {\n classes: \"\",\n description:\n \"Single-status row that auto-dismisses after the call completes. Persists on error or when the user expands it.\",\n },\n },\n} as const;\n\nexport const SF_AI_TOOL_DEFAULT_VARIANTS = {\n variant: \"default\",\n} as const;\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Tool execution state — matches Vercel AI SDK ToolUIPart[\"state\"]. */\nexport type AiToolState =\n | \"input-streaming\"\n | \"input-available\"\n | \"approval-requested\"\n | \"approval-responded\"\n | \"output-available\"\n | \"output-error\"\n | \"output-denied\";\n\n/** Display variant for tool call rendering. */\nexport type AiToolCallVariant = keyof typeof SF_AI_TOOL_VARIANTS.variant;\n\n/** Approval state for tools requiring user confirmation. */\nexport type AiToolApprovalState =\n | \"awaiting\"\n | \"approved\"\n | \"declined\"\n | undefined;\n\n/**\n * Structured tool part — mirrors the shape of Vercel AI SDK's `ToolUIPart`\n * without requiring the `ai` package as a dependency.\n */\nexport interface AiToolPart {\n /** Tool call identifier. */\n toolCallId: string;\n /** Tool name or type identifier. */\n toolName: string;\n /** Current execution state. */\n state: AiToolState;\n /** Tool input parameters. */\n input?: unknown;\n /** Tool output result. */\n output?: unknown;\n /** Error text when state is \"output-error\". */\n errorText?: string;\n}\n\nexport type AiToolCallProps = Omit<ComponentProps<\"div\">, \"part\"> & {\n /** Structured tool part data. */\n part: AiToolPart;\n /** Display variant. @default \"default\" */\n variant?: AiToolCallVariant;\n /** Duration in milliseconds. */\n duration?: number;\n /** Summary text shown alongside the tool name. */\n summary?: string;\n /** Custom icon override. */\n icon?: ElementType;\n /** Approval state for tools requiring confirmation. */\n approvalState?: AiToolApprovalState;\n /** Called when user approves a tool call (only relevant when `approvalState=\"awaiting\"`). */\n onApprove?: () => void;\n /** Called when user rejects a tool call (only relevant when `approvalState=\"awaiting\"`). */\n onReject?: () => void;\n /** Default expanded state for the collapsible. @default false */\n defaultExpanded?: boolean;\n /**\n * For `variant=\"ephemeral\"`: ms to keep the completed row visible before\n * fading out. Set to `0` to disable auto-dismiss. @default 800\n */\n dismissDelay?: number;\n /**\n * For `variant=\"ephemeral\"`: when `true`, the row never auto-dismisses.\n * Errors and user-expanded rows are pinned automatically.\n */\n persist?: boolean;\n /** Called once the ephemeral row has finished its dismiss animation. */\n onDismiss?: () => void;\n};\n\nexport type AiToolCallGroupProps = Omit<ComponentProps<\"div\">, \"part\"> & {\n /** Array of tool parts. */\n parts: AiToolPart[];\n /** Group label. */\n label?: string;\n /** Duration map keyed by toolCallId. */\n durations?: Record<string, number>;\n /** Summary map keyed by toolCallId. */\n summaries?: Record<string, string>;\n /** Approval states map keyed by toolCallId. */\n approvalStates?: Record<string, AiToolApprovalState>;\n /** Called when user approves a tool call. Receives the `toolCallId`. */\n onApprove?: (toolCallId: string) => void;\n /** Called when user rejects a tool call. Receives the `toolCallId`. */\n onReject?: (toolCallId: string) => void;\n /** Default expanded state. @default false */\n defaultExpanded?: boolean;\n};\n\nexport type AiToolCallTimelineProps = ComponentProps<\"div\"> & {\n /** Array of tool parts. */\n parts: AiToolPart[];\n /** Duration map keyed by toolCallId. */\n durations?: Record<string, number>;\n};\n\n// ─── Icon Map ────────────────────────────────────────────────────────────────\n\nconst TOOL_ICONS: Record<string, ElementType> = {\n generateSuggestions: BrainIcon,\n searchDatabase: DatabaseIcon,\n searchWeb: GlobeIcon,\n search: MagnifyingGlassIcon,\n readFile: FileTextIcon,\n writeFile: FileTextIcon,\n executeQuery: LightningIcon,\n analyzeContent: BrainIcon,\n generateImage: ImageIcon,\n chat: ChatCircleIcon,\n runCode: TerminalIcon,\n settings: GearIcon,\n code: CodeIcon,\n};\n\n// ─── Defaults ────────────────────────────────────────────────────────────────\n\nconst EMPTY_DURATIONS: Record<string, number> = {};\nconst EMPTY_SUMMARIES: Record<string, string> = {};\nconst EMPTY_APPROVAL_STATES: Record<string, AiToolApprovalState> = {};\n\n// ─── Utilities ───────────────────────────────────────────────────────────────\n\n/** Extract the display-friendly tool name from a tool part. */\nexport function getToolDisplayName(part: AiToolPart): string {\n return part.toolName\n .replace(\"tool-\", \"\")\n .replace(\"Tool\", \"\")\n .replace(/([A-Z])/gu, \" $1\")\n .replace(/_/gu, \" \")\n .replace(/^./u, (s) => s.toUpperCase())\n .trim();\n}\n\n/** Get the best-matching icon for a tool part. */\nexport function getToolIcon(part: AiToolPart): ElementType {\n if (TOOL_ICONS[part.toolName]) return TOOL_ICONS[part.toolName];\n\n const lower = part.toolName.toLowerCase();\n for (const [key, icon] of Object.entries(TOOL_ICONS)) {\n if (lower.includes(key.toLowerCase())) return icon;\n }\n\n return MagnifyingGlassIcon;\n}\n\n/** Whether the tool is still loading (input phase). */\nexport function isToolLoading(part: AiToolPart): boolean {\n return part.state === \"input-streaming\" || part.state === \"input-available\";\n}\n\n/** Whether the tool has produced a result. */\nexport function hasToolResult(part: AiToolPart): boolean {\n return part.state === \"output-available\";\n}\n\n/** Whether the output itself contains an error flag. */\nexport function hasToolOutputError(part: AiToolPart): boolean {\n if (part.state !== \"output-available\") return false;\n const output = part.output as Record<string, unknown> | undefined;\n return output?.error === true;\n}\n\n/** Whether the tool is in any error state. */\nexport function hasToolError(part: AiToolPart): boolean {\n return part.state === \"output-error\" || hasToolOutputError(part);\n}\n\n/** Extract error text from either error state or output.error. */\nexport function getToolErrorText(part: AiToolPart): string | undefined {\n if (part.state === \"output-error\") return part.errorText;\n if (hasToolOutputError(part)) {\n const output = part.output as Record<string, unknown>;\n return (\n (output.message as string) ||\n (output.error as string) ||\n \"Tool returned an error\"\n );\n }\n return undefined;\n}\n\n// ─── State Config ────────────────────────────────────────────────────────────\n\ninterface StateConfig {\n colorClass: string;\n bgClass: string;\n icon: ElementType;\n spin: boolean;\n label: string;\n /** Solid dot color for the minimalist status indicator (ephemeral variant). */\n dotClass: string;\n /** Whether the dot should pulse (running / streaming states). */\n dotPulse: boolean;\n}\n\nfunction getStateConfig(\n part: AiToolPart,\n approvalState?: AiToolApprovalState\n): StateConfig {\n if (approvalState === \"awaiting\") {\n return {\n colorClass: \"text-sf-warning\",\n bgClass: \"bg-sf-warning/10\",\n icon: ShieldWarningIcon,\n spin: false,\n label: \"Awaiting Approval\",\n dotClass: \"bg-sf-warning\",\n dotPulse: true,\n };\n }\n\n if (approvalState === \"declined\") {\n return {\n colorClass: \"text-sf-danger\",\n bgClass: \"bg-sf-danger/10\",\n icon: XCircleIcon,\n spin: false,\n label: \"Declined\",\n dotClass: \"bg-sf-danger\",\n dotPulse: false,\n };\n }\n\n if (hasToolError(part)) {\n return {\n colorClass: \"text-sf-danger\",\n bgClass: \"bg-sf-danger/10\",\n icon: WarningCircleIcon,\n spin: false,\n label: \"Failed\",\n dotClass: \"bg-sf-danger\",\n dotPulse: false,\n };\n }\n\n switch (part.state) {\n case \"input-streaming\":\n return {\n colorClass: \"text-sf-brand\",\n bgClass: \"bg-sf-brand/10\",\n icon: CircleIcon,\n spin: false,\n label: \"Streaming\",\n dotClass: \"bg-sf-warning\",\n dotPulse: true,\n };\n case \"input-available\":\n return {\n colorClass: \"text-sf-brand\",\n bgClass: \"bg-sf-brand/10\",\n icon: SpinnerGapIcon,\n spin: true,\n label: \"Running\",\n dotClass: \"bg-sf-warning\",\n dotPulse: true,\n };\n case \"output-available\":\n return {\n colorClass: \"text-sf-success\",\n bgClass: \"bg-sf-tint\",\n icon: CheckIcon,\n spin: false,\n label: \"Complete\",\n dotClass: \"bg-sf-success\",\n dotPulse: false,\n };\n default:\n return {\n colorClass: \"text-sf-subtle\",\n bgClass: \"bg-sf-tint\",\n icon: CircleIcon,\n spin: false,\n label: \"Pending\",\n dotClass: \"bg-sf-subtle/40\",\n dotPulse: false,\n };\n }\n}\n\n// ─── AiToolCall ──────────────────────────────────────────────────────────────\n\n/**\n * Renders a single tool call. Supports three display variants:\n * - `\"default\"` — expandable card with collapsible input/output\n * - `\"inline\"` — compact single-line with left accent border\n * - `\"minimal\"` — pill-shaped status badge\n *\n * @example\n * ```tsx\n * <AiToolCall\n * part={{ toolCallId: \"1\", toolName: \"web_search\", state: \"output-available\", input: { q: \"ts\" }, output: \"...\" }}\n * />\n * ```\n */\nexport function AiToolCall({\n part,\n variant = \"default\",\n duration,\n summary,\n icon: CustomIcon,\n approvalState,\n onApprove,\n onReject,\n defaultExpanded = false,\n dismissDelay = 800,\n persist = false,\n onDismiss,\n className,\n ...props\n}: AiToolCallProps) {\n const [isExpanded, setIsExpanded] = useState(defaultExpanded);\n\n const IconComponent = CustomIcon ?? getToolIcon(part);\n const displayName = getToolDisplayName(part);\n const config = getStateConfig(part, approvalState);\n const StatusIconEl = config.icon;\n const errorText = getToolErrorText(part);\n\n // ── Ephemeral ──────────────────────────────────────────────────────────────\n\n if (variant === \"ephemeral\") {\n return (\n <AiToolCallEphemeral\n part={part}\n approvalState={approvalState}\n duration={duration}\n summary={summary}\n icon={IconComponent}\n displayName={displayName}\n config={config}\n errorText={errorText}\n dismissDelay={dismissDelay}\n persist={persist}\n onDismiss={onDismiss}\n onApprove={onApprove}\n onReject={onReject}\n className={className}\n {...props}\n />\n );\n }\n\n // ── Minimal ────────────────────────────────────────────────────────────────\n\n if (variant === \"minimal\") {\n const handleGetToolStatus = (): AiStatusBadgeStatus => {\n if (hasToolError(part)) return \"error\";\n if (approvalState === \"awaiting\") return \"idle\";\n if (isToolLoading(part)) return \"running\";\n if (hasToolResult(part)) return \"success\";\n return \"idle\";\n };\n\n return (\n <AiStatusBadge\n className={cn(\n \"my-1.5 py-1\",\n hasToolError(part) && \"bg-sf-danger/10\",\n className\n )}\n icon={IconComponent}\n label={displayName}\n status={handleGetToolStatus()}\n {...props}\n />\n );\n }\n\n // ── Inline ─────────────────────────────────────────────────────────────────\n\n if (variant === \"inline\") {\n return (\n <div\n className={cn(\n \"my-1 flex w-full items-center gap-2 py-1.5 pl-1\",\n \"animate-in fade-in-0 slide-in-from-bottom-1 duration-200\",\n className\n )}\n {...props}\n >\n <div className={cn(\"shrink-0 rounded-md p-1\", config.bgClass)}>\n <IconComponent className={cn(\"size-3.5\", config.colorClass)} />\n </div>\n <Text\n size=\"sm\"\n variant={hasToolError(part) ? \"error\" : \"secondary\"}\n wrap=\"shrink\"\n as=\"span\"\n DANGEROUS_className=\"min-w-0 grow truncate\"\n >\n {displayName}\n </Text>\n {/* Right-aligned meta group */}\n <div className=\"flex shrink-0 items-center gap-1.5\">\n {duration && hasToolResult(part) ? (\n <span className=\"text-xs tabular-nums text-sf-subtle\">\n {duration}ms\n </span>\n ) : null}\n {summary && !hasToolError(part) ? (\n <Text\n size=\"xs\"\n variant=\"secondary\"\n wrap=\"shrink\"\n as=\"span\"\n DANGEROUS_className=\"max-w-[160px] truncate\"\n >\n {summary}\n </Text>\n ) : null}\n {errorText ? (\n <Text\n size=\"xs\"\n variant=\"error\"\n wrap=\"shrink\"\n as=\"span\"\n DANGEROUS_className=\"max-w-[160px] truncate\"\n title={errorText}\n >\n {errorText}\n </Text>\n ) : null}\n {approvalState === \"awaiting\" && (onApprove || onReject) ? (\n <>\n {onReject && (\n <Button\n onClick={onReject}\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n >\n Reject\n </Button>\n )}\n {onApprove && (\n <Button\n onClick={onApprove}\n size=\"sm\"\n type=\"button\"\n variant=\"primary\"\n >\n Approve\n </Button>\n )}\n </>\n ) : (\n <StatusIconEl\n className={cn(\n \"size-3.5\",\n config.colorClass,\n config.spin && \"animate-spin\"\n )}\n />\n )}\n </div>\n </div>\n );\n }\n\n // ── Default (compact expandable row) ─────────────────────────────────────\n\n return (\n <BaseCollapsible.Root open={isExpanded} onOpenChange={setIsExpanded}>\n <div\n className={cn(\n \"my-0.5 flex w-full max-w-sm flex-col\",\n \"animate-in fade-in-0 duration-150\",\n className\n )}\n {...props}\n >\n {/* Trigger — content-width: name + meta + caret */}\n <BaseCollapsible.Trigger\n render={\n <button\n type=\"button\"\n aria-label={displayName}\n className={cn(\n \"flex w-fit items-center gap-1.5 rounded px-1 py-0.5 text-left\",\n \"transition-colors hover:bg-sf-tint\"\n )}\n />\n }\n >\n <span className=\"min-w-0 truncate text-sm text-sf-subtle\">\n {displayName}\n </span>\n {/* Meta group — part of the content-width trigger */}\n <div className=\"flex shrink-0 items-center gap-1.5\">\n {duration && hasToolResult(part) && !isExpanded ? (\n <span className=\"text-xs tabular-nums text-sf-subtle\">\n {duration}ms\n </span>\n ) : null}\n {summary && !isExpanded && !errorText ? (\n <span className=\"max-w-[120px] truncate text-xs text-sf-subtle\">\n {summary}\n </span>\n ) : null}\n <StatusIconEl\n className={cn(\n \"size-3.5\",\n config.colorClass,\n config.spin && \"animate-spin\"\n )}\n />\n <CaretDownIcon\n className={cn(\n \"size-3 text-sf-subtle transition-transform duration-200\",\n !isExpanded && \"-rotate-90\"\n )}\n />\n </div>\n </BaseCollapsible.Trigger>\n\n {/* Detail panel */}\n <BaseCollapsible.Panel className=\"overflow-hidden\">\n <div className=\"mt-1 space-y-2 rounded-lg bg-sf-tint/50 px-3 py-2\">\n {/* Input */}\n {part.input &&\n typeof part.input === \"object\" &&\n Object.keys(part.input as object).length > 0 ? (\n <div>\n <p className=\"mb-1 text-[10px] uppercase tracking-wider text-sf-subtle\">\n Input\n </p>\n <pre className=\"overflow-x-auto rounded bg-sf-recessed p-1.5 font-mono text-xs text-sf-subtle\">\n {JSON.stringify(\n part.input as Record<string, unknown>,\n null,\n 2\n )}\n </pre>\n </div>\n ) : null}\n\n {/* Output */}\n {hasToolResult(part) &&\n part.output !== undefined &&\n !hasToolError(part) ? (\n <div>\n <p className=\"mb-1 text-[10px] uppercase tracking-wider text-sf-subtle\">\n Output\n </p>\n <pre className=\"max-h-28 overflow-x-auto overflow-y-auto rounded bg-sf-recessed p-1.5 font-mono text-xs text-sf-subtle\">\n {typeof part.output === \"string\"\n ? part.output\n : JSON.stringify(\n part.output as Record<string, unknown>,\n null,\n 2\n )}\n </pre>\n </div>\n ) : null}\n\n {/* Error */}\n {errorText ? (\n <div>\n <p className=\"mb-1 flex items-center gap-1 text-[10px] uppercase tracking-wider text-sf-danger\">\n <WarningCircleIcon className=\"size-3\" />\n Error\n </p>\n <pre className=\"overflow-x-auto whitespace-pre-wrap rounded bg-sf-danger/10 p-1.5 font-mono text-xs text-sf-danger\">\n {errorText}\n </pre>\n </div>\n ) : null}\n\n {/* Approval actions */}\n {approvalState === \"awaiting\" && (onApprove || onReject) && (\n <div className=\"flex items-center justify-end gap-2 border-t border-sf-line/20 pt-2\">\n {onReject && (\n <Button\n onClick={onReject}\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n >\n Reject\n </Button>\n )}\n {onApprove && (\n <Button\n onClick={onApprove}\n size=\"sm\"\n type=\"button\"\n variant=\"primary\"\n >\n Approve\n </Button>\n )}\n </div>\n )}\n\n {/* Tool call ID */}\n <p className=\"font-mono text-[10px] text-sf-subtle/50\">\n {part.toolCallId}\n </p>\n </div>\n </BaseCollapsible.Panel>\n </div>\n </BaseCollapsible.Root>\n );\n}\n\n// ─── AiToolCallEphemeral ─────────────────────────────────────────────────────\n\ninterface AiToolCallEphemeralInternalProps extends Omit<\n ComponentProps<\"div\">,\n \"part\"\n> {\n part: AiToolPart;\n approvalState?: AiToolApprovalState;\n duration?: number;\n summary?: string;\n icon: ElementType;\n displayName: string;\n config: StateConfig;\n errorText: string | undefined;\n dismissDelay: number;\n persist: boolean;\n onDismiss?: () => void;\n onApprove?: () => void;\n onReject?: () => void;\n}\n\n// Note: `icon` (tool icon) is accepted for API symmetry with other variants\n// but the ephemeral row leads with the status icon for at-a-glance state.\n\nconst FADE_OUT_MS = 200;\n\n/**\n * Internal renderer for `variant=\"ephemeral\"`. Shows a single-status row\n * that auto-dismisses once the tool call completes. Pins on error or when\n * the user expands the row.\n */\nfunction AiToolCallEphemeral({\n part,\n approvalState,\n duration,\n summary,\n icon: _icon,\n displayName,\n config,\n errorText,\n dismissDelay,\n persist,\n onDismiss,\n onApprove,\n onReject,\n className,\n ...props\n}: AiToolCallEphemeralInternalProps) {\n const [isExpanded, setIsExpanded] = useState(false);\n const [phase, setPhase] = useState<\"live\" | \"fading\" | \"gone\">(\"live\");\n const userExpandedRef = useRef(false);\n\n const hasError = hasToolError(part);\n const isComplete = hasToolResult(part);\n const isAwaitingApproval = approvalState === \"awaiting\";\n\n // Pin the row when: errored, user expanded, persist requested, or awaiting approval.\n const pinned =\n persist || hasError || userExpandedRef.current || isAwaitingApproval;\n\n // Auto-dismiss when complete (and not pinned).\n useEffect(() => {\n if (phase !== \"live\") return;\n if (!isComplete) return;\n if (pinned) return;\n if (dismissDelay <= 0) return;\n\n const settleTimer = setTimeout(() => {\n setPhase(\"fading\");\n }, dismissDelay);\n\n return () => clearTimeout(settleTimer);\n }, [phase, isComplete, pinned, dismissDelay]);\n\n // After fade animation, unmount.\n useEffect(() => {\n if (phase !== \"fading\") return;\n const fadeTimer = setTimeout(() => {\n setPhase(\"gone\");\n onDismiss?.();\n }, FADE_OUT_MS);\n return () => clearTimeout(fadeTimer);\n }, [phase, onDismiss]);\n\n if (phase === \"gone\") return null;\n\n const handleToggle = (next: boolean) => {\n if (next) userExpandedRef.current = true;\n setIsExpanded(next);\n };\n\n return (\n <BaseCollapsible.Root open={isExpanded} onOpenChange={handleToggle}>\n <div\n className={cn(\n \"my-0.5 flex w-full max-w-sm flex-col overflow-hidden\",\n \"transition-[opacity,max-height,margin] duration-200 ease-out\",\n phase === \"live\"\n ? \"max-h-40 opacity-100\"\n : \"pointer-events-none my-0 max-h-0 opacity-0\",\n phase === \"live\" && \"animate-in fade-in-0 duration-150\",\n className\n )}\n data-phase={phase}\n {...props}\n >\n <BaseCollapsible.Trigger\n render={\n <button\n type=\"button\"\n aria-label={displayName}\n className={cn(\n \"flex w-fit items-center gap-1.5 rounded px-1 py-0.5 text-left\",\n \"transition-colors hover:bg-sf-tint\"\n )}\n />\n }\n >\n <span\n aria-label={config.label}\n className={cn(\n \"size-1.5 shrink-0 rounded-full\",\n config.dotClass,\n config.dotPulse && \"animate-pulse\"\n )}\n // oxlint-disable-next-line prefer-tag-over-role -- live status dot; <output> would not be appropriate here\n role=\"status\"\n />\n <span\n className={cn(\n \"min-w-0 truncate text-sm\",\n hasError ? \"text-sf-danger\" : \"text-sf-subtle\"\n )}\n >\n {displayName}\n </span>\n {duration && isComplete && !isExpanded ? (\n <span className=\"text-xs tabular-nums text-sf-subtle/60\">\n {duration}ms\n </span>\n ) : null}\n {summary && !isExpanded && !errorText ? (\n <span className=\"max-w-[120px] truncate text-xs text-sf-subtle/60\">\n {summary}\n </span>\n ) : null}\n <CaretDownIcon\n className={cn(\n \"size-3 text-sf-subtle/60 transition-transform duration-200\",\n !isExpanded && \"-rotate-90\"\n )}\n />\n </BaseCollapsible.Trigger>\n\n <BaseCollapsible.Panel className=\"overflow-hidden\">\n <div className=\"mt-1 space-y-2 rounded-lg bg-sf-tint/50 px-3 py-2\">\n {part.input &&\n typeof part.input === \"object\" &&\n Object.keys(part.input as object).length > 0 ? (\n <div>\n <p className=\"mb-1 text-[10px] uppercase tracking-wider text-sf-subtle\">\n Input\n </p>\n <pre className=\"overflow-x-auto rounded bg-sf-recessed p-1.5 font-mono text-xs text-sf-subtle\">\n {JSON.stringify(\n part.input as Record<string, unknown>,\n null,\n 2\n )}\n </pre>\n </div>\n ) : null}\n\n {hasToolResult(part) && part.output !== undefined && !hasError ? (\n <div>\n <p className=\"mb-1 text-[10px] uppercase tracking-wider text-sf-subtle\">\n Output\n </p>\n <pre className=\"max-h-28 overflow-x-auto overflow-y-auto rounded bg-sf-recessed p-1.5 font-mono text-xs text-sf-subtle\">\n {typeof part.output === \"string\"\n ? part.output\n : JSON.stringify(\n part.output as Record<string, unknown>,\n null,\n 2\n )}\n </pre>\n </div>\n ) : null}\n\n {errorText ? (\n <div>\n <p className=\"mb-1 flex items-center gap-1 text-[10px] uppercase tracking-wider text-sf-danger\">\n <WarningCircleIcon className=\"size-3\" />\n Error\n </p>\n <pre className=\"overflow-x-auto whitespace-pre-wrap rounded bg-sf-danger/10 p-1.5 font-mono text-xs text-sf-danger\">\n {errorText}\n </pre>\n </div>\n ) : null}\n\n {isAwaitingApproval && (onApprove || onReject) && (\n <div className=\"flex items-center justify-end gap-2 border-t border-sf-line/20 pt-2\">\n {onReject && (\n <Button\n onClick={onReject}\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n >\n Reject\n </Button>\n )}\n {onApprove && (\n <Button\n onClick={onApprove}\n size=\"sm\"\n type=\"button\"\n variant=\"primary\"\n >\n Approve\n </Button>\n )}\n </div>\n )}\n </div>\n </BaseCollapsible.Panel>\n </div>\n </BaseCollapsible.Root>\n );\n}\n\n// ─── AiToolCallGroup ─────────────────────────────────────────────────────────\n\n/**\n * Collapsible group of tool calls. Shows a summary header with progress\n * counter and stacked tool icons when collapsed. Renders a single tool\n * directly if only one part is provided.\n *\n * @example\n * ```tsx\n * <AiToolCallGroup parts={toolParts} label=\"3 tools ran\" />\n * ```\n */\nexport function AiToolCallGroup({\n parts,\n label,\n durations = EMPTY_DURATIONS,\n summaries = EMPTY_SUMMARIES,\n approvalStates = EMPTY_APPROVAL_STATES,\n onApprove,\n onReject,\n defaultExpanded = false,\n className,\n ...props\n}: AiToolCallGroupProps) {\n const [isExpanded, setIsExpanded] = useState(defaultExpanded);\n\n const completedCount = parts.filter(\n (p) => p.state === \"output-available\"\n ).length;\n const errorCount = parts.filter(hasToolError).length;\n const totalCount = parts.length;\n\n // Single item — render directly\n if (parts.length === 1 && parts[0]) {\n const singlePart = parts[0];\n // Strip `part` from div props spread to avoid collision with HTML `part` attribute\n const { part: _part, ...restProps } = props as typeof props & {\n part?: unknown;\n };\n return (\n <AiToolCall\n part={singlePart}\n duration={durations[singlePart.toolCallId]}\n summary={summaries[singlePart.toolCallId]}\n approvalState={approvalStates[singlePart.toolCallId]}\n onApprove={\n onApprove ? () => onApprove(singlePart.toolCallId) : undefined\n }\n onReject={onReject ? () => onReject(singlePart.toolCallId) : undefined}\n className={className}\n {...restProps}\n />\n );\n }\n\n return (\n <BaseCollapsible.Root open={isExpanded} onOpenChange={setIsExpanded}>\n <div\n className={cn(\n \"my-1.5 w-full overflow-hidden rounded-lg bg-sf-tint/50\",\n \"animate-in fade-in-0 slide-in-from-bottom-2 duration-200\",\n className\n )}\n {...props}\n >\n <BaseCollapsible.Trigger\n render={\n <button\n type=\"button\"\n aria-label={label ?? `${totalCount} tool calls`}\n className=\"flex w-fit items-center gap-3 px-3 py-2.5 text-left transition-colors hover:bg-sf-tint\"\n />\n }\n >\n <span className=\"text-sm font-medium text-sf-subtle\">\n {label ?? `${totalCount} tool calls`}\n </span>\n <span className=\"text-xs text-sf-subtle\">\n {completedCount}/{totalCount}\n {errorCount > 0 ? (\n <span className=\"ml-1 text-sf-danger\">({errorCount} errors)</span>\n ) : null}\n </span>\n\n <div className=\"flex items-center gap-2\">\n {/* Tool icon stack when collapsed */}\n {isExpanded ? null : (\n <div className=\"flex -space-x-1\">\n {parts.slice(0, 5).map((p) => {\n const Icon = getToolIcon(p);\n return (\n <div\n key={p.toolCallId}\n className={cn(\n \"flex size-6 items-center justify-center rounded-full border-2 border-sf-elevated\",\n p.state === \"output-available\" &&\n !hasToolError(p) &&\n \"bg-sf-tint\",\n isToolLoading(p) && \"bg-sf-tint\",\n hasToolError(p) && \"bg-sf-danger/20\"\n )}\n >\n <Icon className=\"size-3\" />\n </div>\n );\n })}\n {parts.length > 5 ? (\n <div className=\"flex size-6 items-center justify-center rounded-full border-2 border-sf-elevated bg-sf-tint text-[10px] text-sf-subtle\">\n +{parts.length - 5}\n </div>\n ) : null}\n </div>\n )}\n <CaretDownIcon\n className={cn(\n \"size-4 text-sf-subtle transition-transform duration-200\",\n !isExpanded && \"-rotate-90\"\n )}\n />\n </div>\n </BaseCollapsible.Trigger>\n\n <BaseCollapsible.Panel className=\"overflow-hidden\">\n <div className=\"space-y-2 border-t border-sf-line/20 px-3 pt-1 pb-3\">\n {parts.map((p) => (\n <AiToolCall\n key={p.toolCallId}\n part={p}\n variant=\"inline\"\n duration={durations[p.toolCallId]}\n summary={summaries[p.toolCallId]}\n approvalState={approvalStates[p.toolCallId]}\n onApprove={\n onApprove ? () => onApprove(p.toolCallId) : undefined\n }\n onReject={onReject ? () => onReject(p.toolCallId) : undefined}\n />\n ))}\n </div>\n </BaseCollapsible.Panel>\n </div>\n </BaseCollapsible.Root>\n );\n}\n\n// ─── AiToolCallTimeline ──────────────────────────────────────────────────────\n\n/**\n * Horizontal timeline view of tool calls. Each tool is shown as a small\n * icon pill with a tooltip showing its name, duration, and any errors.\n *\n * @example\n * ```tsx\n * <AiToolCallTimeline parts={toolParts} durations={{ id1: 230, id2: 540 }} />\n * ```\n */\nexport function AiToolCallTimeline({\n parts,\n durations = EMPTY_DURATIONS,\n className,\n ...props\n}: AiToolCallTimelineProps) {\n return (\n <div\n className={cn(\"flex flex-wrap items-center gap-1 py-2\", className)}\n {...props}\n >\n {parts.map((part, index) => {\n const IconComponent = getToolIcon(part);\n const displayName = getToolDisplayName(part);\n const config = getStateConfig(part);\n const duration = durations[part.toolCallId];\n const errorText = getToolErrorText(part);\n\n const tooltipLines = [\n displayName,\n duration ? `${duration}ms` : null,\n errorText ?? null,\n ]\n .filter(Boolean)\n .join(\" · \");\n\n return (\n <div key={part.toolCallId} className=\"flex items-center\">\n <Tooltip content={tooltipLines}>\n <div\n className={cn(\n \"flex cursor-default items-center gap-1.5 rounded-md px-2 py-1 transition-all\",\n config.bgClass\n )}\n >\n <IconComponent className={cn(\"size-3.5\", config.colorClass)} />\n {part.state === \"input-streaming\" ? (\n <CircleIcon\n className={cn(\"size-3 animate-pulse\", config.colorClass)}\n />\n ) : null}\n {part.state === \"input-available\" ? (\n <SpinnerGapIcon\n className={cn(\"size-3 animate-spin\", config.colorClass)}\n />\n ) : null}\n {hasToolResult(part) && !hasToolError(part) ? (\n <CheckIcon className={cn(\"size-3\", config.colorClass)} />\n ) : null}\n {hasToolError(part) ? (\n <WarningCircleIcon\n className={cn(\"size-3\", config.colorClass)}\n />\n ) : null}\n </div>\n </Tooltip>\n\n {/* Connector line */}\n {index < parts.length - 1 ? (\n <div\n className={cn(\n \"mx-0.5 h-px w-3\",\n (() => {\n const nextPart = parts[index + 1];\n if (!nextPart) return \"bg-sf-line\";\n return hasToolResult(nextPart) || isToolLoading(nextPart)\n ? \"bg-sf-success/50\"\n : \"bg-sf-line\";\n })()\n )}\n />\n ) : null}\n </div>\n );\n })}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { t as cn } from "./cn-YROP2_ox.js";
2
+ import { t as cn } from "./cn-CmAOpn49.js";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import { LightningIcon } from "@phosphor-icons/react";
5
5
  //#region src/components/ai-usage-bar/ai-usage-bar.tsx
@@ -67,4 +67,4 @@ AiUsageBar.displayName = "AiUsageBar";
67
67
  //#endregion
68
68
  export { SF_AI_USAGE_BAR_DEFAULT_VARIANTS as n, SF_AI_USAGE_BAR_VARIANTS as r, AiUsageBar as t };
69
69
 
70
- //# sourceMappingURL=ai-usage-bar-BRf5LC_b.js.map
70
+ //# sourceMappingURL=ai-usage-bar-45pVRCGA.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai-usage-bar-BRf5LC_b.js","names":[],"sources":["../src/components/ai-usage-bar/ai-usage-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport { LightningIcon } from \"@phosphor-icons/react\";\nimport type { ElementType, HTMLAttributes } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\n\n// ─── Variants ────────────────────────────────────────────────────────────────\n\nexport const SF_AI_USAGE_BAR_VARIANTS = {} as const;\nexport const SF_AI_USAGE_BAR_DEFAULT_VARIANTS = {} as const;\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type AiUsageBarProps = HTMLAttributes<HTMLDivElement> & {\n /** Input/prompt token count. */\n inputTokens?: number;\n /** Output/completion token count. */\n outputTokens?: number;\n /** Total token count. Computed from input + output if not provided. */\n totalTokens?: number;\n /** Estimated cost in USD. */\n cost?: number;\n /** Model ID being used (shown as label). */\n modelId?: string;\n /** Custom icon. Defaults to `LightningIcon`. */\n icon?: ElementType;\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatTokens(count: number): string {\n if (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`;\n if (count >= 1000) return `${(count / 1000).toFixed(1)}k`;\n return count.toString();\n}\n\nfunction formatCost(usd: number): string {\n if (usd < 0.01) return `<$0.01`;\n return `$${usd.toFixed(2)}`;\n}\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\n/**\n * Compact token usage display bar. Shows input/output token counts, total,\n * optional cost, and model identifier.\n *\n * Maps to harness event: `usage_update`.\n *\n * @example\n * ```tsx\n * <AiUsageBar\n * inputTokens={1234}\n * outputTokens={567}\n * cost={0.02}\n * modelId=\"claude-sonnet-4\"\n * />\n * ```\n */\nexport function AiUsageBar({\n inputTokens,\n outputTokens,\n totalTokens,\n cost,\n modelId,\n icon,\n className,\n ...props\n}: AiUsageBarProps) {\n const IconComponent = icon ?? LightningIcon;\n const computed = (inputTokens ?? 0) + (outputTokens ?? 0);\n const total = totalTokens ?? (computed > 0 ? computed : undefined);\n const hasTokens =\n inputTokens !== undefined ||\n outputTokens !== undefined ||\n total !== undefined;\n\n if (!hasTokens && cost === undefined && !modelId) return null;\n\n return (\n <div\n className={cn(\n \"flex items-center gap-3 px-3 py-1 text-[11px] tabular-nums text-sf-subtle\",\n className\n )}\n {...props}\n >\n <IconComponent className=\"size-3 shrink-0\" />\n\n {inputTokens !== undefined && (\n <span>\n <span className=\"text-sf-inactive\">in </span>\n {formatTokens(inputTokens)}\n </span>\n )}\n {outputTokens !== undefined && (\n <span>\n <span className=\"text-sf-inactive\">out </span>\n {formatTokens(outputTokens)}\n </span>\n )}\n {total !== undefined && (\n <span>\n <span className=\"text-sf-inactive\">total </span>\n {formatTokens(total)}\n </span>\n )}\n {cost !== undefined && (\n <span className=\"text-sf-subtle\">{formatCost(cost)}</span>\n )}\n {modelId && (\n <span className=\"ml-auto truncate font-mono text-sf-inactive\">\n {modelId}\n </span>\n )}\n </div>\n );\n}\n\nAiUsageBar.displayName = \"AiUsageBar\";\n"],"mappings":";;;;;AASA,IAAa,2BAA2B,EAAE;AAC1C,IAAa,mCAAmC,EAAE;AAqBlD,SAAS,aAAa,OAAuB;AAC3C,KAAI,SAAS,IAAW,QAAO,IAAI,QAAQ,KAAW,QAAQ,EAAE,CAAC;AACjE,KAAI,SAAS,IAAM,QAAO,IAAI,QAAQ,KAAM,QAAQ,EAAE,CAAC;AACvD,QAAO,MAAM,UAAU;;AAGzB,SAAS,WAAW,KAAqB;AACvC,KAAI,MAAM,IAAM,QAAO;AACvB,QAAO,IAAI,IAAI,QAAQ,EAAE;;;;;;;;;;;;;;;;;;AAqB3B,SAAgB,WAAW,EACzB,aACA,cACA,aACA,MACA,SACA,MACA,WACA,GAAG,SACe;CAClB,MAAM,gBAAgB,QAAQ;CAC9B,MAAM,YAAY,eAAe,MAAM,gBAAgB;CACvD,MAAM,QAAQ,gBAAgB,WAAW,IAAI,WAAW,KAAA;AAMxD,KAAI,EAJF,gBAAgB,KAAA,KAChB,iBAAiB,KAAA,KACjB,UAAU,KAAA,MAEM,SAAS,KAAA,KAAa,CAAC,QAAS,QAAO;AAEzD,QACE,qBAAC,OAAD;EACE,WAAW,GACT,6EACA,UACD;EACD,GAAI;YALN;GAOE,oBAAC,eAAD,EAAe,WAAU,mBAAoB,CAAA;GAE5C,gBAAgB,KAAA,KACf,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;cAAmB;IAAU,CAAA,EAC5C,aAAa,YAAY,CACrB,EAAA,CAAA;GAER,iBAAiB,KAAA,KAChB,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;cAAmB;IAAW,CAAA,EAC7C,aAAa,aAAa,CACtB,EAAA,CAAA;GAER,UAAU,KAAA,KACT,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;cAAmB;IAAa,CAAA,EAC/C,aAAa,MAAM,CACf,EAAA,CAAA;GAER,SAAS,KAAA,KACR,oBAAC,QAAD;IAAM,WAAU;cAAkB,WAAW,KAAK;IAAQ,CAAA;GAE3D,WACC,oBAAC,QAAD;IAAM,WAAU;cACb;IACI,CAAA;GAEL;;;AAIV,WAAW,cAAc"}
1
+ {"version":3,"file":"ai-usage-bar-45pVRCGA.js","names":[],"sources":["../src/components/ai-usage-bar/ai-usage-bar.tsx"],"sourcesContent":["\"use client\";\n\nimport { LightningIcon } from \"@phosphor-icons/react\";\nimport type { ElementType, HTMLAttributes } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\n\n// ─── Variants ────────────────────────────────────────────────────────────────\n\nexport const SF_AI_USAGE_BAR_VARIANTS = {} as const;\nexport const SF_AI_USAGE_BAR_DEFAULT_VARIANTS = {} as const;\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type AiUsageBarProps = HTMLAttributes<HTMLDivElement> & {\n /** Input/prompt token count. */\n inputTokens?: number;\n /** Output/completion token count. */\n outputTokens?: number;\n /** Total token count. Computed from input + output if not provided. */\n totalTokens?: number;\n /** Estimated cost in USD. */\n cost?: number;\n /** Model ID being used (shown as label). */\n modelId?: string;\n /** Custom icon. Defaults to `LightningIcon`. */\n icon?: ElementType;\n};\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatTokens(count: number): string {\n if (count >= 1_000_000) return `${(count / 1_000_000).toFixed(1)}M`;\n if (count >= 1000) return `${(count / 1000).toFixed(1)}k`;\n return count.toString();\n}\n\nfunction formatCost(usd: number): string {\n if (usd < 0.01) return `<$0.01`;\n return `$${usd.toFixed(2)}`;\n}\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\n/**\n * Compact token usage display bar. Shows input/output token counts, total,\n * optional cost, and model identifier.\n *\n * Maps to harness event: `usage_update`.\n *\n * @example\n * ```tsx\n * <AiUsageBar\n * inputTokens={1234}\n * outputTokens={567}\n * cost={0.02}\n * modelId=\"claude-sonnet-4\"\n * />\n * ```\n */\nexport function AiUsageBar({\n inputTokens,\n outputTokens,\n totalTokens,\n cost,\n modelId,\n icon,\n className,\n ...props\n}: AiUsageBarProps) {\n const IconComponent = icon ?? LightningIcon;\n const computed = (inputTokens ?? 0) + (outputTokens ?? 0);\n const total = totalTokens ?? (computed > 0 ? computed : undefined);\n const hasTokens =\n inputTokens !== undefined ||\n outputTokens !== undefined ||\n total !== undefined;\n\n if (!hasTokens && cost === undefined && !modelId) return null;\n\n return (\n <div\n className={cn(\n \"flex items-center gap-3 px-3 py-1 text-[11px] tabular-nums text-sf-subtle\",\n className\n )}\n {...props}\n >\n <IconComponent className=\"size-3 shrink-0\" />\n\n {inputTokens !== undefined && (\n <span>\n <span className=\"text-sf-inactive\">in </span>\n {formatTokens(inputTokens)}\n </span>\n )}\n {outputTokens !== undefined && (\n <span>\n <span className=\"text-sf-inactive\">out </span>\n {formatTokens(outputTokens)}\n </span>\n )}\n {total !== undefined && (\n <span>\n <span className=\"text-sf-inactive\">total </span>\n {formatTokens(total)}\n </span>\n )}\n {cost !== undefined && (\n <span className=\"text-sf-subtle\">{formatCost(cost)}</span>\n )}\n {modelId && (\n <span className=\"ml-auto truncate font-mono text-sf-inactive\">\n {modelId}\n </span>\n )}\n </div>\n );\n}\n\nAiUsageBar.displayName = \"AiUsageBar\";\n"],"mappings":";;;;;AASA,IAAa,2BAA2B,CAAC;AACzC,IAAa,mCAAmC,CAAC;AAqBjD,SAAS,aAAa,OAAuB;CAC3C,IAAI,SAAS,KAAW,OAAO,IAAI,QAAQ,KAAW,QAAQ,CAAC,EAAE;CACjE,IAAI,SAAS,KAAM,OAAO,IAAI,QAAQ,KAAM,QAAQ,CAAC,EAAE;CACvD,OAAO,MAAM,SAAS;AACxB;AAEA,SAAS,WAAW,KAAqB;CACvC,IAAI,MAAM,KAAM,OAAO;CACvB,OAAO,IAAI,IAAI,QAAQ,CAAC;AAC1B;;;;;;;;;;;;;;;;;AAoBA,SAAgB,WAAW,EACzB,aACA,cACA,aACA,MACA,SACA,MACA,WACA,GAAG,SACe;CAClB,MAAM,gBAAgB,QAAQ;CAC9B,MAAM,YAAY,eAAe,MAAM,gBAAgB;CACvD,MAAM,QAAQ,gBAAgB,WAAW,IAAI,WAAW,KAAA;CAMxD,IAAI,EAJF,gBAAgB,KAAA,KAChB,iBAAiB,KAAA,KACjB,UAAU,KAAA,MAEM,SAAS,KAAA,KAAa,CAAC,SAAS,OAAO;CAEzD,OACE,qBAAC,OAAD;EACE,WAAW,GACT,6EACA,SACF;EACA,GAAI;YALN;GAOE,oBAAC,eAAD,EAAe,WAAU,kBAAmB,CAAA;GAE3C,gBAAgB,KAAA,KACf,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;cAAmB;GAAS,CAAA,GAC3C,aAAa,WAAW,CACrB,EAAA,CAAA;GAEP,iBAAiB,KAAA,KAChB,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;cAAmB;GAAU,CAAA,GAC5C,aAAa,YAAY,CACtB,EAAA,CAAA;GAEP,UAAU,KAAA,KACT,qBAAC,QAAD,EAAA,UAAA,CACE,oBAAC,QAAD;IAAM,WAAU;cAAmB;GAAY,CAAA,GAC9C,aAAa,KAAK,CACf,EAAA,CAAA;GAEP,SAAS,KAAA,KACR,oBAAC,QAAD;IAAM,WAAU;cAAkB,WAAW,IAAI;GAAQ,CAAA;GAE1D,WACC,oBAAC,QAAD;IAAM,WAAU;cACb;GACG,CAAA;EAEL;;AAET;AAEA,WAAW,cAAc"}
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import { t as cn } from "./cn-YROP2_ox.js";
3
- import { n as useLinkComponent } from "./link-provider-BUZKXaNE.js";
4
- import { t as Loader } from "./loader-DAcc-Uag.js";
5
- import { t as Tooltip } from "./tooltip-g9lFsvcT.js";
2
+ import { t as cn } from "./cn-CmAOpn49.js";
3
+ import { n as useLinkComponent } from "./link-provider-BSn8YJon.js";
4
+ import { t as Loader } from "./loader-BEMz8pJO.js";
5
+ import { t as Tooltip } from "./tooltip-uobk6Oh-.js";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
7
  //#region src/components/badge/badge.tsx
8
8
  /** Base styles applied to all badge variants. */
@@ -125,4 +125,4 @@ function Badge({ variant = SF_BADGE_DEFAULT_VARIANTS.variant, className, childre
125
125
  //#endregion
126
126
  export { badgeVariants as a, SF_BADGE_VARIANTS as i, SF_BADGE_BASE_STYLES as n, SF_BADGE_DEFAULT_VARIANTS as r, Badge as t };
127
127
 
128
- //# sourceMappingURL=badge-BheXjMc8.js.map
128
+ //# sourceMappingURL=badge-Beb-6uut.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"badge-BheXjMc8.js","names":[],"sources":["../src/components/badge/badge.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ElementType, MouseEvent, ReactNode } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\nimport { Loader } from \"../loader/loader\";\nimport { Tooltip } from \"../tooltip/tooltip\";\n\n/** Base styles applied to all badge variants. */\nexport const SF_BADGE_BASE_STYLES =\n \"inline-flex w-fit flex-none shrink-0 items-center gap-1 justify-self-start rounded-full px-2 py-0.5 text-xs font-medium whitespace-nowrap select-none cursor-default\";\n\n/** Badge variant definitions mapping variant names to their Tailwind classes and descriptions. */\nexport const SF_BADGE_VARIANTS = {\n variant: {\n primary: {\n classes: \"bg-sf-contrast text-sf-inverse\",\n description: \"Default high-emphasis badge for important labels\",\n },\n secondary: {\n classes: \"bg-sf-fill text-sf-default\",\n description: \"Subtle badge for secondary information\",\n },\n destructive: {\n classes: \"bg-sf-danger text-sf-inverse\",\n description: \"Error or danger state indicator\",\n },\n outline: {\n classes: \"border border-sf-fill bg-transparent text-sf-default\",\n description: \"Bordered badge with transparent background\",\n },\n beta: {\n classes:\n \"border border-dashed border-sf-brand bg-transparent text-sf-link\",\n description: \"Indicates beta or experimental features\",\n },\n success: {\n classes: \"bg-sf-success/20 text-sf-success\",\n description: \"Positive status indicator\",\n },\n warning: {\n classes: \"bg-sf-warning/20 text-sf-warning\",\n description: \"Caution or attention indicator\",\n },\n info: {\n classes: \"bg-sf-info/20 text-sf-link\",\n description: \"Informational badge\",\n },\n ghost: {\n classes: \"bg-transparent text-sf-strong\",\n description: \"Text-only badge with no background or border\",\n },\n },\n} as const;\n\nexport const SF_BADGE_DEFAULT_VARIANTS = {\n variant: \"primary\",\n} as const;\n\n// Derived types from SF_BADGE_VARIANTS\nexport type SFBadgeVariant = keyof typeof SF_BADGE_VARIANTS.variant;\n\nexport interface SFBadgeVariantsProps {\n variant?: SFBadgeVariant;\n}\n\nexport function badgeVariants({\n variant = SF_BADGE_DEFAULT_VARIANTS.variant,\n}: SFBadgeVariantsProps = {}) {\n return cn(\n // Base styles (exported as SF_BADGE_BASE_STYLES for Figma plugin)\n SF_BADGE_BASE_STYLES,\n // Apply variant styles from SF_BADGE_VARIANTS\n SF_BADGE_VARIANTS.variant[variant].classes\n );\n}\n\n// Legacy type alias for backwards compatibility\nexport type BadgeVariant = SFBadgeVariant;\n\nconst DOT_COLORS = {\n green: \"bg-sf-success\",\n red: \"bg-sf-danger\",\n yellow: \"bg-sf-warning\",\n blue: \"bg-sf-brand\",\n gray: \"bg-sf-subtle\",\n} as const;\n\nexport type BadgeDotColor = keyof typeof DOT_COLORS;\n\n/**\n * Badge component props.\n *\n * @example\n * ```tsx\n * <Badge variant=\"primary\">New</Badge>\n * <Badge variant=\"success\" icon={CheckCircle}>Deployed</Badge>\n * <Badge dot=\"green\">Online</Badge>\n * <Badge onDismiss={() => remove(id)}>typescript</Badge>\n * <Badge loading>Syncing</Badge>\n * <Badge onClick={() => filter(\"tag\")}>Filter</Badge>\n * ```\n */\nexport type BadgeProps = {\n /**\n * Visual style of the badge.\n * - `\"primary\"` — High-emphasis badge for important labels\n * - `\"secondary\"` — Subtle badge for secondary information\n * - `\"destructive\"` — Error or danger state indicator\n * - `\"outline\"` — Bordered badge with transparent background\n * - `\"beta\"` — Dashed-border badge for beta/experimental features\n * - `\"success\"` — Positive status indicator\n * - `\"warning\"` — Caution or attention indicator\n * - `\"info\"` — Informational badge\n * - `\"ghost\"` — Text-only badge with no background or border\n * @default \"primary\"\n */\n variant?: SFBadgeVariant;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Content rendered inside the badge. */\n children: ReactNode;\n /** Icon component rendered alongside the text. */\n icon?: ElementType;\n /**\n * Position of the icon relative to the text.\n * @default \"left\"\n */\n iconPosition?: \"left\" | \"right\";\n /** When provided, renders a dismiss button on the right. */\n onDismiss?: () => void;\n /** Shows a loading spinner, replacing the icon slot. */\n loading?: boolean;\n /** Renders a small colored status dot before the text. */\n dot?: BadgeDotColor;\n /** Wraps the badge in a Tooltip with this content. Requires a TooltipProvider ancestor. */\n tooltip?: ReactNode;\n} & (\n | { onClick?: (e: MouseEvent<HTMLButtonElement>) => void; href?: never }\n | { href?: string; onClick?: never }\n);\n\n/**\n * Small status label for categorizing or highlighting content.\n * Supports icons, loading state, status dots, dismiss, tooltip, and interactive (button/link) modes.\n *\n * @example\n * ```tsx\n * <Badge variant=\"primary\">Active</Badge>\n * <Badge variant=\"success\" dot=\"green\">Online</Badge>\n * <Badge onClick={() => apply()}>Apply filter</Badge>\n * ```\n */\nexport function Badge({\n variant = SF_BADGE_DEFAULT_VARIANTS.variant,\n className,\n children,\n icon: Icon,\n iconPosition = \"left\",\n onDismiss,\n loading,\n dot,\n tooltip,\n ...interactiveProps\n}: BadgeProps) {\n const LinkComponent = useLinkComponent();\n\n const isInteractive =\n \"onClick\" in interactiveProps\n ? !!interactiveProps.onClick\n : \"href\" in interactiveProps\n ? !!interactiveProps.href\n : false;\n\n const variantClasses = badgeVariants({ variant });\n const combinedClasses = cn(\n variantClasses,\n isInteractive && \"cursor-pointer transition-opacity hover:opacity-80\",\n className\n );\n\n // Build inner content\n const leftIcon = loading ? (\n <Loader size={12} />\n ) : Icon && iconPosition === \"left\" ? (\n <Icon className=\"size-3\" />\n ) : null;\n\n const rightIcon =\n !loading && Icon && iconPosition === \"right\" ? (\n <Icon className=\"size-3\" />\n ) : null;\n\n const dotElement = dot ? (\n <span className={cn(\"size-1.5 rounded-full\", DOT_COLORS[dot])} />\n ) : null;\n\n const dismissButton = onDismiss ? (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDismiss();\n }}\n className=\"-mr-0.5 ml-0.5 inline-flex size-3 cursor-pointer items-center justify-center rounded-full opacity-70 hover:opacity-100\"\n aria-label=\"Remove\"\n >\n <svg\n className=\"size-2.5\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n >\n <path d=\"M3 3l6 6M9 3l-6 6\" />\n </svg>\n </button>\n ) : null;\n\n const content = (\n <>\n {dotElement}\n {leftIcon}\n {children}\n {rightIcon}\n {dismissButton}\n </>\n );\n\n // Determine the element to render\n let badge: ReactNode;\n\n if (\"href\" in interactiveProps && interactiveProps.href) {\n badge = (\n <LinkComponent href={interactiveProps.href} className={combinedClasses}>\n {content}\n </LinkComponent>\n );\n } else if (\"onClick\" in interactiveProps && interactiveProps.onClick) {\n const handleClick = interactiveProps.onClick;\n badge = (\n <button type=\"button\" onClick={handleClick} className={combinedClasses}>\n {content}\n </button>\n );\n } else {\n badge = <span className={combinedClasses}>{content}</span>;\n }\n\n if (tooltip) {\n return <Tooltip content={tooltip}>{badge}</Tooltip>;\n }\n\n return badge;\n}\n"],"mappings":";;;;;;;;AAUA,IAAa,uBACX;;AAGF,IAAa,oBAAoB,EAC/B,SAAS;CACP,SAAS;EACP,SAAS;EACT,aAAa;EACd;CACD,WAAW;EACT,SAAS;EACT,aAAa;EACd;CACD,aAAa;EACX,SAAS;EACT,aAAa;EACd;CACD,SAAS;EACP,SAAS;EACT,aAAa;EACd;CACD,MAAM;EACJ,SACE;EACF,aAAa;EACd;CACD,SAAS;EACP,SAAS;EACT,aAAa;EACd;CACD,SAAS;EACP,SAAS;EACT,aAAa;EACd;CACD,MAAM;EACJ,SAAS;EACT,aAAa;EACd;CACD,OAAO;EACL,SAAS;EACT,aAAa;EACd;CACF,EACF;AAED,IAAa,4BAA4B,EACvC,SAAS,WACV;AASD,SAAgB,cAAc,EAC5B,UAAU,0BAA0B,YACZ,EAAE,EAAE;AAC5B,QAAO,GAEL,sBAEA,kBAAkB,QAAQ,SAAS,QACpC;;AAMH,IAAM,aAAa;CACjB,OAAO;CACP,KAAK;CACL,QAAQ;CACR,MAAM;CACN,MAAM;CACP;;;;;;;;;;;;AAmED,SAAgB,MAAM,EACpB,UAAU,0BAA0B,SACpC,WACA,UACA,MAAM,MACN,eAAe,QACf,WACA,SACA,KACA,SACA,GAAG,oBACU;CACb,MAAM,gBAAgB,kBAAkB;CAExC,MAAM,gBACJ,aAAa,mBACT,CAAC,CAAC,iBAAiB,UACnB,UAAU,mBACR,CAAC,CAAC,iBAAiB,OACnB;CAGR,MAAM,kBAAkB,GADD,cAAc,EAAE,SAAS,CAAC,EAG/C,iBAAiB,sDACjB,UACD;CAGD,MAAM,WAAW,UACf,oBAAC,QAAD,EAAQ,MAAM,IAAM,CAAA,GAClB,QAAQ,iBAAiB,SAC3B,oBAAC,MAAD,EAAM,WAAU,UAAW,CAAA,GACzB;CAEJ,MAAM,YACJ,CAAC,WAAW,QAAQ,iBAAiB,UACnC,oBAAC,MAAD,EAAM,WAAU,UAAW,CAAA,GACzB;CA6BN,MAAM,UACJ,qBAAA,UAAA,EAAA,UAAA;EA5BiB,MACjB,oBAAC,QAAD,EAAM,WAAW,GAAG,yBAAyB,WAAW,KAAK,EAAI,CAAA,GAC/D;EA4BC;EACA;EACA;EA5BiB,YACpB,oBAAC,UAAD;GACE,MAAK;GACL,UAAU,MAAM;AACd,MAAE,iBAAiB;AACnB,eAAW;;GAEb,WAAU;GACV,cAAW;aAEX,oBAAC,OAAD;IACE,WAAU;IACV,SAAQ;IACR,MAAK;IACL,QAAO;IACP,aAAY;IACZ,eAAc;cAEd,oBAAC,QAAD,EAAM,GAAE,qBAAsB,CAAA;IAC1B,CAAA;GACC,CAAA,GACP;EASC,EAAA,CAAA;CAIL,IAAI;AAEJ,KAAI,UAAU,oBAAoB,iBAAiB,KACjD,SACE,oBAAC,eAAD;EAAe,MAAM,iBAAiB;EAAM,WAAW;YACpD;EACa,CAAA;UAET,aAAa,oBAAoB,iBAAiB,SAAS;EACpE,MAAM,cAAc,iBAAiB;AACrC,UACE,oBAAC,UAAD;GAAQ,MAAK;GAAS,SAAS;GAAa,WAAW;aACpD;GACM,CAAA;OAGX,SAAQ,oBAAC,QAAD;EAAM,WAAW;YAAkB;EAAe,CAAA;AAG5D,KAAI,QACF,QAAO,oBAAC,SAAD;EAAS,SAAS;YAAU;EAAgB,CAAA;AAGrD,QAAO"}
1
+ {"version":3,"file":"badge-Beb-6uut.js","names":[],"sources":["../src/components/badge/badge.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ElementType, MouseEvent, ReactNode } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\nimport { Loader } from \"../loader/loader\";\nimport { Tooltip } from \"../tooltip/tooltip\";\n\n/** Base styles applied to all badge variants. */\nexport const SF_BADGE_BASE_STYLES =\n \"inline-flex w-fit flex-none shrink-0 items-center gap-1 justify-self-start rounded-full px-2 py-0.5 text-xs font-medium whitespace-nowrap select-none cursor-default\";\n\n/** Badge variant definitions mapping variant names to their Tailwind classes and descriptions. */\nexport const SF_BADGE_VARIANTS = {\n variant: {\n primary: {\n classes: \"bg-sf-contrast text-sf-inverse\",\n description: \"Default high-emphasis badge for important labels\",\n },\n secondary: {\n classes: \"bg-sf-fill text-sf-default\",\n description: \"Subtle badge for secondary information\",\n },\n destructive: {\n classes: \"bg-sf-danger text-sf-inverse\",\n description: \"Error or danger state indicator\",\n },\n outline: {\n classes: \"border border-sf-fill bg-transparent text-sf-default\",\n description: \"Bordered badge with transparent background\",\n },\n beta: {\n classes:\n \"border border-dashed border-sf-brand bg-transparent text-sf-link\",\n description: \"Indicates beta or experimental features\",\n },\n success: {\n classes: \"bg-sf-success/20 text-sf-success\",\n description: \"Positive status indicator\",\n },\n warning: {\n classes: \"bg-sf-warning/20 text-sf-warning\",\n description: \"Caution or attention indicator\",\n },\n info: {\n classes: \"bg-sf-info/20 text-sf-link\",\n description: \"Informational badge\",\n },\n ghost: {\n classes: \"bg-transparent text-sf-strong\",\n description: \"Text-only badge with no background or border\",\n },\n },\n} as const;\n\nexport const SF_BADGE_DEFAULT_VARIANTS = {\n variant: \"primary\",\n} as const;\n\n// Derived types from SF_BADGE_VARIANTS\nexport type SFBadgeVariant = keyof typeof SF_BADGE_VARIANTS.variant;\n\nexport interface SFBadgeVariantsProps {\n variant?: SFBadgeVariant;\n}\n\nexport function badgeVariants({\n variant = SF_BADGE_DEFAULT_VARIANTS.variant,\n}: SFBadgeVariantsProps = {}) {\n return cn(\n // Base styles (exported as SF_BADGE_BASE_STYLES for Figma plugin)\n SF_BADGE_BASE_STYLES,\n // Apply variant styles from SF_BADGE_VARIANTS\n SF_BADGE_VARIANTS.variant[variant].classes\n );\n}\n\n// Legacy type alias for backwards compatibility\nexport type BadgeVariant = SFBadgeVariant;\n\nconst DOT_COLORS = {\n green: \"bg-sf-success\",\n red: \"bg-sf-danger\",\n yellow: \"bg-sf-warning\",\n blue: \"bg-sf-brand\",\n gray: \"bg-sf-subtle\",\n} as const;\n\nexport type BadgeDotColor = keyof typeof DOT_COLORS;\n\n/**\n * Badge component props.\n *\n * @example\n * ```tsx\n * <Badge variant=\"primary\">New</Badge>\n * <Badge variant=\"success\" icon={CheckCircle}>Deployed</Badge>\n * <Badge dot=\"green\">Online</Badge>\n * <Badge onDismiss={() => remove(id)}>typescript</Badge>\n * <Badge loading>Syncing</Badge>\n * <Badge onClick={() => filter(\"tag\")}>Filter</Badge>\n * ```\n */\nexport type BadgeProps = {\n /**\n * Visual style of the badge.\n * - `\"primary\"` — High-emphasis badge for important labels\n * - `\"secondary\"` — Subtle badge for secondary information\n * - `\"destructive\"` — Error or danger state indicator\n * - `\"outline\"` — Bordered badge with transparent background\n * - `\"beta\"` — Dashed-border badge for beta/experimental features\n * - `\"success\"` — Positive status indicator\n * - `\"warning\"` — Caution or attention indicator\n * - `\"info\"` — Informational badge\n * - `\"ghost\"` — Text-only badge with no background or border\n * @default \"primary\"\n */\n variant?: SFBadgeVariant;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Content rendered inside the badge. */\n children: ReactNode;\n /** Icon component rendered alongside the text. */\n icon?: ElementType;\n /**\n * Position of the icon relative to the text.\n * @default \"left\"\n */\n iconPosition?: \"left\" | \"right\";\n /** When provided, renders a dismiss button on the right. */\n onDismiss?: () => void;\n /** Shows a loading spinner, replacing the icon slot. */\n loading?: boolean;\n /** Renders a small colored status dot before the text. */\n dot?: BadgeDotColor;\n /** Wraps the badge in a Tooltip with this content. Requires a TooltipProvider ancestor. */\n tooltip?: ReactNode;\n} & (\n | { onClick?: (e: MouseEvent<HTMLButtonElement>) => void; href?: never }\n | { href?: string; onClick?: never }\n);\n\n/**\n * Small status label for categorizing or highlighting content.\n * Supports icons, loading state, status dots, dismiss, tooltip, and interactive (button/link) modes.\n *\n * @example\n * ```tsx\n * <Badge variant=\"primary\">Active</Badge>\n * <Badge variant=\"success\" dot=\"green\">Online</Badge>\n * <Badge onClick={() => apply()}>Apply filter</Badge>\n * ```\n */\nexport function Badge({\n variant = SF_BADGE_DEFAULT_VARIANTS.variant,\n className,\n children,\n icon: Icon,\n iconPosition = \"left\",\n onDismiss,\n loading,\n dot,\n tooltip,\n ...interactiveProps\n}: BadgeProps) {\n const LinkComponent = useLinkComponent();\n\n const isInteractive =\n \"onClick\" in interactiveProps\n ? !!interactiveProps.onClick\n : \"href\" in interactiveProps\n ? !!interactiveProps.href\n : false;\n\n const variantClasses = badgeVariants({ variant });\n const combinedClasses = cn(\n variantClasses,\n isInteractive && \"cursor-pointer transition-opacity hover:opacity-80\",\n className\n );\n\n // Build inner content\n const leftIcon = loading ? (\n <Loader size={12} />\n ) : Icon && iconPosition === \"left\" ? (\n <Icon className=\"size-3\" />\n ) : null;\n\n const rightIcon =\n !loading && Icon && iconPosition === \"right\" ? (\n <Icon className=\"size-3\" />\n ) : null;\n\n const dotElement = dot ? (\n <span className={cn(\"size-1.5 rounded-full\", DOT_COLORS[dot])} />\n ) : null;\n\n const dismissButton = onDismiss ? (\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onDismiss();\n }}\n className=\"-mr-0.5 ml-0.5 inline-flex size-3 cursor-pointer items-center justify-center rounded-full opacity-70 hover:opacity-100\"\n aria-label=\"Remove\"\n >\n <svg\n className=\"size-2.5\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n >\n <path d=\"M3 3l6 6M9 3l-6 6\" />\n </svg>\n </button>\n ) : null;\n\n const content = (\n <>\n {dotElement}\n {leftIcon}\n {children}\n {rightIcon}\n {dismissButton}\n </>\n );\n\n // Determine the element to render\n let badge: ReactNode;\n\n if (\"href\" in interactiveProps && interactiveProps.href) {\n badge = (\n <LinkComponent href={interactiveProps.href} className={combinedClasses}>\n {content}\n </LinkComponent>\n );\n } else if (\"onClick\" in interactiveProps && interactiveProps.onClick) {\n const handleClick = interactiveProps.onClick;\n badge = (\n <button type=\"button\" onClick={handleClick} className={combinedClasses}>\n {content}\n </button>\n );\n } else {\n badge = <span className={combinedClasses}>{content}</span>;\n }\n\n if (tooltip) {\n return <Tooltip content={tooltip}>{badge}</Tooltip>;\n }\n\n return badge;\n}\n"],"mappings":";;;;;;;;AAUA,IAAa,uBACX;;AAGF,IAAa,oBAAoB,EAC/B,SAAS;CACP,SAAS;EACP,SAAS;EACT,aAAa;CACf;CACA,WAAW;EACT,SAAS;EACT,aAAa;CACf;CACA,aAAa;EACX,SAAS;EACT,aAAa;CACf;CACA,SAAS;EACP,SAAS;EACT,aAAa;CACf;CACA,MAAM;EACJ,SACE;EACF,aAAa;CACf;CACA,SAAS;EACP,SAAS;EACT,aAAa;CACf;CACA,SAAS;EACP,SAAS;EACT,aAAa;CACf;CACA,MAAM;EACJ,SAAS;EACT,aAAa;CACf;CACA,OAAO;EACL,SAAS;EACT,aAAa;CACf;AACF,EACF;AAEA,IAAa,4BAA4B,EACvC,SAAS,UACX;AASA,SAAgB,cAAc,EAC5B,UAAU,0BAA0B,YACZ,CAAC,GAAG;CAC5B,OAAO,GAEL,sBAEA,kBAAkB,QAAQ,SAAS,OACrC;AACF;AAKA,IAAM,aAAa;CACjB,OAAO;CACP,KAAK;CACL,QAAQ;CACR,MAAM;CACN,MAAM;AACR;;;;;;;;;;;;AAmEA,SAAgB,MAAM,EACpB,UAAU,0BAA0B,SACpC,WACA,UACA,MAAM,MACN,eAAe,QACf,WACA,SACA,KACA,SACA,GAAG,oBACU;CACb,MAAM,gBAAgB,iBAAiB;CAEvC,MAAM,gBACJ,aAAa,mBACT,CAAC,CAAC,iBAAiB,UACnB,UAAU,mBACR,CAAC,CAAC,iBAAiB,OACnB;CAGR,MAAM,kBAAkB,GADD,cAAc,EAAE,QAAQ,CAE7C,GACA,iBAAiB,sDACjB,SACF;CAGA,MAAM,WAAW,UACf,oBAAC,QAAD,EAAQ,MAAM,GAAK,CAAA,IACjB,QAAQ,iBAAiB,SAC3B,oBAAC,MAAD,EAAM,WAAU,SAAU,CAAA,IACxB;CAEJ,MAAM,YACJ,CAAC,WAAW,QAAQ,iBAAiB,UACnC,oBAAC,MAAD,EAAM,WAAU,SAAU,CAAA,IACxB;CA6BN,MAAM,UACJ,qBAAA,UAAA,EAAA,UAAA;EA5BiB,MACjB,oBAAC,QAAD,EAAM,WAAW,GAAG,yBAAyB,WAAW,IAAI,EAAI,CAAA,IAC9D;EA4BC;EACA;EACA;EA5BiB,YACpB,oBAAC,UAAD;GACE,MAAK;GACL,UAAU,MAAM;IACd,EAAE,gBAAgB;IAClB,UAAU;GACZ;GACA,WAAU;GACV,cAAW;aAEX,oBAAC,OAAD;IACE,WAAU;IACV,SAAQ;IACR,MAAK;IACL,QAAO;IACP,aAAY;IACZ,eAAc;cAEd,oBAAC,QAAD,EAAM,GAAE,oBAAqB,CAAA;GAC1B,CAAA;EACC,CAAA,IACN;CASA,EAAA,CAAA;CAIJ,IAAI;CAEJ,IAAI,UAAU,oBAAoB,iBAAiB,MACjD,QACE,oBAAC,eAAD;EAAe,MAAM,iBAAiB;EAAM,WAAW;YACpD;CACY,CAAA;MAEZ,IAAI,aAAa,oBAAoB,iBAAiB,SAAS;EACpE,MAAM,cAAc,iBAAiB;EACrC,QACE,oBAAC,UAAD;GAAQ,MAAK;GAAS,SAAS;GAAa,WAAW;aACpD;EACK,CAAA;CAEZ,OACE,QAAQ,oBAAC,QAAD;EAAM,WAAW;YAAkB;CAAc,CAAA;CAG3D,IAAI,SACF,OAAO,oBAAC,SAAD;EAAS,SAAS;YAAU;CAAe,CAAA;CAGpD,OAAO;AACT"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
- import { t as cn } from "./cn-YROP2_ox.js";
3
- import { t as Text } from "./text-Cqryz7rk.js";
2
+ import { t as cn } from "./cn-CmAOpn49.js";
3
+ import { t as Text } from "./text-iQ0YUFNg.js";
4
4
  import { isValidElement } from "react";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  //#region src/components/banner/banner.tsx
@@ -56,4 +56,4 @@ function Banner({ icon, children, text, variant = SF_BANNER_DEFAULT_VARIANTS.var
56
56
  //#endregion
57
57
  export { BannerVariant as n, Banner as t };
58
58
 
59
- //# sourceMappingURL=banner-CcsjunJg.js.map
59
+ //# sourceMappingURL=banner-CCEksxPg.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"banner-CcsjunJg.js","names":[],"sources":["../src/components/banner/banner.tsx"],"sourcesContent":["import { type ReactNode, isValidElement } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { Text } from \"../text\";\n\n/** Base styles applied to all banner variants. */\nexport const SF_BANNER_BASE_STYLES =\n \"flex w-full items-center gap-2 rounded-lg border px-4 py-1.5 text-base\";\n\n/** Banner variant definitions mapping variant names to their Tailwind classes and descriptions. */\nexport const SF_BANNER_VARIANTS = {\n variant: {\n default: {\n classes:\n \"bg-sf-info/20 border-sf-info text-sf-link selection:bg-sf-info-tint\",\n description: \"Informational banner for general messages\",\n },\n alert: {\n classes:\n \"bg-sf-warning/20 border-sf-warning text-sf-warning selection:bg-sf-warning-tint\",\n description: \"Warning banner for cautionary messages\",\n },\n error: {\n classes:\n \"bg-sf-danger/20 border-sf-danger text-sf-danger selection:bg-sf-danger-tint\",\n description: \"Error banner for critical issues\",\n },\n },\n} as const;\n\nexport const SF_BANNER_DEFAULT_VARIANTS = {\n variant: \"default\",\n} as const;\n\n// Derived types from SF_BANNER_VARIANTS\nexport type SFBannerVariant = keyof typeof SF_BANNER_VARIANTS.variant;\n\nexport interface SFBannerVariantsProps {\n /**\n * Visual style of the banner.\n * - `\"default\"` — Informational banner for general messages\n * - `\"alert\"` — Warning banner for cautionary messages\n * - `\"error\"` — Error banner for critical issues\n * @default \"default\"\n */\n variant?: SFBannerVariant;\n}\n\nexport function bannerVariants({\n variant = SF_BANNER_DEFAULT_VARIANTS.variant,\n}: SFBannerVariantsProps = {}) {\n return cn(\n // Base styles (exported as SF_BANNER_BASE_STYLES for Figma plugin)\n SF_BANNER_BASE_STYLES,\n // Apply variant styles from SF_BANNER_VARIANTS\n SF_BANNER_VARIANTS.variant[variant].classes\n );\n}\n\n// Legacy enum for backwards compatibility\nexport enum BannerVariant {\n DEFAULT,\n ALERT,\n ERROR,\n}\n\n/**\n * Banner component props.\n *\n * @example\n * ```tsx\n * <Banner>This is an informational banner.</Banner>\n * <Banner variant=\"alert\">Your session will expire soon.</Banner>\n * <Banner variant=\"error\">We couldn't save your changes.</Banner>\n * ```\n */\nexport interface BannerProps {\n /** Icon element rendered before the banner text (e.g. from `@phosphor-icons/react`). */\n icon?: ReactNode;\n /** @deprecated Use `children` instead. Will be removed in a future major version. */\n text?: string;\n /** Banner message content. Accepts strings or custom React elements. */\n children?: ReactNode;\n /**\n * Visual style of the banner.\n * - `\"default\"` — Informational blue banner for general messages\n * - `\"alert\"` — Warning yellow banner for cautionary messages\n * - `\"error\"` — Error red banner for critical issues\n * @default \"default\"\n */\n variant?: SFBannerVariant;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n}\n\n/**\n * Full-width message bar for informational, warning, or error notices.\n *\n * @example\n * ```tsx\n * <Banner variant=\"alert\" icon={<WarningCircle />}>\n * Review your billing information.\n * </Banner>\n * ```\n */\nexport function Banner({\n icon,\n children,\n text,\n variant = SF_BANNER_DEFAULT_VARIANTS.variant,\n className,\n}: BannerProps) {\n // Prefer children over deprecated text prop\n const value = children ?? text;\n\n const content = isValidElement(value) ? (\n value\n ) : (\n <Text wrap=\"balance\" as=\"p\">\n {value}\n </Text>\n );\n\n return (\n <div className={cn(bannerVariants({ variant }), className)}>\n {icon}\n {content}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAMA,IAAa,wBACX;;AAGF,IAAa,qBAAqB,EAChC,SAAS;CACP,SAAS;EACP,SACE;EACF,aAAa;EACd;CACD,OAAO;EACL,SACE;EACF,aAAa;EACd;CACD,OAAO;EACL,SACE;EACF,aAAa;EACd;CACF,EACF;AAED,IAAa,6BAA6B,EACxC,SAAS,WACV;AAgBD,SAAgB,eAAe,EAC7B,UAAU,2BAA2B,YACZ,EAAE,EAAE;AAC7B,QAAO,GAEL,uBAEA,mBAAmB,QAAQ,SAAS,QACrC;;AAIH,IAAY,gBAAL,yBAAA,eAAA;AACL,eAAA,cAAA,aAAA,KAAA;AACA,eAAA,cAAA,WAAA,KAAA;AACA,eAAA,cAAA,WAAA,KAAA;;KACD;;;;;;;;;;;AAyCD,SAAgB,OAAO,EACrB,MACA,UACA,MACA,UAAU,2BAA2B,SACrC,aACc;CAEd,MAAM,QAAQ,YAAY;CAE1B,MAAM,UAAU,eAAe,MAAM,GACnC,QAEA,oBAAC,MAAD;EAAM,MAAK;EAAU,IAAG;YACrB;EACI,CAAA;AAGT,QACE,qBAAC,OAAD;EAAK,WAAW,GAAG,eAAe,EAAE,SAAS,CAAC,EAAE,UAAU;YAA1D,CACG,MACA,QACG"}
1
+ {"version":3,"file":"banner-CCEksxPg.js","names":[],"sources":["../src/components/banner/banner.tsx"],"sourcesContent":["import { type ReactNode, isValidElement } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { Text } from \"../text\";\n\n/** Base styles applied to all banner variants. */\nexport const SF_BANNER_BASE_STYLES =\n \"flex w-full items-center gap-2 rounded-lg border px-4 py-1.5 text-base\";\n\n/** Banner variant definitions mapping variant names to their Tailwind classes and descriptions. */\nexport const SF_BANNER_VARIANTS = {\n variant: {\n default: {\n classes:\n \"bg-sf-info/20 border-sf-info text-sf-link selection:bg-sf-info-tint\",\n description: \"Informational banner for general messages\",\n },\n alert: {\n classes:\n \"bg-sf-warning/20 border-sf-warning text-sf-warning selection:bg-sf-warning-tint\",\n description: \"Warning banner for cautionary messages\",\n },\n error: {\n classes:\n \"bg-sf-danger/20 border-sf-danger text-sf-danger selection:bg-sf-danger-tint\",\n description: \"Error banner for critical issues\",\n },\n },\n} as const;\n\nexport const SF_BANNER_DEFAULT_VARIANTS = {\n variant: \"default\",\n} as const;\n\n// Derived types from SF_BANNER_VARIANTS\nexport type SFBannerVariant = keyof typeof SF_BANNER_VARIANTS.variant;\n\nexport interface SFBannerVariantsProps {\n /**\n * Visual style of the banner.\n * - `\"default\"` — Informational banner for general messages\n * - `\"alert\"` — Warning banner for cautionary messages\n * - `\"error\"` — Error banner for critical issues\n * @default \"default\"\n */\n variant?: SFBannerVariant;\n}\n\nexport function bannerVariants({\n variant = SF_BANNER_DEFAULT_VARIANTS.variant,\n}: SFBannerVariantsProps = {}) {\n return cn(\n // Base styles (exported as SF_BANNER_BASE_STYLES for Figma plugin)\n SF_BANNER_BASE_STYLES,\n // Apply variant styles from SF_BANNER_VARIANTS\n SF_BANNER_VARIANTS.variant[variant].classes\n );\n}\n\n// Legacy enum for backwards compatibility\nexport enum BannerVariant {\n DEFAULT,\n ALERT,\n ERROR,\n}\n\n/**\n * Banner component props.\n *\n * @example\n * ```tsx\n * <Banner>This is an informational banner.</Banner>\n * <Banner variant=\"alert\">Your session will expire soon.</Banner>\n * <Banner variant=\"error\">We couldn't save your changes.</Banner>\n * ```\n */\nexport interface BannerProps {\n /** Icon element rendered before the banner text (e.g. from `@phosphor-icons/react`). */\n icon?: ReactNode;\n /** @deprecated Use `children` instead. Will be removed in a future major version. */\n text?: string;\n /** Banner message content. Accepts strings or custom React elements. */\n children?: ReactNode;\n /**\n * Visual style of the banner.\n * - `\"default\"` — Informational blue banner for general messages\n * - `\"alert\"` — Warning yellow banner for cautionary messages\n * - `\"error\"` — Error red banner for critical issues\n * @default \"default\"\n */\n variant?: SFBannerVariant;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n}\n\n/**\n * Full-width message bar for informational, warning, or error notices.\n *\n * @example\n * ```tsx\n * <Banner variant=\"alert\" icon={<WarningCircle />}>\n * Review your billing information.\n * </Banner>\n * ```\n */\nexport function Banner({\n icon,\n children,\n text,\n variant = SF_BANNER_DEFAULT_VARIANTS.variant,\n className,\n}: BannerProps) {\n // Prefer children over deprecated text prop\n const value = children ?? text;\n\n const content = isValidElement(value) ? (\n value\n ) : (\n <Text wrap=\"balance\" as=\"p\">\n {value}\n </Text>\n );\n\n return (\n <div className={cn(bannerVariants({ variant }), className)}>\n {icon}\n {content}\n </div>\n );\n}\n"],"mappings":";;;;;;;AAMA,IAAa,wBACX;;AAGF,IAAa,qBAAqB,EAChC,SAAS;CACP,SAAS;EACP,SACE;EACF,aAAa;CACf;CACA,OAAO;EACL,SACE;EACF,aAAa;CACf;CACA,OAAO;EACL,SACE;EACF,aAAa;CACf;AACF,EACF;AAEA,IAAa,6BAA6B,EACxC,SAAS,UACX;AAgBA,SAAgB,eAAe,EAC7B,UAAU,2BAA2B,YACZ,CAAC,GAAG;CAC7B,OAAO,GAEL,uBAEA,mBAAmB,QAAQ,SAAS,OACtC;AACF;AAGA,IAAY,gBAAL,yBAAA,eAAA;CACL,cAAA,cAAA,aAAA,KAAA;CACA,cAAA,cAAA,WAAA,KAAA;CACA,cAAA,cAAA,WAAA,KAAA;;AACF,EAAA,CAAA,CAAA;;;;;;;;;;;AAyCA,SAAgB,OAAO,EACrB,MACA,UACA,MACA,UAAU,2BAA2B,SACrC,aACc;CAEd,MAAM,QAAQ,YAAY;CAE1B,MAAM,UAAU,eAAe,KAAK,IAClC,QAEA,oBAAC,MAAD;EAAM,MAAK;EAAU,IAAG;YACrB;CACG,CAAA;CAGR,OACE,qBAAC,OAAD;EAAK,WAAW,GAAG,eAAe,EAAE,QAAQ,CAAC,GAAG,SAAS;YAAzD,CACG,MACA,OACE;;AAET"}
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import { t as cn } from "./cn-YROP2_ox.js";
3
- import { n as useLinkComponent } from "./link-provider-BUZKXaNE.js";
4
- import { t as Button } from "./button-CO6-qPax.js";
5
- import { t as SkeletonLine } from "./skeleton-line-CH1-h6e2.js";
2
+ import { t as cn } from "./cn-CmAOpn49.js";
3
+ import { n as useLinkComponent } from "./link-provider-BSn8YJon.js";
4
+ import { t as Button } from "./button-BHOgXJRU.js";
5
+ import { t as SkeletonLine } from "./skeleton-line-CxxYVTO2.js";
6
6
  import { useEffect, useState } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { CheckIcon, CopyIcon } from "@phosphor-icons/react";
@@ -125,4 +125,4 @@ Breadcrumb.Clipboard = Clipboard;
125
125
  //#endregion
126
126
  export { breadcrumbsVariants as i, SF_BREADCRUMBS_DEFAULT_VARIANTS as n, SF_BREADCRUMBS_VARIANTS as r, Breadcrumb as t };
127
127
 
128
- //# sourceMappingURL=breadcrumbs-CouSyy3H.js.map
128
+ //# sourceMappingURL=breadcrumbs-HiTmgaZ4.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"breadcrumbs-CouSyy3H.js","names":[],"sources":["../src/components/breadcrumbs/breadcrumbs.tsx"],"sourcesContent":["import { CheckIcon, CopyIcon } from \"@phosphor-icons/react\";\nimport { useEffect, useState, type PropsWithChildren } from \"react\";\n\nimport { Button } from \"../../components/button\";\nimport { SkeletonLine } from \"../../components/loader/skeleton-line\";\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\n\n/** Breadcrumbs size variant definitions. */\nexport const SF_BREADCRUMBS_VARIANTS = {\n size: {\n sm: {\n classes: \"text-sm h-10 gap-0.5\",\n description: \"Compact breadcrumbs for dense UIs\",\n },\n base: {\n classes: \"text-base h-12 gap-1\",\n description: \"Default breadcrumbs size\",\n },\n },\n} as const;\n\nexport const SF_BREADCRUMBS_DEFAULT_VARIANTS = {\n size: \"base\",\n} as const;\n\nexport type SFBreadcrumbsSize = keyof typeof SF_BREADCRUMBS_VARIANTS.size;\n\nexport interface SFBreadcrumbsVariantsProps {\n /**\n * Size of the breadcrumbs.\n * - `\"sm\"` — Compact breadcrumbs for dense UIs\n * - `\"base\"` — Default breadcrumbs size\n * @default \"base\"\n */\n size?: SFBreadcrumbsSize;\n}\n\nexport function breadcrumbsVariants({\n size = SF_BREADCRUMBS_DEFAULT_VARIANTS.size,\n}: SFBreadcrumbsVariantsProps = {}) {\n return cn(\n \"group mr-4 hidden min-w-0 grow items-center sm:flex\",\n SF_BREADCRUMBS_VARIANTS.size[size].classes\n );\n}\n\nexport interface BreadcrumbsItemProps {\n href: string;\n icon?: React.ReactNode;\n}\n\nconst Link = ({\n href,\n icon,\n children,\n}: PropsWithChildren<BreadcrumbsItemProps>) => {\n const LinkComponent = useLinkComponent();\n\n return (\n <LinkComponent\n to={href}\n className=\"flex min-w-0 items-center gap-1 text-sf-subtle no-underline\"\n >\n {!!icon && <span className=\"flex shrink-0 items-center\">{icon}</span>}\n {children}\n </LinkComponent>\n );\n};\n\ninterface BreadcrumbsCurrentProps {\n loading?: boolean;\n icon?: React.ReactNode;\n}\n\nfunction Current({\n children,\n icon,\n loading,\n}: PropsWithChildren<BreadcrumbsCurrentProps>) {\n if (loading) {\n return (\n <div className=\"flex w-[125px] min-w-0 items-center gap-1\">\n {icon && <span className=\"flex shrink-0 items-center\">{icon}</span>}\n <SkeletonLine />\n </div>\n );\n }\n\n return (\n <div\n className=\"flex items-center gap-1 truncate font-medium\"\n aria-current=\"page\"\n >\n {icon && <span className=\"flex shrink-0 items-center\">{icon}</span>}\n {children}\n </div>\n );\n}\n\nfunction Separator() {\n return (\n <span className=\"flex items-center text-sf-inactive\" aria-hidden=\"true\">\n <svg width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\">\n <path\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n d=\"M10.75 8.75L14.25 12L10.75 15.25\"\n />\n </svg>\n </span>\n );\n}\n\nfunction Clipboard({ text }: { text: string }) {\n const [isCopied, setIsCopied] = useState(false);\n\n useEffect(() => {\n if (!isCopied) return;\n\n const timeoutId = setTimeout(() => setIsCopied(false), 2000);\n return () => clearTimeout(timeoutId);\n }, [isCopied]);\n\n const handleCopyDeeplink = async () => {\n if (!text) return;\n\n try {\n await navigator.clipboard.writeText(text);\n setIsCopied(true);\n } catch (err) {\n console.error(\"Failed to copy deeplink:\", err);\n }\n };\n\n return (\n <Button\n variant=\"ghost\"\n shape=\"square\"\n size=\"sm\"\n className=\"opacity-0 transition-[opacity] group-hover:opacity-100\"\n onClick={handleCopyDeeplink}\n title=\"Click to copy\"\n aria-label=\"Copy\"\n >\n {isCopied ? (\n <CheckIcon weight=\"bold\" className=\"text-sf-success\" />\n ) : (\n <CopyIcon weight=\"regular\" />\n )}\n </Button>\n );\n}\n\n/**\n * Breadcrumbs component props.\n *\n * @example\n * ```tsx\n * <Breadcrumbs>\n * <Breadcrumbs.Link href=\"/\">Home</Breadcrumbs.Link>\n * <Breadcrumbs.Separator />\n * <Breadcrumbs.Link href=\"/docs\">Docs</Breadcrumbs.Link>\n * <Breadcrumbs.Separator />\n * <Breadcrumbs.Current>Current Page</Breadcrumbs.Current>\n * </Breadcrumbs>\n * ```\n */\nexport interface BreadcrumbsProps\n extends PropsWithChildren, SFBreadcrumbsVariantsProps {\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n}\n\n/**\n * Navigation breadcrumb trail showing the current page's location in a hierarchy.\n * Compound component with `Breadcrumbs.Link`, `Breadcrumbs.Current`, `Breadcrumbs.Separator`, and `Breadcrumbs.Clipboard`.\n *\n * @example\n * ```tsx\n * <Breadcrumbs>\n * <Breadcrumbs.Link href=\"/\">Home</Breadcrumbs.Link>\n * <Breadcrumbs.Separator />\n * <Breadcrumbs.Current>Dashboard</Breadcrumbs.Current>\n * </Breadcrumbs>\n * ```\n */\nexport function Breadcrumb({\n children,\n size = \"base\",\n className,\n}: BreadcrumbsProps) {\n return (\n <nav\n className={cn(breadcrumbsVariants({ size }), className)}\n aria-label=\"breadcrumb\"\n >\n {children}\n </nav>\n );\n}\n\nBreadcrumb.Link = Link;\nBreadcrumb.Current = Current;\nBreadcrumb.Separator = Separator;\nBreadcrumb.Clipboard = Clipboard;\n"],"mappings":";;;;;;;;;;AASA,IAAa,0BAA0B,EACrC,MAAM;CACJ,IAAI;EACF,SAAS;EACT,aAAa;EACd;CACD,MAAM;EACJ,SAAS;EACT,aAAa;EACd;CACF,EACF;AAED,IAAa,kCAAkC,EAC7C,MAAM,QACP;AAcD,SAAgB,oBAAoB,EAClC,OAAO,gCAAgC,SACT,EAAE,EAAE;AAClC,QAAO,GACL,uDACA,wBAAwB,KAAK,MAAM,QACpC;;AAQH,IAAM,QAAQ,EACZ,MACA,MACA,eAC6C;AAG7C,QACE,qBAHoB,kBAAkB,EAGtC;EACE,IAAI;EACJ,WAAU;YAFZ,CAIG,CAAC,CAAC,QAAQ,oBAAC,QAAD;GAAM,WAAU;aAA8B;GAAY,CAAA,EACpE,SACa;;;AASpB,SAAS,QAAQ,EACf,UACA,MACA,WAC6C;AAC7C,KAAI,QACF,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,QAAQ,oBAAC,QAAD;GAAM,WAAU;aAA8B;GAAY,CAAA,EACnE,oBAAC,cAAD,EAAgB,CAAA,CACZ;;AAIV,QACE,qBAAC,OAAD;EACE,WAAU;EACV,gBAAa;YAFf,CAIG,QAAQ,oBAAC,QAAD;GAAM,WAAU;aAA8B;GAAY,CAAA,EAClE,SACG;;;AAIV,SAAS,YAAY;AACnB,QACE,oBAAC,QAAD;EAAM,WAAU;EAAqC,eAAY;YAC/D,oBAAC,OAAD;GAAK,OAAM;GAAK,QAAO;GAAK,MAAK;GAAO,SAAQ;aAC9C,oBAAC,QAAD;IACE,QAAO;IACP,eAAc;IACd,gBAAe;IACf,aAAY;IACZ,GAAE;IACF,CAAA;GACE,CAAA;EACD,CAAA;;AAIX,SAAS,UAAU,EAAE,QAA0B;CAC7C,MAAM,CAAC,UAAU,eAAe,SAAS,MAAM;AAE/C,iBAAgB;AACd,MAAI,CAAC,SAAU;EAEf,MAAM,YAAY,iBAAiB,YAAY,MAAM,EAAE,IAAK;AAC5D,eAAa,aAAa,UAAU;IACnC,CAAC,SAAS,CAAC;CAEd,MAAM,qBAAqB,YAAY;AACrC,MAAI,CAAC,KAAM;AAEX,MAAI;AACF,SAAM,UAAU,UAAU,UAAU,KAAK;AACzC,eAAY,KAAK;WACV,KAAK;AACZ,WAAQ,MAAM,4BAA4B,IAAI;;;AAIlD,QACE,oBAAC,QAAD;EACE,SAAQ;EACR,OAAM;EACN,MAAK;EACL,WAAU;EACV,SAAS;EACT,OAAM;EACN,cAAW;YAEV,WACC,oBAAC,WAAD;GAAW,QAAO;GAAO,WAAU;GAAoB,CAAA,GAEvD,oBAAC,UAAD,EAAU,QAAO,WAAY,CAAA;EAExB,CAAA;;;;;;;;;;;;;;;AAqCb,SAAgB,WAAW,EACzB,UACA,OAAO,QACP,aACmB;AACnB,QACE,oBAAC,OAAD;EACE,WAAW,GAAG,oBAAoB,EAAE,MAAM,CAAC,EAAE,UAAU;EACvD,cAAW;EAEV;EACG,CAAA;;AAIV,WAAW,OAAO;AAClB,WAAW,UAAU;AACrB,WAAW,YAAY;AACvB,WAAW,YAAY"}
1
+ {"version":3,"file":"breadcrumbs-HiTmgaZ4.js","names":[],"sources":["../src/components/breadcrumbs/breadcrumbs.tsx"],"sourcesContent":["import { CheckIcon, CopyIcon } from \"@phosphor-icons/react\";\nimport { useEffect, useState, type PropsWithChildren } from \"react\";\n\nimport { Button } from \"../../components/button\";\nimport { SkeletonLine } from \"../../components/loader/skeleton-line\";\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\n\n/** Breadcrumbs size variant definitions. */\nexport const SF_BREADCRUMBS_VARIANTS = {\n size: {\n sm: {\n classes: \"text-sm h-10 gap-0.5\",\n description: \"Compact breadcrumbs for dense UIs\",\n },\n base: {\n classes: \"text-base h-12 gap-1\",\n description: \"Default breadcrumbs size\",\n },\n },\n} as const;\n\nexport const SF_BREADCRUMBS_DEFAULT_VARIANTS = {\n size: \"base\",\n} as const;\n\nexport type SFBreadcrumbsSize = keyof typeof SF_BREADCRUMBS_VARIANTS.size;\n\nexport interface SFBreadcrumbsVariantsProps {\n /**\n * Size of the breadcrumbs.\n * - `\"sm\"` — Compact breadcrumbs for dense UIs\n * - `\"base\"` — Default breadcrumbs size\n * @default \"base\"\n */\n size?: SFBreadcrumbsSize;\n}\n\nexport function breadcrumbsVariants({\n size = SF_BREADCRUMBS_DEFAULT_VARIANTS.size,\n}: SFBreadcrumbsVariantsProps = {}) {\n return cn(\n \"group mr-4 hidden min-w-0 grow items-center sm:flex\",\n SF_BREADCRUMBS_VARIANTS.size[size].classes\n );\n}\n\nexport interface BreadcrumbsItemProps {\n href: string;\n icon?: React.ReactNode;\n}\n\nconst Link = ({\n href,\n icon,\n children,\n}: PropsWithChildren<BreadcrumbsItemProps>) => {\n const LinkComponent = useLinkComponent();\n\n return (\n <LinkComponent\n to={href}\n className=\"flex min-w-0 items-center gap-1 text-sf-subtle no-underline\"\n >\n {!!icon && <span className=\"flex shrink-0 items-center\">{icon}</span>}\n {children}\n </LinkComponent>\n );\n};\n\ninterface BreadcrumbsCurrentProps {\n loading?: boolean;\n icon?: React.ReactNode;\n}\n\nfunction Current({\n children,\n icon,\n loading,\n}: PropsWithChildren<BreadcrumbsCurrentProps>) {\n if (loading) {\n return (\n <div className=\"flex w-[125px] min-w-0 items-center gap-1\">\n {icon && <span className=\"flex shrink-0 items-center\">{icon}</span>}\n <SkeletonLine />\n </div>\n );\n }\n\n return (\n <div\n className=\"flex items-center gap-1 truncate font-medium\"\n aria-current=\"page\"\n >\n {icon && <span className=\"flex shrink-0 items-center\">{icon}</span>}\n {children}\n </div>\n );\n}\n\nfunction Separator() {\n return (\n <span className=\"flex items-center text-sf-inactive\" aria-hidden=\"true\">\n <svg width=\"24\" height=\"24\" fill=\"none\" viewBox=\"0 0 24 24\">\n <path\n stroke=\"currentColor\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"1.5\"\n d=\"M10.75 8.75L14.25 12L10.75 15.25\"\n />\n </svg>\n </span>\n );\n}\n\nfunction Clipboard({ text }: { text: string }) {\n const [isCopied, setIsCopied] = useState(false);\n\n useEffect(() => {\n if (!isCopied) return;\n\n const timeoutId = setTimeout(() => setIsCopied(false), 2000);\n return () => clearTimeout(timeoutId);\n }, [isCopied]);\n\n const handleCopyDeeplink = async () => {\n if (!text) return;\n\n try {\n await navigator.clipboard.writeText(text);\n setIsCopied(true);\n } catch (err) {\n console.error(\"Failed to copy deeplink:\", err);\n }\n };\n\n return (\n <Button\n variant=\"ghost\"\n shape=\"square\"\n size=\"sm\"\n className=\"opacity-0 transition-[opacity] group-hover:opacity-100\"\n onClick={handleCopyDeeplink}\n title=\"Click to copy\"\n aria-label=\"Copy\"\n >\n {isCopied ? (\n <CheckIcon weight=\"bold\" className=\"text-sf-success\" />\n ) : (\n <CopyIcon weight=\"regular\" />\n )}\n </Button>\n );\n}\n\n/**\n * Breadcrumbs component props.\n *\n * @example\n * ```tsx\n * <Breadcrumbs>\n * <Breadcrumbs.Link href=\"/\">Home</Breadcrumbs.Link>\n * <Breadcrumbs.Separator />\n * <Breadcrumbs.Link href=\"/docs\">Docs</Breadcrumbs.Link>\n * <Breadcrumbs.Separator />\n * <Breadcrumbs.Current>Current Page</Breadcrumbs.Current>\n * </Breadcrumbs>\n * ```\n */\nexport interface BreadcrumbsProps\n extends PropsWithChildren, SFBreadcrumbsVariantsProps {\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n}\n\n/**\n * Navigation breadcrumb trail showing the current page's location in a hierarchy.\n * Compound component with `Breadcrumbs.Link`, `Breadcrumbs.Current`, `Breadcrumbs.Separator`, and `Breadcrumbs.Clipboard`.\n *\n * @example\n * ```tsx\n * <Breadcrumbs>\n * <Breadcrumbs.Link href=\"/\">Home</Breadcrumbs.Link>\n * <Breadcrumbs.Separator />\n * <Breadcrumbs.Current>Dashboard</Breadcrumbs.Current>\n * </Breadcrumbs>\n * ```\n */\nexport function Breadcrumb({\n children,\n size = \"base\",\n className,\n}: BreadcrumbsProps) {\n return (\n <nav\n className={cn(breadcrumbsVariants({ size }), className)}\n aria-label=\"breadcrumb\"\n >\n {children}\n </nav>\n );\n}\n\nBreadcrumb.Link = Link;\nBreadcrumb.Current = Current;\nBreadcrumb.Separator = Separator;\nBreadcrumb.Clipboard = Clipboard;\n"],"mappings":";;;;;;;;;;AASA,IAAa,0BAA0B,EACrC,MAAM;CACJ,IAAI;EACF,SAAS;EACT,aAAa;CACf;CACA,MAAM;EACJ,SAAS;EACT,aAAa;CACf;AACF,EACF;AAEA,IAAa,kCAAkC,EAC7C,MAAM,OACR;AAcA,SAAgB,oBAAoB,EAClC,OAAO,gCAAgC,SACT,CAAC,GAAG;CAClC,OAAO,GACL,uDACA,wBAAwB,KAAK,MAAM,OACrC;AACF;AAOA,IAAM,QAAQ,EACZ,MACA,MACA,eAC6C;CAG7C,OACE,qBAHoB,iBAGnB,GAAD;EACE,IAAI;EACJ,WAAU;YAFZ,CAIG,CAAC,CAAC,QAAQ,oBAAC,QAAD;GAAM,WAAU;aAA8B;EAAW,CAAA,GACnE,QACY;;AAEnB;AAOA,SAAS,QAAQ,EACf,UACA,MACA,WAC6C;CAC7C,IAAI,SACF,OACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACG,QAAQ,oBAAC,QAAD;GAAM,WAAU;aAA8B;EAAW,CAAA,GAClE,oBAAC,cAAD,CAAe,CAAA,CACZ;;CAIT,OACE,qBAAC,OAAD;EACE,WAAU;EACV,gBAAa;YAFf,CAIG,QAAQ,oBAAC,QAAD;GAAM,WAAU;aAA8B;EAAW,CAAA,GACjE,QACE;;AAET;AAEA,SAAS,YAAY;CACnB,OACE,oBAAC,QAAD;EAAM,WAAU;EAAqC,eAAY;YAC/D,oBAAC,OAAD;GAAK,OAAM;GAAK,QAAO;GAAK,MAAK;GAAO,SAAQ;aAC9C,oBAAC,QAAD;IACE,QAAO;IACP,eAAc;IACd,gBAAe;IACf,aAAY;IACZ,GAAE;GACH,CAAA;EACE,CAAA;CACD,CAAA;AAEV;AAEA,SAAS,UAAU,EAAE,QAA0B;CAC7C,MAAM,CAAC,UAAU,eAAe,SAAS,KAAK;CAE9C,gBAAgB;EACd,IAAI,CAAC,UAAU;EAEf,MAAM,YAAY,iBAAiB,YAAY,KAAK,GAAG,GAAI;EAC3D,aAAa,aAAa,SAAS;CACrC,GAAG,CAAC,QAAQ,CAAC;CAEb,MAAM,qBAAqB,YAAY;EACrC,IAAI,CAAC,MAAM;EAEX,IAAI;GACF,MAAM,UAAU,UAAU,UAAU,IAAI;GACxC,YAAY,IAAI;EAClB,SAAS,KAAK;GACZ,QAAQ,MAAM,4BAA4B,GAAG;EAC/C;CACF;CAEA,OACE,oBAAC,QAAD;EACE,SAAQ;EACR,OAAM;EACN,MAAK;EACL,WAAU;EACV,SAAS;EACT,OAAM;EACN,cAAW;YAEV,WACC,oBAAC,WAAD;GAAW,QAAO;GAAO,WAAU;EAAmB,CAAA,IAEtD,oBAAC,UAAD,EAAU,QAAO,UAAW,CAAA;CAExB,CAAA;AAEZ;;;;;;;;;;;;;;AAmCA,SAAgB,WAAW,EACzB,UACA,OAAO,QACP,aACmB;CACnB,OACE,oBAAC,OAAD;EACE,WAAW,GAAG,oBAAoB,EAAE,KAAK,CAAC,GAAG,SAAS;EACtD,cAAW;EAEV;CACE,CAAA;AAET;AAEA,WAAW,OAAO;AAClB,WAAW,UAAU;AACrB,WAAW,YAAY;AACvB,WAAW,YAAY"}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
- import { t as cn } from "./cn-YROP2_ox.js";
3
- import { n as useLinkComponent } from "./link-provider-BUZKXaNE.js";
4
- import { t as Loader } from "./loader-DAcc-Uag.js";
2
+ import { t as cn } from "./cn-CmAOpn49.js";
3
+ import { n as useLinkComponent } from "./link-provider-BSn8YJon.js";
4
+ import { t as Loader } from "./loader-BEMz8pJO.js";
5
5
  import React from "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import { ArrowsClockwise } from "@phosphor-icons/react";
@@ -167,4 +167,4 @@ LinkButton.displayName = "LinkButton";
167
167
  //#endregion
168
168
  export { buttonVariants as i, LinkButton as n, RefreshButton as r, Button as t };
169
169
 
170
- //# sourceMappingURL=button-CO6-qPax.js.map
170
+ //# sourceMappingURL=button-BHOgXJRU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"button-CO6-qPax.js","names":[],"sources":["../src/components/button/button.tsx"],"sourcesContent":["import { ArrowsClockwise, type Icon } from \"@phosphor-icons/react\";\nimport React from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\nimport { Loader } from \"../loader/loader\";\n\n/** Button variant definitions mapping shape, size, and variant names to their Tailwind classes. */\nexport const SF_BUTTON_VARIANTS = {\n shape: {\n base: {\n classes: \"\",\n description: \"Default rectangular button shape\",\n },\n square: {\n classes: \"items-center justify-center p-0\",\n description: \"Square button for icon-only actions\",\n },\n circle: {\n classes: \"items-center justify-center p-0 rounded-full\",\n description: \"Circular button for icon-only actions\",\n },\n },\n size: {\n xs: {\n classes: \"h-5 gap-1 rounded-sm px-1.5 text-xs\",\n description: \"Extra small button for compact UIs\",\n },\n sm: {\n classes: \"h-6.5 gap-1 rounded-md px-2 text-xs\",\n description: \"Small button for secondary actions\",\n },\n base: {\n classes: \"h-9 gap-1.5 rounded-lg px-3 text-base\",\n description: \"Default button size\",\n },\n lg: {\n classes: \"h-10 gap-2 rounded-lg px-4 text-base\",\n description: \"Large button for primary CTAs\",\n },\n },\n compactSize: {\n xs: { classes: \"size-3.5\" },\n sm: { classes: \"size-6.5\" },\n base: { classes: \"size-9\" },\n lg: { classes: \"size-10\" },\n },\n variant: {\n primary: {\n classes:\n \"bg-sf-brand !text-white hover:bg-sf-brand-hover focus:bg-sf-brand-hover disabled:bg-sf-brand/50\",\n description: \"High-emphasis button for primary actions\",\n },\n secondary: {\n classes:\n \"bg-sf-control !text-sf-default ring not-disabled:hover:border-secondary! not-disabled:hover:bg-sf-control disabled:bg-sf-control/50 disabled:!text-sf-default/70 ring-sf-line data-[state=open]:bg-sf-control\",\n description: \"Default button style for most actions\",\n },\n ghost: {\n classes: \"text-sf-default hover:bg-sf-tint shadow-none bg-inherit\",\n description: \"Minimal button with no background\",\n },\n destructive: {\n classes: \"bg-sf-danger !text-white hover:bg-sf-danger/70\",\n description: \"Danger button for destructive actions like delete\",\n },\n \"secondary-destructive\": {\n classes:\n \"bg-sf-control !text-sf-danger ring not-disabled:hover:border-secondary! not-disabled:hover:bg-sf-control disabled:bg-sf-control/50 disabled:!text-sf-danger/70 ring-sf-line data-[state=open]:bg-sf-control\",\n description:\n \"Secondary button with destructive text for less prominent dangerous actions\",\n },\n outline: {\n classes: \"bg-sf-base text-sf-default ring ring-sf-line\",\n description: \"Bordered button with transparent background\",\n },\n },\n} as const;\n\nexport const SF_BUTTON_DEFAULT_VARIANTS = {\n shape: \"base\",\n size: \"base\",\n variant: \"secondary\",\n} as const;\n\n// Derived types from SF_BUTTON_VARIANTS\nexport type SFButtonShape = keyof typeof SF_BUTTON_VARIANTS.shape;\nexport type SFButtonSize = keyof typeof SF_BUTTON_VARIANTS.size;\nexport type SFButtonVariant = keyof typeof SF_BUTTON_VARIANTS.variant;\n\nexport interface SFButtonVariantsProps {\n /**\n * Button shape.\n * - `\"base\"` — Default rectangular button\n * - `\"square\"` — Square button for icon-only actions\n * - `\"circle\"` — Circular button for icon-only actions\n * @default \"base\"\n */\n shape?: SFButtonShape;\n /**\n * Button size.\n * - `\"xs\"` — Extra small for compact UIs\n * - `\"sm\"` — Small for secondary actions\n * - `\"base\"` — Default size\n * - `\"lg\"` — Large for primary CTAs\n * @default \"base\"\n */\n size?: SFButtonSize;\n /**\n * Visual style of the button.\n * - `\"primary\"` — High-emphasis, brand-colored for primary actions\n * - `\"secondary\"` — Default style with border for most actions\n * - `\"ghost\"` — Minimal, no background for tertiary actions\n * - `\"destructive\"` — Danger button for destructive actions\n * - `\"secondary-destructive\"` — Secondary style with destructive text\n * - `\"outline\"` — Bordered with transparent background\n * @default \"secondary\"\n */\n variant?: SFButtonVariant;\n}\n\nexport function buttonVariants({\n variant = SF_BUTTON_DEFAULT_VARIANTS.variant,\n size = SF_BUTTON_DEFAULT_VARIANTS.size,\n shape = SF_BUTTON_DEFAULT_VARIANTS.shape,\n}: SFButtonVariantsProps = {}) {\n const isCompactShape = shape === \"square\" || shape === \"circle\";\n\n return cn(\n // Base styles\n \"group flex w-max shrink-0 items-center font-medium select-none\",\n \"border-0 shadow-xs\",\n \"cursor-pointer\",\n // Disabled state\n \"disabled:cursor-not-allowed disabled:text-sf-subtle\",\n // Apply variant, size, shape styles from SF_BUTTON_VARIANTS\n SF_BUTTON_VARIANTS.variant[variant].classes,\n SF_BUTTON_VARIANTS.size[size].classes,\n SF_BUTTON_VARIANTS.shape[shape].classes,\n isCompactShape && SF_BUTTON_VARIANTS.compactSize[size].classes\n );\n}\n\n// Normalize icon prop to support both React elements and component types\nconst renderIconNode = (IconComponent?: Icon | React.ReactNode) => {\n if (!IconComponent) return null;\n if (React.isValidElement(IconComponent)) return IconComponent;\n const Comp = IconComponent as React.ComponentType<Record<string, unknown>>;\n return <Comp />;\n};\n\n/**\n * Button component props.\n *\n * Uses a discriminated union on `shape` so that icon-only buttons\n * (`shape=\"square\"` or `shape=\"circle\"`) require an `aria-label`.\n *\n * @example\n * ```tsx\n * <Button variant=\"primary\">Save</Button>\n * <Button variant=\"secondary\" shape=\"square\" icon={PlusIcon} aria-label=\"Add\" />\n * <Button variant=\"destructive\" loading>Deleting...</Button>\n * ```\n */\ntype ButtonBaseProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Content rendered inside the button. */\n children?: React.ReactNode;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Icon from `@phosphor-icons/react` or a React element. Rendered before children. */\n icon?: Icon | React.ReactNode;\n /** Shows a loading spinner and disables interaction. */\n loading?: boolean;\n};\n\ntype ButtonWithTextProps = ButtonBaseProps & {\n shape?: \"base\";\n size?: SFButtonSize;\n variant?: SFButtonVariant;\n};\n\ntype IconOnlyButtonProps = ButtonBaseProps & {\n shape: \"square\" | \"circle\";\n size?: SFButtonSize;\n variant?: SFButtonVariant;\n /** Required for icon-only buttons to provide accessible label for screen readers */\n \"aria-label\": string;\n};\n\nexport type ButtonProps = ButtonWithTextProps | IconOnlyButtonProps;\n\n/**\n * LinkButton component props — renders an anchor styled as a button.\n *\n * @example\n * ```tsx\n * <LinkButton href=\"/docs\" variant=\"ghost\" icon={BookIcon}>Docs</LinkButton>\n * <LinkButton href=\"https://example.com\" external>Visit Site</LinkButton>\n * ```\n */\nexport type LinkButtonProps = React.AnchorHTMLAttributes<HTMLAnchorElement> &\n SFButtonVariantsProps & {\n /** Content rendered inside the link button. */\n children?: React.ReactNode;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Icon from `@phosphor-icons/react` or a React element. Rendered before children. */\n icon?: Icon | React.ReactNode;\n /** When `true`, opens in a new tab with `rel=\"noopener noreferrer\"`. */\n external?: boolean;\n linksExternal?: boolean;\n };\n\n/**\n * Primary action trigger. Supports multiple variants, sizes, shapes, icons, and loading state.\n *\n * @example\n * ```tsx\n * <Button variant=\"primary\">Save</Button>\n * <Button variant=\"secondary\" icon={PlusIcon}>Create Worker</Button>\n * ```\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n className,\n disabled,\n loading,\n shape = \"base\",\n size = \"base\",\n variant = \"secondary\",\n icon: IconComponent,\n ...props\n },\n ref\n ) => {\n const { type, ...restProps } = props;\n return (\n <button\n ref={ref}\n className={cn(\n buttonVariants({ variant, size, shape }),\n \"outline-none focus:opacity-100 focus-visible:ring-1 focus-visible:ring-sf-ring *:in-focus:opacity-100\", // Focus styles\n disabled && \"cursor-not-allowed opacity-50\",\n className\n )}\n disabled={loading || disabled}\n type={type ?? \"button\"}\n {...restProps}\n >\n {loading && <Loader size={size === \"lg\" ? 16 : 14} />}\n {!loading && renderIconNode(IconComponent)}\n\n {children}\n </button>\n );\n }\n);\n\nButton.displayName = \"Button\";\n\n/**\n * Square button with a rotating arrows icon, used to trigger data refresh actions.\n *\n * @example\n * ```tsx\n * <RefreshButton loading={isRefreshing} onClick={refresh} />\n * ```\n */\nexport const RefreshButton = ({\n \"aria-label\": ariaLabel = \"Refresh\",\n loading,\n ...props\n}: ButtonProps) => (\n <Button shape=\"square\" aria-label={ariaLabel} {...props}>\n <ArrowsClockwise\n className={cn({\n \"animate-refresh\": loading,\n \"size-4.5\": props.size === \"base\" || !props.size,\n \"size-4\": props.size === \"sm\",\n \"size-5\": props.size === \"lg\",\n })}\n />\n </Button>\n);\n\n/**\n * Anchor element styled as a button. Integrates with `LinkProvider` for framework routing.\n *\n * @example\n * ```tsx\n * <LinkButton href=\"/settings\" variant=\"ghost\">Settings</LinkButton>\n * ```\n */\nexport const LinkButton = React.forwardRef<HTMLAnchorElement, LinkButtonProps>(\n (\n {\n children,\n className,\n external,\n href,\n shape = \"base\",\n size = \"base\",\n variant = \"ghost\",\n icon: IconComponent,\n // linksExternal = false,\n ...props\n },\n ref\n ) => {\n const LinkComponent = useLinkComponent();\n const externalProps = external\n ? { target: \"_blank\", rel: \"noopener noreferrer\" }\n : {};\n\n return (\n <LinkComponent\n ref={ref}\n className={cn(\n buttonVariants({ variant, size, shape }),\n \"flex items-center no-underline!\",\n className\n )}\n href={href}\n to={typeof href === \"string\" ? href : undefined}\n {...externalProps}\n {...props}\n >\n {renderIconNode(IconComponent)}\n {children}\n </LinkComponent>\n );\n }\n);\n\nLinkButton.displayName = \"LinkButton\";\n"],"mappings":"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"}
1
+ {"version":3,"file":"button-BHOgXJRU.js","names":[],"sources":["../src/components/button/button.tsx"],"sourcesContent":["import { ArrowsClockwise, type Icon } from \"@phosphor-icons/react\";\nimport React from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { useLinkComponent } from \"../../utils/link-provider\";\nimport { Loader } from \"../loader/loader\";\n\n/** Button variant definitions mapping shape, size, and variant names to their Tailwind classes. */\nexport const SF_BUTTON_VARIANTS = {\n shape: {\n base: {\n classes: \"\",\n description: \"Default rectangular button shape\",\n },\n square: {\n classes: \"items-center justify-center p-0\",\n description: \"Square button for icon-only actions\",\n },\n circle: {\n classes: \"items-center justify-center p-0 rounded-full\",\n description: \"Circular button for icon-only actions\",\n },\n },\n size: {\n xs: {\n classes: \"h-5 gap-1 rounded-sm px-1.5 text-xs\",\n description: \"Extra small button for compact UIs\",\n },\n sm: {\n classes: \"h-6.5 gap-1 rounded-md px-2 text-xs\",\n description: \"Small button for secondary actions\",\n },\n base: {\n classes: \"h-9 gap-1.5 rounded-lg px-3 text-base\",\n description: \"Default button size\",\n },\n lg: {\n classes: \"h-10 gap-2 rounded-lg px-4 text-base\",\n description: \"Large button for primary CTAs\",\n },\n },\n compactSize: {\n xs: { classes: \"size-3.5\" },\n sm: { classes: \"size-6.5\" },\n base: { classes: \"size-9\" },\n lg: { classes: \"size-10\" },\n },\n variant: {\n primary: {\n classes:\n \"bg-sf-brand !text-white hover:bg-sf-brand-hover focus:bg-sf-brand-hover disabled:bg-sf-brand/50\",\n description: \"High-emphasis button for primary actions\",\n },\n secondary: {\n classes:\n \"bg-sf-control !text-sf-default ring not-disabled:hover:border-secondary! not-disabled:hover:bg-sf-control disabled:bg-sf-control/50 disabled:!text-sf-default/70 ring-sf-line data-[state=open]:bg-sf-control\",\n description: \"Default button style for most actions\",\n },\n ghost: {\n classes: \"text-sf-default hover:bg-sf-tint shadow-none bg-inherit\",\n description: \"Minimal button with no background\",\n },\n destructive: {\n classes: \"bg-sf-danger !text-white hover:bg-sf-danger/70\",\n description: \"Danger button for destructive actions like delete\",\n },\n \"secondary-destructive\": {\n classes:\n \"bg-sf-control !text-sf-danger ring not-disabled:hover:border-secondary! not-disabled:hover:bg-sf-control disabled:bg-sf-control/50 disabled:!text-sf-danger/70 ring-sf-line data-[state=open]:bg-sf-control\",\n description:\n \"Secondary button with destructive text for less prominent dangerous actions\",\n },\n outline: {\n classes: \"bg-sf-base text-sf-default ring ring-sf-line\",\n description: \"Bordered button with transparent background\",\n },\n },\n} as const;\n\nexport const SF_BUTTON_DEFAULT_VARIANTS = {\n shape: \"base\",\n size: \"base\",\n variant: \"secondary\",\n} as const;\n\n// Derived types from SF_BUTTON_VARIANTS\nexport type SFButtonShape = keyof typeof SF_BUTTON_VARIANTS.shape;\nexport type SFButtonSize = keyof typeof SF_BUTTON_VARIANTS.size;\nexport type SFButtonVariant = keyof typeof SF_BUTTON_VARIANTS.variant;\n\nexport interface SFButtonVariantsProps {\n /**\n * Button shape.\n * - `\"base\"` — Default rectangular button\n * - `\"square\"` — Square button for icon-only actions\n * - `\"circle\"` — Circular button for icon-only actions\n * @default \"base\"\n */\n shape?: SFButtonShape;\n /**\n * Button size.\n * - `\"xs\"` — Extra small for compact UIs\n * - `\"sm\"` — Small for secondary actions\n * - `\"base\"` — Default size\n * - `\"lg\"` — Large for primary CTAs\n * @default \"base\"\n */\n size?: SFButtonSize;\n /**\n * Visual style of the button.\n * - `\"primary\"` — High-emphasis, brand-colored for primary actions\n * - `\"secondary\"` — Default style with border for most actions\n * - `\"ghost\"` — Minimal, no background for tertiary actions\n * - `\"destructive\"` — Danger button for destructive actions\n * - `\"secondary-destructive\"` — Secondary style with destructive text\n * - `\"outline\"` — Bordered with transparent background\n * @default \"secondary\"\n */\n variant?: SFButtonVariant;\n}\n\nexport function buttonVariants({\n variant = SF_BUTTON_DEFAULT_VARIANTS.variant,\n size = SF_BUTTON_DEFAULT_VARIANTS.size,\n shape = SF_BUTTON_DEFAULT_VARIANTS.shape,\n}: SFButtonVariantsProps = {}) {\n const isCompactShape = shape === \"square\" || shape === \"circle\";\n\n return cn(\n // Base styles\n \"group flex w-max shrink-0 items-center font-medium select-none\",\n \"border-0 shadow-xs\",\n \"cursor-pointer\",\n // Disabled state\n \"disabled:cursor-not-allowed disabled:text-sf-subtle\",\n // Apply variant, size, shape styles from SF_BUTTON_VARIANTS\n SF_BUTTON_VARIANTS.variant[variant].classes,\n SF_BUTTON_VARIANTS.size[size].classes,\n SF_BUTTON_VARIANTS.shape[shape].classes,\n isCompactShape && SF_BUTTON_VARIANTS.compactSize[size].classes\n );\n}\n\n// Normalize icon prop to support both React elements and component types\nconst renderIconNode = (IconComponent?: Icon | React.ReactNode) => {\n if (!IconComponent) return null;\n if (React.isValidElement(IconComponent)) return IconComponent;\n const Comp = IconComponent as React.ComponentType<Record<string, unknown>>;\n return <Comp />;\n};\n\n/**\n * Button component props.\n *\n * Uses a discriminated union on `shape` so that icon-only buttons\n * (`shape=\"square\"` or `shape=\"circle\"`) require an `aria-label`.\n *\n * @example\n * ```tsx\n * <Button variant=\"primary\">Save</Button>\n * <Button variant=\"secondary\" shape=\"square\" icon={PlusIcon} aria-label=\"Add\" />\n * <Button variant=\"destructive\" loading>Deleting...</Button>\n * ```\n */\ntype ButtonBaseProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Content rendered inside the button. */\n children?: React.ReactNode;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Icon from `@phosphor-icons/react` or a React element. Rendered before children. */\n icon?: Icon | React.ReactNode;\n /** Shows a loading spinner and disables interaction. */\n loading?: boolean;\n};\n\ntype ButtonWithTextProps = ButtonBaseProps & {\n shape?: \"base\";\n size?: SFButtonSize;\n variant?: SFButtonVariant;\n};\n\ntype IconOnlyButtonProps = ButtonBaseProps & {\n shape: \"square\" | \"circle\";\n size?: SFButtonSize;\n variant?: SFButtonVariant;\n /** Required for icon-only buttons to provide accessible label for screen readers */\n \"aria-label\": string;\n};\n\nexport type ButtonProps = ButtonWithTextProps | IconOnlyButtonProps;\n\n/**\n * LinkButton component props — renders an anchor styled as a button.\n *\n * @example\n * ```tsx\n * <LinkButton href=\"/docs\" variant=\"ghost\" icon={BookIcon}>Docs</LinkButton>\n * <LinkButton href=\"https://example.com\" external>Visit Site</LinkButton>\n * ```\n */\nexport type LinkButtonProps = React.AnchorHTMLAttributes<HTMLAnchorElement> &\n SFButtonVariantsProps & {\n /** Content rendered inside the link button. */\n children?: React.ReactNode;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Icon from `@phosphor-icons/react` or a React element. Rendered before children. */\n icon?: Icon | React.ReactNode;\n /** When `true`, opens in a new tab with `rel=\"noopener noreferrer\"`. */\n external?: boolean;\n linksExternal?: boolean;\n };\n\n/**\n * Primary action trigger. Supports multiple variants, sizes, shapes, icons, and loading state.\n *\n * @example\n * ```tsx\n * <Button variant=\"primary\">Save</Button>\n * <Button variant=\"secondary\" icon={PlusIcon}>Create Worker</Button>\n * ```\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n children,\n className,\n disabled,\n loading,\n shape = \"base\",\n size = \"base\",\n variant = \"secondary\",\n icon: IconComponent,\n ...props\n },\n ref\n ) => {\n const { type, ...restProps } = props;\n return (\n <button\n ref={ref}\n className={cn(\n buttonVariants({ variant, size, shape }),\n \"outline-none focus:opacity-100 focus-visible:ring-1 focus-visible:ring-sf-ring *:in-focus:opacity-100\", // Focus styles\n disabled && \"cursor-not-allowed opacity-50\",\n className\n )}\n disabled={loading || disabled}\n type={type ?? \"button\"}\n {...restProps}\n >\n {loading && <Loader size={size === \"lg\" ? 16 : 14} />}\n {!loading && renderIconNode(IconComponent)}\n\n {children}\n </button>\n );\n }\n);\n\nButton.displayName = \"Button\";\n\n/**\n * Square button with a rotating arrows icon, used to trigger data refresh actions.\n *\n * @example\n * ```tsx\n * <RefreshButton loading={isRefreshing} onClick={refresh} />\n * ```\n */\nexport const RefreshButton = ({\n \"aria-label\": ariaLabel = \"Refresh\",\n loading,\n ...props\n}: ButtonProps) => (\n <Button shape=\"square\" aria-label={ariaLabel} {...props}>\n <ArrowsClockwise\n className={cn({\n \"animate-refresh\": loading,\n \"size-4.5\": props.size === \"base\" || !props.size,\n \"size-4\": props.size === \"sm\",\n \"size-5\": props.size === \"lg\",\n })}\n />\n </Button>\n);\n\n/**\n * Anchor element styled as a button. Integrates with `LinkProvider` for framework routing.\n *\n * @example\n * ```tsx\n * <LinkButton href=\"/settings\" variant=\"ghost\">Settings</LinkButton>\n * ```\n */\nexport const LinkButton = React.forwardRef<HTMLAnchorElement, LinkButtonProps>(\n (\n {\n children,\n className,\n external,\n href,\n shape = \"base\",\n size = \"base\",\n variant = \"ghost\",\n icon: IconComponent,\n // linksExternal = false,\n ...props\n },\n ref\n ) => {\n const LinkComponent = useLinkComponent();\n const externalProps = external\n ? { target: \"_blank\", rel: \"noopener noreferrer\" }\n : {};\n\n return (\n <LinkComponent\n ref={ref}\n className={cn(\n buttonVariants({ variant, size, shape }),\n \"flex items-center no-underline!\",\n className\n )}\n href={href}\n to={typeof href === \"string\" ? href : undefined}\n {...externalProps}\n {...props}\n >\n {renderIconNode(IconComponent)}\n {children}\n </LinkComponent>\n );\n }\n);\n\nLinkButton.displayName = \"LinkButton\";\n"],"mappings":"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"}
package/dist/catalog.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { C as resolveDynamicValue, S as getByPath, T as sfComponents, _ as defineCatalog, a as ValidationProvider, b as validateSpec, c as defineRegistry, d as useJsonRenderMessage, f as useUIStream, g as deepMergeSpec, h as buildUserPrompt, i as StateProvider, l as useBoundProp, m as autoFixSpec, n as JSONUIProvider, o as VisibilityProvider, p as schema, r as Renderer, s as createRenderer, t as ActionProvider, u as useChatUI, v as diffToPatches, w as setByPath, x as createStateStore, y as evaluateVisibility } from "./dist-B6iWiWwp.js";
2
+ import { C as resolveDynamicValue, S as getByPath, T as sfComponents, _ as defineCatalog, a as ValidationProvider, b as validateSpec, c as defineRegistry, d as useJsonRenderMessage, f as useUIStream, g as deepMergeSpec, h as buildUserPrompt, i as StateProvider, l as useBoundProp, m as autoFixSpec, n as JSONUIProvider, o as VisibilityProvider, p as schema, r as Renderer, s as createRenderer, t as ActionProvider, u as useChatUI, v as diffToPatches, w as setByPath, x as createStateStore, y as evaluateVisibility } from "./dist-6AtBsaJE.js";
3
3
  import { z } from "zod";
4
4
  //#region src/catalog/sf-components.ts
5
5
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.js","names":[],"sources":["../src/catalog/sf-components.ts"],"sourcesContent":["/**\n * Curated SignalFlare component definitions for json-render catalogs.\n *\n * These definitions expose an LLM-friendly API surface:\n * - Simple string/enum/boolean props (no className, callbacks, refs)\n * - `text` / `label` props for display text (mapped to `children` in renderers)\n * - Descriptions and examples that guide the LLM\n *\n * The renderers in `sf-registry.ts` bridge these LLM-friendly props\n * to the actual SignalFlare component APIs.\n */\n\nimport { z } from \"zod\";\n\nexport const sfComponentDefinitions: Record<\n string,\n {\n props: z.ZodTypeAny;\n slots?: string[];\n description: string;\n example?: Record<string, unknown>;\n }\n> = {\n // ── Layout ────────────────────────────────────────────────────────────\n\n Stack: {\n props: z.object({\n direction: z.enum([\"horizontal\", \"vertical\"]).optional(),\n gap: z.enum([\"sm\", \"base\", \"lg\"]).optional(),\n align: z.enum([\"start\", \"center\", \"end\", \"stretch\"]).optional(),\n wrap: z.boolean().optional(),\n }),\n slots: [\"default\"],\n description:\n \"Flex layout container. Use as the primary way to arrange child components vertically or horizontally with consistent spacing. Default: vertical, base gap.\",\n example: { direction: \"vertical\", gap: \"base\" },\n },\n\n Surface: {\n props: z.object({\n padding: z.enum([\"sm\", \"base\", \"lg\"]).optional(),\n border: z.boolean().optional(),\n }),\n slots: [\"default\"],\n description:\n \"Visual container with background, shadow, and ring. Use for cards, panels, and sections. For layout/spacing, use Stack instead.\",\n example: { padding: \"base\", border: true },\n },\n\n Grid: {\n props: z.object({\n variant: z\n .enum([\"2up\", \"side-by-side\", \"2-1\", \"1-2\", \"3up\", \"4up\", \"6up\"])\n .optional(),\n gap: z.enum([\"none\", \"sm\", \"base\", \"lg\"]).optional(),\n }),\n slots: [\"default\"],\n description:\n \"Responsive CSS grid layout. Place child components inside as grid items.\",\n example: { variant: \"3up\", gap: \"base\" },\n },\n\n LayerCard: {\n props: z.object({}),\n slots: [\"default\"],\n description:\n \"Elevated card container with border and shadow. Wrap content inside it.\",\n },\n\n // ── Typography ────────────────────────────────────────────────────────\n\n Text: {\n props: z.object({\n text: z.string(),\n variant: z\n .enum([\n \"heading1\",\n \"heading2\",\n \"heading3\",\n \"body\",\n \"secondary\",\n \"success\",\n \"error\",\n \"mono\",\n ])\n .optional(),\n size: z.enum([\"xs\", \"sm\", \"base\", \"lg\"]).optional(),\n bold: z.boolean().optional(),\n }),\n description:\n \"Text content — headings, body copy, labels. Use variant='heading1' for page titles, 'heading2' for sections, 'body' for paragraphs.\",\n example: { text: \"Dashboard Overview\", variant: \"heading1\" },\n },\n\n Code: {\n props: z.object({\n code: z.string(),\n lang: z.enum([\"ts\", \"tsx\", \"jsonc\", \"bash\", \"css\"]).optional(),\n }),\n description: \"Code display with syntax highlighting.\",\n example: { code: \"const x = 42;\", lang: \"ts\" },\n },\n\n // ── Actions ───────────────────────────────────────────────────────────\n\n Button: {\n props: z.object({\n label: z.string(),\n variant: z\n .enum([\"primary\", \"secondary\", \"ghost\", \"destructive\", \"outline\"])\n .optional(),\n size: z.enum([\"xs\", \"sm\", \"base\", \"lg\"]).optional(),\n disabled: z.boolean().optional(),\n loading: z.boolean().optional(),\n }),\n description: \"Clickable action button.\",\n example: { label: \"Save changes\", variant: \"primary\" },\n },\n\n Link: {\n props: z.object({\n text: z.string(),\n href: z.string(),\n variant: z.enum([\"inline\", \"plain\"]).optional(),\n }),\n description: \"Navigation link.\",\n example: { text: \"View details\", href: \"/details\" },\n },\n\n // ── Data Display ──────────────────────────────────────────────────────\n\n Badge: {\n props: z.object({\n text: z.string(),\n variant: z\n .enum([\"primary\", \"secondary\", \"destructive\", \"outline\", \"beta\"])\n .optional(),\n }),\n description: \"Small status label or tag.\",\n example: { text: \"Active\", variant: \"primary\" },\n },\n\n Banner: {\n props: z.object({\n variant: z.enum([\"default\", \"alert\", \"error\"]).optional(),\n title: z.string(),\n description: z.string().optional(),\n }),\n description: \"Full-width alert message for notices, warnings, or errors.\",\n example: {\n variant: \"alert\",\n title: \"Warning\",\n description: \"Your trial expires in 3 days.\",\n },\n },\n\n Meter: {\n props: z.object({\n label: z.string(),\n value: z.number(),\n max: z.number().optional(),\n showValue: z.boolean().optional(),\n }),\n description: \"Progress bar showing a value (defaults 0–100).\",\n example: { label: \"Storage used\", value: 72, max: 100 },\n },\n\n Empty: {\n props: z.object({\n title: z.string(),\n description: z.string().optional(),\n size: z.enum([\"sm\", \"base\", \"lg\"]).optional(),\n }),\n description: \"Placeholder for empty lists, tables, or sections.\",\n example: {\n title: \"No results\",\n description: \"Try adjusting your filters.\",\n },\n },\n\n Loader: {\n props: z.object({\n size: z.enum([\"sm\", \"base\", \"lg\"]).optional(),\n }),\n description: \"Animated loading spinner.\",\n },\n\n Table: {\n props: z.object({\n data: z.array(z.record(z.string(), z.unknown())),\n columns: z.array(z.object({ key: z.string(), label: z.string() })),\n }),\n description:\n \"Data table. Provide `data` (array of row objects) and `columns` (key + label pairs). The renderer builds header and body automatically.\",\n example: {\n columns: [\n { key: \"name\", label: \"Name\" },\n { key: \"email\", label: \"Email\" },\n ],\n data: [{ name: \"Alice\", email: \"alice@example.com\" }],\n },\n },\n\n // ── Charts ──────────────────────────────────────────────────────────\n\n BarChart: {\n props: z.object({\n title: z.string().optional(),\n data: z.array(z.record(z.string(), z.unknown())),\n xKey: z.string(),\n yKey: z.string(),\n aggregate: z.enum([\"sum\", \"count\", \"avg\"]).optional(),\n color: z.string().optional(),\n height: z.number().optional(),\n }),\n description:\n \"Bar chart visualization. Use { $state: \\\"/path\\\" } on data to bind to an array of objects. xKey is the category/group field, yKey is the numeric value field. Use aggregate='count' to count items grouped by xKey.\",\n example: {\n data: { $state: \"/sales\" } as any,\n xKey: \"month\",\n yKey: \"revenue\",\n },\n },\n\n LineChart: {\n props: z.object({\n title: z.string().optional(),\n data: z.array(z.record(z.string(), z.unknown())),\n xKey: z.string(),\n yKey: z.string(),\n aggregate: z.enum([\"sum\", \"count\", \"avg\"]).optional(),\n color: z.string().optional(),\n height: z.number().optional(),\n }),\n description:\n 'Line chart visualization. Use { $state: \"/path\" } on data to bind to an array of objects. xKey is the x-axis field, yKey is the numeric value field.',\n example: {\n data: { $state: \"/metrics\" } as any,\n xKey: \"date\",\n yKey: \"value\",\n },\n },\n\n PieChart: {\n props: z.object({\n title: z.string().optional(),\n data: z.array(z.record(z.string(), z.unknown())),\n nameKey: z.string(),\n valueKey: z.string(),\n height: z.number().optional(),\n }),\n description:\n 'Pie/donut chart. nameKey is the label field, valueKey is the numeric field. Use { $state: \"/path\" } on data.',\n example: {\n data: { $state: \"/categories\" } as any,\n nameKey: \"name\",\n valueKey: \"count\",\n },\n },\n\n Chart: {\n props: z.object({\n options: z.record(z.string(), z.unknown()),\n height: z.number().optional(),\n }),\n description:\n \"Low-level ECharts component for any chart type. Pass a full ECharts option object. Use for advanced charts not covered by BarChart/LineChart/PieChart. Data arrays in options can use { $state } references.\",\n example: {\n options: {\n xAxis: { type: \"category\", data: [\"Mon\", \"Tue\", \"Wed\"] },\n yAxis: { type: \"value\" },\n series: [{ type: \"bar\", data: [120, 200, 150] }],\n },\n height: 400,\n },\n },\n\n // ── Form Controls ─────────────────────────────────────────────────────\n\n Input: {\n props: z.object({\n label: z.string().optional(),\n placeholder: z.string().optional(),\n type: z.enum([\"text\", \"email\", \"password\", \"number\", \"url\"]).optional(),\n description: z.string().optional(),\n error: z.string().optional(),\n }),\n description: \"Text input field.\",\n example: { label: \"Email\", placeholder: \"you@example.com\", type: \"email\" },\n },\n\n InputArea: {\n props: z.object({\n label: z.string().optional(),\n placeholder: z.string().optional(),\n rows: z.number().optional(),\n description: z.string().optional(),\n error: z.string().optional(),\n }),\n description: \"Multi-line text area.\",\n example: { label: \"Message\", placeholder: \"Type your message...\", rows: 4 },\n },\n\n Select: {\n props: z.object({\n label: z.string().optional(),\n placeholder: z.string().optional(),\n options: z.array(z.object({ value: z.string(), label: z.string() })),\n }),\n description:\n \"Dropdown select. Provide options as an array of {value, label}.\",\n example: {\n label: \"Country\",\n placeholder: \"Select...\",\n options: [\n { value: \"us\", label: \"United States\" },\n { value: \"uk\", label: \"United Kingdom\" },\n ],\n },\n },\n\n Checkbox: {\n props: z.object({\n label: z.string(),\n }),\n description: \"Boolean checkbox input with a label.\",\n example: { label: \"I agree to the terms\" },\n },\n\n Switch: {\n props: z.object({\n label: z.string(),\n }),\n description: \"Toggle switch with a label.\",\n example: { label: \"Enable notifications\" },\n },\n\n Radio: {\n props: z.object({\n legend: z.string(),\n options: z.array(z.object({ value: z.string(), label: z.string() })),\n }),\n description:\n \"Radio button group. Provide legend and options as {value, label} pairs.\",\n example: {\n legend: \"Plan\",\n options: [\n { value: \"free\", label: \"Free\" },\n { value: \"pro\", label: \"Pro\" },\n ],\n },\n },\n\n Field: {\n props: z.object({\n label: z.string().optional(),\n description: z.string().optional(),\n error: z.string().optional(),\n }),\n slots: [\"default\"],\n description:\n \"Form field wrapper that adds a label, description, and error message around an input.\",\n example: { label: \"Username\", description: \"Must be unique.\" },\n },\n\n // ── Overlays & Disclosure ─────────────────────────────────────────────\n\n Tabs: {\n props: z.object({\n tabs: z.array(z.object({ value: z.string(), label: z.string() })),\n defaultValue: z.string().optional(),\n variant: z.enum([\"segmented\", \"underline\"]).optional(),\n }),\n slots: [\"default\"],\n description:\n \"Tabbed navigation. Provide tab definitions; place tab content as children.\",\n example: {\n tabs: [\n { value: \"general\", label: \"General\" },\n { value: \"advanced\", label: \"Advanced\" },\n ],\n defaultValue: \"general\",\n },\n },\n\n Dialog: {\n props: z.object({\n trigger: z.string(),\n title: z.string().optional(),\n description: z.string().optional(),\n }),\n slots: [\"default\"],\n description:\n \"Modal dialog. The `trigger` text creates a button that opens the dialog.\",\n example: {\n trigger: \"Delete\",\n title: \"Confirm deletion\",\n description: \"This action cannot be undone.\",\n },\n },\n\n Collapsible: {\n props: z.object({\n label: z.string(),\n }),\n slots: [\"default\"],\n description:\n \"Expandable/collapsible section. The label is the toggle trigger.\",\n example: { label: \"Advanced options\" },\n },\n\n Tooltip: {\n props: z.object({\n content: z.string(),\n }),\n slots: [\"default\"],\n description: \"Hover tooltip. Wrap the target element as a child.\",\n },\n\n Popover: {\n props: z.object({\n trigger: z.string(),\n }),\n slots: [\"default\"],\n description:\n \"Popover panel. The `trigger` text creates a button that toggles the popover.\",\n example: { trigger: \"More info\" },\n },\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"catalog.js","names":[],"sources":["../src/catalog/sf-components.ts"],"sourcesContent":["/**\n * Curated SignalFlare component definitions for json-render catalogs.\n *\n * These definitions expose an LLM-friendly API surface:\n * - Simple string/enum/boolean props (no className, callbacks, refs)\n * - `text` / `label` props for display text (mapped to `children` in renderers)\n * - Descriptions and examples that guide the LLM\n *\n * The renderers in `sf-registry.ts` bridge these LLM-friendly props\n * to the actual SignalFlare component APIs.\n */\n\nimport { z } from \"zod\";\n\nexport const sfComponentDefinitions: Record<\n string,\n {\n props: z.ZodTypeAny;\n slots?: string[];\n description: string;\n example?: Record<string, unknown>;\n }\n> = {\n // ── Layout ────────────────────────────────────────────────────────────\n\n Stack: {\n props: z.object({\n direction: z.enum([\"horizontal\", \"vertical\"]).optional(),\n gap: z.enum([\"sm\", \"base\", \"lg\"]).optional(),\n align: z.enum([\"start\", \"center\", \"end\", \"stretch\"]).optional(),\n wrap: z.boolean().optional(),\n }),\n slots: [\"default\"],\n description:\n \"Flex layout container. Use as the primary way to arrange child components vertically or horizontally with consistent spacing. Default: vertical, base gap.\",\n example: { direction: \"vertical\", gap: \"base\" },\n },\n\n Surface: {\n props: z.object({\n padding: z.enum([\"sm\", \"base\", \"lg\"]).optional(),\n border: z.boolean().optional(),\n }),\n slots: [\"default\"],\n description:\n \"Visual container with background, shadow, and ring. Use for cards, panels, and sections. For layout/spacing, use Stack instead.\",\n example: { padding: \"base\", border: true },\n },\n\n Grid: {\n props: z.object({\n variant: z\n .enum([\"2up\", \"side-by-side\", \"2-1\", \"1-2\", \"3up\", \"4up\", \"6up\"])\n .optional(),\n gap: z.enum([\"none\", \"sm\", \"base\", \"lg\"]).optional(),\n }),\n slots: [\"default\"],\n description:\n \"Responsive CSS grid layout. Place child components inside as grid items.\",\n example: { variant: \"3up\", gap: \"base\" },\n },\n\n LayerCard: {\n props: z.object({}),\n slots: [\"default\"],\n description:\n \"Elevated card container with border and shadow. Wrap content inside it.\",\n },\n\n // ── Typography ────────────────────────────────────────────────────────\n\n Text: {\n props: z.object({\n text: z.string(),\n variant: z\n .enum([\n \"heading1\",\n \"heading2\",\n \"heading3\",\n \"body\",\n \"secondary\",\n \"success\",\n \"error\",\n \"mono\",\n ])\n .optional(),\n size: z.enum([\"xs\", \"sm\", \"base\", \"lg\"]).optional(),\n bold: z.boolean().optional(),\n }),\n description:\n \"Text content — headings, body copy, labels. Use variant='heading1' for page titles, 'heading2' for sections, 'body' for paragraphs.\",\n example: { text: \"Dashboard Overview\", variant: \"heading1\" },\n },\n\n Code: {\n props: z.object({\n code: z.string(),\n lang: z.enum([\"ts\", \"tsx\", \"jsonc\", \"bash\", \"css\"]).optional(),\n }),\n description: \"Code display with syntax highlighting.\",\n example: { code: \"const x = 42;\", lang: \"ts\" },\n },\n\n // ── Actions ───────────────────────────────────────────────────────────\n\n Button: {\n props: z.object({\n label: z.string(),\n variant: z\n .enum([\"primary\", \"secondary\", \"ghost\", \"destructive\", \"outline\"])\n .optional(),\n size: z.enum([\"xs\", \"sm\", \"base\", \"lg\"]).optional(),\n disabled: z.boolean().optional(),\n loading: z.boolean().optional(),\n }),\n description: \"Clickable action button.\",\n example: { label: \"Save changes\", variant: \"primary\" },\n },\n\n Link: {\n props: z.object({\n text: z.string(),\n href: z.string(),\n variant: z.enum([\"inline\", \"plain\"]).optional(),\n }),\n description: \"Navigation link.\",\n example: { text: \"View details\", href: \"/details\" },\n },\n\n // ── Data Display ──────────────────────────────────────────────────────\n\n Badge: {\n props: z.object({\n text: z.string(),\n variant: z\n .enum([\"primary\", \"secondary\", \"destructive\", \"outline\", \"beta\"])\n .optional(),\n }),\n description: \"Small status label or tag.\",\n example: { text: \"Active\", variant: \"primary\" },\n },\n\n Banner: {\n props: z.object({\n variant: z.enum([\"default\", \"alert\", \"error\"]).optional(),\n title: z.string(),\n description: z.string().optional(),\n }),\n description: \"Full-width alert message for notices, warnings, or errors.\",\n example: {\n variant: \"alert\",\n title: \"Warning\",\n description: \"Your trial expires in 3 days.\",\n },\n },\n\n Meter: {\n props: z.object({\n label: z.string(),\n value: z.number(),\n max: z.number().optional(),\n showValue: z.boolean().optional(),\n }),\n description: \"Progress bar showing a value (defaults 0–100).\",\n example: { label: \"Storage used\", value: 72, max: 100 },\n },\n\n Empty: {\n props: z.object({\n title: z.string(),\n description: z.string().optional(),\n size: z.enum([\"sm\", \"base\", \"lg\"]).optional(),\n }),\n description: \"Placeholder for empty lists, tables, or sections.\",\n example: {\n title: \"No results\",\n description: \"Try adjusting your filters.\",\n },\n },\n\n Loader: {\n props: z.object({\n size: z.enum([\"sm\", \"base\", \"lg\"]).optional(),\n }),\n description: \"Animated loading spinner.\",\n },\n\n Table: {\n props: z.object({\n data: z.array(z.record(z.string(), z.unknown())),\n columns: z.array(z.object({ key: z.string(), label: z.string() })),\n }),\n description:\n \"Data table. Provide `data` (array of row objects) and `columns` (key + label pairs). The renderer builds header and body automatically.\",\n example: {\n columns: [\n { key: \"name\", label: \"Name\" },\n { key: \"email\", label: \"Email\" },\n ],\n data: [{ name: \"Alice\", email: \"alice@example.com\" }],\n },\n },\n\n // ── Charts ──────────────────────────────────────────────────────────\n\n BarChart: {\n props: z.object({\n title: z.string().optional(),\n data: z.array(z.record(z.string(), z.unknown())),\n xKey: z.string(),\n yKey: z.string(),\n aggregate: z.enum([\"sum\", \"count\", \"avg\"]).optional(),\n color: z.string().optional(),\n height: z.number().optional(),\n }),\n description:\n \"Bar chart visualization. Use { $state: \\\"/path\\\" } on data to bind to an array of objects. xKey is the category/group field, yKey is the numeric value field. Use aggregate='count' to count items grouped by xKey.\",\n example: {\n data: { $state: \"/sales\" } as any,\n xKey: \"month\",\n yKey: \"revenue\",\n },\n },\n\n LineChart: {\n props: z.object({\n title: z.string().optional(),\n data: z.array(z.record(z.string(), z.unknown())),\n xKey: z.string(),\n yKey: z.string(),\n aggregate: z.enum([\"sum\", \"count\", \"avg\"]).optional(),\n color: z.string().optional(),\n height: z.number().optional(),\n }),\n description:\n 'Line chart visualization. Use { $state: \"/path\" } on data to bind to an array of objects. xKey is the x-axis field, yKey is the numeric value field.',\n example: {\n data: { $state: \"/metrics\" } as any,\n xKey: \"date\",\n yKey: \"value\",\n },\n },\n\n PieChart: {\n props: z.object({\n title: z.string().optional(),\n data: z.array(z.record(z.string(), z.unknown())),\n nameKey: z.string(),\n valueKey: z.string(),\n height: z.number().optional(),\n }),\n description:\n 'Pie/donut chart. nameKey is the label field, valueKey is the numeric field. Use { $state: \"/path\" } on data.',\n example: {\n data: { $state: \"/categories\" } as any,\n nameKey: \"name\",\n valueKey: \"count\",\n },\n },\n\n Chart: {\n props: z.object({\n options: z.record(z.string(), z.unknown()),\n height: z.number().optional(),\n }),\n description:\n \"Low-level ECharts component for any chart type. Pass a full ECharts option object. Use for advanced charts not covered by BarChart/LineChart/PieChart. Data arrays in options can use { $state } references.\",\n example: {\n options: {\n xAxis: { type: \"category\", data: [\"Mon\", \"Tue\", \"Wed\"] },\n yAxis: { type: \"value\" },\n series: [{ type: \"bar\", data: [120, 200, 150] }],\n },\n height: 400,\n },\n },\n\n // ── Form Controls ─────────────────────────────────────────────────────\n\n Input: {\n props: z.object({\n label: z.string().optional(),\n placeholder: z.string().optional(),\n type: z.enum([\"text\", \"email\", \"password\", \"number\", \"url\"]).optional(),\n description: z.string().optional(),\n error: z.string().optional(),\n }),\n description: \"Text input field.\",\n example: { label: \"Email\", placeholder: \"you@example.com\", type: \"email\" },\n },\n\n InputArea: {\n props: z.object({\n label: z.string().optional(),\n placeholder: z.string().optional(),\n rows: z.number().optional(),\n description: z.string().optional(),\n error: z.string().optional(),\n }),\n description: \"Multi-line text area.\",\n example: { label: \"Message\", placeholder: \"Type your message...\", rows: 4 },\n },\n\n Select: {\n props: z.object({\n label: z.string().optional(),\n placeholder: z.string().optional(),\n options: z.array(z.object({ value: z.string(), label: z.string() })),\n }),\n description:\n \"Dropdown select. Provide options as an array of {value, label}.\",\n example: {\n label: \"Country\",\n placeholder: \"Select...\",\n options: [\n { value: \"us\", label: \"United States\" },\n { value: \"uk\", label: \"United Kingdom\" },\n ],\n },\n },\n\n Checkbox: {\n props: z.object({\n label: z.string(),\n }),\n description: \"Boolean checkbox input with a label.\",\n example: { label: \"I agree to the terms\" },\n },\n\n Switch: {\n props: z.object({\n label: z.string(),\n }),\n description: \"Toggle switch with a label.\",\n example: { label: \"Enable notifications\" },\n },\n\n Radio: {\n props: z.object({\n legend: z.string(),\n options: z.array(z.object({ value: z.string(), label: z.string() })),\n }),\n description:\n \"Radio button group. Provide legend and options as {value, label} pairs.\",\n example: {\n legend: \"Plan\",\n options: [\n { value: \"free\", label: \"Free\" },\n { value: \"pro\", label: \"Pro\" },\n ],\n },\n },\n\n Field: {\n props: z.object({\n label: z.string().optional(),\n description: z.string().optional(),\n error: z.string().optional(),\n }),\n slots: [\"default\"],\n description:\n \"Form field wrapper that adds a label, description, and error message around an input.\",\n example: { label: \"Username\", description: \"Must be unique.\" },\n },\n\n // ── Overlays & Disclosure ─────────────────────────────────────────────\n\n Tabs: {\n props: z.object({\n tabs: z.array(z.object({ value: z.string(), label: z.string() })),\n defaultValue: z.string().optional(),\n variant: z.enum([\"segmented\", \"underline\"]).optional(),\n }),\n slots: [\"default\"],\n description:\n \"Tabbed navigation. Provide tab definitions; place tab content as children.\",\n example: {\n tabs: [\n { value: \"general\", label: \"General\" },\n { value: \"advanced\", label: \"Advanced\" },\n ],\n defaultValue: \"general\",\n },\n },\n\n Dialog: {\n props: z.object({\n trigger: z.string(),\n title: z.string().optional(),\n description: z.string().optional(),\n }),\n slots: [\"default\"],\n description:\n \"Modal dialog. The `trigger` text creates a button that opens the dialog.\",\n example: {\n trigger: \"Delete\",\n title: \"Confirm deletion\",\n description: \"This action cannot be undone.\",\n },\n },\n\n Collapsible: {\n props: z.object({\n label: z.string(),\n }),\n slots: [\"default\"],\n description:\n \"Expandable/collapsible section. The label is the toggle trigger.\",\n example: { label: \"Advanced options\" },\n },\n\n Tooltip: {\n props: z.object({\n content: z.string(),\n }),\n slots: [\"default\"],\n description: \"Hover tooltip. Wrap the target element as a child.\",\n },\n\n Popover: {\n props: z.object({\n trigger: z.string(),\n }),\n slots: [\"default\"],\n description:\n \"Popover panel. The `trigger` text creates a button that toggles the popover.\",\n example: { trigger: \"More info\" },\n },\n};\n"],"mappings":"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"}