@signalflare-ai/ui 1.1.0 → 1.3.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 (362) hide show
  1. package/CHANGELOG.md +102 -5
  2. package/README.md +1 -1
  3. package/ai/component-registry.json +531 -79
  4. package/ai/component-registry.md +4067 -6
  5. package/ai/schemas.ts +6 -1
  6. package/dist/.build-complete +1 -1
  7. package/dist/ai/schemas.d.ts +76 -58
  8. package/dist/ai/schemas.d.ts.map +1 -1
  9. package/dist/{ai-actions-DSVeQn4e.js → ai-actions-CBfz5XEf.js} +4 -4
  10. package/dist/{ai-actions-DSVeQn4e.js.map → ai-actions-CBfz5XEf.js.map} +1 -1
  11. package/dist/{ai-agent-card-BXHwhWAU.js → ai-agent-card-CByAUe0q.js} +3 -3
  12. package/dist/ai-agent-card-CByAUe0q.js.map +1 -0
  13. package/dist/{ai-approval-aa0qvjFN.js → ai-approval-Ci8N70a7.js} +4 -3
  14. package/dist/{ai-approval-aa0qvjFN.js.map → ai-approval-Ci8N70a7.js.map} +1 -1
  15. package/dist/{ai-code-block-BgtIxtZZ.js → ai-code-block-P9TJHvaC.js} +37 -39
  16. package/dist/ai-code-block-P9TJHvaC.js.map +1 -0
  17. package/dist/ai-conversation-Qslfdi1t.js +228 -0
  18. package/dist/ai-conversation-Qslfdi1t.js.map +1 -0
  19. package/dist/{ai-info-banner-uFxHHwBA.js → ai-info-banner-B_9vtGK3.js} +8 -4
  20. package/dist/ai-info-banner-B_9vtGK3.js.map +1 -0
  21. package/dist/{ai-message-BjnFznXy.js → ai-message-Ci3gwM7G.js} +29 -10
  22. package/dist/ai-message-Ci3gwM7G.js.map +1 -0
  23. package/dist/{ai-mission-header-08__gULL.js → ai-mission-header-CaBc19-t.js} +2 -2
  24. package/dist/{ai-mission-header-08__gULL.js.map → ai-mission-header-CaBc19-t.js.map} +1 -1
  25. package/dist/{ai-part-group-DBtgTgAn.js → ai-part-group-Dx1Mr92B.js} +5 -4
  26. package/dist/ai-part-group-Dx1Mr92B.js.map +1 -0
  27. package/dist/{ai-prompt-input-CuluUzpf.js → ai-prompt-input-Bm4XoSj2.js} +44 -55
  28. package/dist/ai-prompt-input-Bm4XoSj2.js.map +1 -0
  29. package/dist/{ai-question-CHHoDJMg.js → ai-question-OyJovxGe.js} +4 -3
  30. package/dist/{ai-question-CHHoDJMg.js.map → ai-question-OyJovxGe.js.map} +1 -1
  31. package/dist/{ai-reasoning-CnL6ZSr5.js → ai-reasoning-BLfBXx3F.js} +9 -5
  32. package/dist/ai-reasoning-BLfBXx3F.js.map +1 -0
  33. package/dist/{ai-response-BEUg3xvd.js → ai-response-hbVCZJmo.js} +9 -4
  34. package/dist/ai-response-hbVCZJmo.js.map +1 -0
  35. package/dist/{ai-shimmer-By5_L05p.js → ai-shimmer-BamNMNK3.js} +2 -2
  36. package/dist/{ai-shimmer-By5_L05p.js.map → ai-shimmer-BamNMNK3.js.map} +1 -1
  37. package/dist/{ai-status-badge-BGYGWYF6.js → ai-status-badge-BZLczdkI.js} +2 -2
  38. package/dist/{ai-status-badge-BGYGWYF6.js.map → ai-status-badge-BZLczdkI.js.map} +1 -1
  39. package/dist/{ai-streaming-text-CMfoThV0.js → ai-streaming-text-DgYu64UH.js} +44 -16
  40. package/dist/ai-streaming-text-DgYu64UH.js.map +1 -0
  41. package/dist/{ai-subagent-DcPRqkAA.js → ai-subagent-p97AI1h9.js} +14 -6
  42. package/dist/ai-subagent-p97AI1h9.js.map +1 -0
  43. package/dist/{ai-suggestion-MgeCg5Ar.js → ai-suggestion-Bj6vF7CT.js} +3 -3
  44. package/dist/{ai-suggestion-MgeCg5Ar.js.map → ai-suggestion-Bj6vF7CT.js.map} +1 -1
  45. package/dist/{ai-task-list-Da9zIm00.js → ai-task-list-C_UQYpk9.js} +15 -6
  46. package/dist/ai-task-list-C_UQYpk9.js.map +1 -0
  47. package/dist/{ai-timeline-Cwu045IR.js → ai-timeline-CePL1LOU.js} +3 -3
  48. package/dist/ai-timeline-CePL1LOU.js.map +1 -0
  49. package/dist/{ai-tool-Cn1O4xjP.js → ai-tool-CfRcwmHT.js} +35 -16
  50. package/dist/ai-tool-CfRcwmHT.js.map +1 -0
  51. package/dist/{ai-usage-bar-DjS12DMp.js → ai-usage-bar-45pVRCGA.js} +2 -2
  52. package/dist/{ai-usage-bar-DjS12DMp.js.map → ai-usage-bar-45pVRCGA.js.map} +1 -1
  53. package/dist/{badge-D_eaA6wv.js → badge-Beb-6uut.js} +5 -5
  54. package/dist/{badge-D_eaA6wv.js.map → badge-Beb-6uut.js.map} +1 -1
  55. package/dist/{banner-B_6oBrsu.js → banner-CCEksxPg.js} +8 -3
  56. package/dist/banner-CCEksxPg.js.map +1 -0
  57. package/dist/{breadcrumbs-BlmeYfgq.js → breadcrumbs-HiTmgaZ4.js} +5 -5
  58. package/dist/{breadcrumbs-BlmeYfgq.js.map → breadcrumbs-HiTmgaZ4.js.map} +1 -1
  59. package/dist/{button-De0267YU.js → button-BHOgXJRU.js} +4 -4
  60. package/dist/{button-De0267YU.js.map → button-BHOgXJRU.js.map} +1 -1
  61. package/dist/catalog.js +1 -1
  62. package/dist/catalog.js.map +1 -1
  63. package/dist/{chart-BK3sVPnD.js → chart-B9FfZdKs.js} +7 -7
  64. package/dist/chart-B9FfZdKs.js.map +1 -0
  65. package/dist/{checkbox-DYhUmZNw.js → checkbox-Cy_OCyay.js} +3 -3
  66. package/dist/{checkbox-DYhUmZNw.js.map → checkbox-Cy_OCyay.js.map} +1 -1
  67. package/dist/{clipboard-text-ssybngLw.js → clipboard-text-CKSvNp9L.js} +6 -5
  68. package/dist/clipboard-text-CKSvNp9L.js.map +1 -0
  69. package/dist/{cn-YROP2_ox.js → cn-CmAOpn49.js} +2 -2
  70. package/dist/{cn-YROP2_ox.js.map → cn-CmAOpn49.js.map} +1 -1
  71. package/dist/{code-Cx-QSoOT.js → code-JsQz-0G_.js} +4 -4
  72. package/dist/{code-Cx-QSoOT.js.map → code-JsQz-0G_.js.map} +1 -1
  73. package/dist/{collapsible-DWsXeXmS.js → collapsible-1kOZ-89L.js} +2 -2
  74. package/dist/{collapsible-DWsXeXmS.js.map → collapsible-1kOZ-89L.js.map} +1 -1
  75. package/dist/{combobox-C0iW6a0r.js → combobox-CQwDmqgA.js} +4 -4
  76. package/dist/{combobox-C0iW6a0r.js.map → combobox-CQwDmqgA.js.map} +1 -1
  77. package/dist/command-line/cli.js +3 -3
  78. package/dist/{command-palette-DGzioeki.js → command-palette-Bkuv3e6o.js} +20 -5
  79. package/dist/command-palette-Bkuv3e6o.js.map +1 -0
  80. package/dist/components/ai-actions.js +1 -1
  81. package/dist/components/ai-agent-card.js +1 -1
  82. package/dist/components/ai-approval.js +1 -1
  83. package/dist/components/ai-code-block.js +1 -1
  84. package/dist/components/ai-conversation.js +2 -2
  85. package/dist/components/ai-info-banner.js +1 -1
  86. package/dist/components/ai-message.js +1 -1
  87. package/dist/components/ai-mission-header.js +1 -1
  88. package/dist/components/ai-part-group.js +1 -1
  89. package/dist/components/ai-prompt-input.js +1 -1
  90. package/dist/components/ai-question.js +1 -1
  91. package/dist/components/ai-reasoning.js +1 -1
  92. package/dist/components/ai-response.js +1 -1
  93. package/dist/components/ai-shimmer.js +1 -1
  94. package/dist/components/ai-status-badge.js +1 -1
  95. package/dist/components/ai-streaming-text.js +2 -2
  96. package/dist/components/ai-subagent.js +1 -1
  97. package/dist/components/ai-suggestion.js +1 -1
  98. package/dist/components/ai-task-list.js +1 -1
  99. package/dist/components/ai-timeline.js +1 -1
  100. package/dist/components/ai-tool.js +1 -1
  101. package/dist/components/ai-usage-bar.js +1 -1
  102. package/dist/components/badge.js +1 -1
  103. package/dist/components/banner.js +1 -1
  104. package/dist/components/breadcrumbs.js +1 -1
  105. package/dist/components/button.js +1 -1
  106. package/dist/components/chart.js +2 -2
  107. package/dist/components/checkbox.js +1 -1
  108. package/dist/components/clipboard-text.js +1 -1
  109. package/dist/components/code.js +1 -1
  110. package/dist/components/collapsible.js +1 -1
  111. package/dist/components/combobox.js +1 -1
  112. package/dist/components/command-palette.js +1 -1
  113. package/dist/components/data-grid.js +1 -1
  114. package/dist/components/date-picker.js +1 -1
  115. package/dist/components/date-range-picker.js +1 -1
  116. package/dist/components/dialog.js +1 -1
  117. package/dist/components/dropdown.js +1 -1
  118. package/dist/components/empty.js +1 -1
  119. package/dist/components/field.js +1 -1
  120. package/dist/components/filters.js +1 -1
  121. package/dist/components/flow.js +1 -1
  122. package/dist/components/grid.js +1 -1
  123. package/dist/components/input.js +2 -2
  124. package/dist/components/label.js +1 -1
  125. package/dist/components/layer-card.js +1 -1
  126. package/dist/components/link.js +3 -3
  127. package/dist/components/link.js.map +1 -1
  128. package/dist/components/loader.js +2 -2
  129. package/dist/components/menubar.js +1 -1
  130. package/dist/components/meter.js +1 -1
  131. package/dist/components/pagination.js +1 -1
  132. package/dist/components/popover.js +1 -1
  133. package/dist/components/radio.js +1 -1
  134. package/dist/components/select.js +1 -1
  135. package/dist/components/sensitive-input.js +1 -1
  136. package/dist/components/sidebar.js +1 -1
  137. package/dist/components/signalflare-ai-logo.js +1 -1
  138. package/dist/components/sparkline.js +1 -1
  139. package/dist/components/stat-card.js +1 -1
  140. package/dist/components/surface.js +1 -1
  141. package/dist/components/switch.js +1 -1
  142. package/dist/components/table.js +1 -1
  143. package/dist/components/tabs.js +1 -1
  144. package/dist/components/text-roll.js +1 -1
  145. package/dist/components/text.js +1 -1
  146. package/dist/components/theme-toggle.js +1 -1
  147. package/dist/components/toast.js +1 -1
  148. package/dist/components/tooltip.js +1 -1
  149. package/dist/components/use-agent-harness.js +1 -1
  150. package/dist/{data-grid-CG76N_hK.js → data-grid-DDSFMHud.js} +136 -53
  151. package/dist/data-grid-DDSFMHud.js.map +1 -0
  152. package/dist/{date-picker-Dqg9L4xu.js → date-picker-O34AqG3f.js} +2 -2
  153. package/dist/{date-picker-Dqg9L4xu.js.map → date-picker-O34AqG3f.js.map} +1 -1
  154. package/dist/{date-range-picker-D75LLINc.js → date-range-picker-YKYvum_r.js} +29 -39
  155. package/dist/{date-range-picker-D75LLINc.js.map → date-range-picker-YKYvum_r.js.map} +1 -1
  156. package/dist/{dialog-CyHEQXEY.js → dialog-DYqu4aDO.js} +3 -3
  157. package/dist/{dialog-CyHEQXEY.js.map → dialog-DYqu4aDO.js.map} +1 -1
  158. package/dist/{dist-1-gcEL2L.js → dist-6AtBsaJE.js} +153 -47
  159. package/dist/dist-6AtBsaJE.js.map +1 -0
  160. package/dist/{dropdown-qnEYRFXZ.js → dropdown-XzbnRLYR.js} +15 -5
  161. package/dist/dropdown-XzbnRLYR.js.map +1 -0
  162. package/dist/{echart-DURZEyai.js → echart-DGBIVAv1.js} +23 -57
  163. package/dist/{echart-DURZEyai.js.map → echart-DGBIVAv1.js.map} +1 -1
  164. package/dist/{empty-D2TypIId.js → empty-C1tAkawe.js} +12 -7
  165. package/dist/empty-C1tAkawe.js.map +1 -0
  166. package/dist/{field-Y_UK1_Cg.js → field-DBpFzzBS.js} +3 -3
  167. package/dist/{field-Y_UK1_Cg.js.map → field-DBpFzzBS.js.map} +1 -1
  168. package/dist/{filters-Bw_U6ZTx.js → filters-SmEl93za.js} +10 -10
  169. package/dist/filters-SmEl93za.js.map +1 -0
  170. package/dist/{flow-BRsYUCJa.js → flow-BLzgbq1T.js} +6 -6
  171. package/dist/flow-BLzgbq1T.js.map +1 -0
  172. package/dist/genui.js +2 -2
  173. package/dist/genui.js.map +1 -1
  174. package/dist/{grid-qUAN9hFx.js → grid-CifjQL-5.js} +2 -2
  175. package/dist/{grid-qUAN9hFx.js.map → grid-CifjQL-5.js.map} +1 -1
  176. package/dist/{highlight-to-react-ClEfL81q.js → highlight-to-react-DN9dUCS2.js} +9 -15
  177. package/dist/highlight-to-react-DN9dUCS2.js.map +1 -0
  178. package/dist/index.js +72 -72
  179. package/dist/index.js.map +1 -1
  180. package/dist/{input-DddtBN-g.js → input-COmx2M_R.js} +5 -5
  181. package/dist/{input-DddtBN-g.js.map → input-COmx2M_R.js.map} +1 -1
  182. package/dist/{input-DXYUjGgD.js → input-GkfMQZC_.js} +3 -3
  183. package/dist/{input-DXYUjGgD.js.map → input-GkfMQZC_.js.map} +1 -1
  184. package/dist/{label-QtJxtJ4u.js → label-CiGZ464N.js} +3 -3
  185. package/dist/{label-QtJxtJ4u.js.map → label-CiGZ464N.js.map} +1 -1
  186. package/dist/{layer-card-BME0eljh.js → layer-card-8l8GuLQr.js} +2 -2
  187. package/dist/{layer-card-BME0eljh.js.map → layer-card-8l8GuLQr.js.map} +1 -1
  188. package/dist/layout-CWBE0qwx.js +6207 -0
  189. package/dist/layout-CWBE0qwx.js.map +1 -0
  190. package/dist/{link-provider-BUZKXaNE.js → link-provider-BSn8YJon.js} +2 -2
  191. package/dist/link-provider-BSn8YJon.js.map +1 -0
  192. package/dist/{loader-DAcc-Uag.js → loader-BEMz8pJO.js} +1 -1
  193. package/dist/{loader-DAcc-Uag.js.map → loader-BEMz8pJO.js.map} +1 -1
  194. package/dist/measured-text-CXkdw9Yr.js +305 -0
  195. package/dist/measured-text-CXkdw9Yr.js.map +1 -0
  196. package/dist/{menubar-C8NzAjfd.js → menubar-CoOr4ocj.js} +3 -3
  197. package/dist/{menubar-C8NzAjfd.js.map → menubar-CoOr4ocj.js.map} +1 -1
  198. package/dist/{meter-CpmTenEr.js → meter-Pf_VOl59.js} +2 -2
  199. package/dist/{meter-CpmTenEr.js.map → meter-Pf_VOl59.js.map} +1 -1
  200. package/dist/{pagination-BVqdlONY.js → pagination-DSY279Ta.js} +2 -2
  201. package/dist/{pagination-BVqdlONY.js.map → pagination-DSY279Ta.js.map} +1 -1
  202. package/dist/{popover-BRQZ2b6z.js → popover-BY-e9co1.js} +2 -2
  203. package/dist/{popover-BRQZ2b6z.js.map → popover-BY-e9co1.js.map} +1 -1
  204. package/dist/{radio-BNSwOt3B.js → radio-DZwL13j0.js} +2 -2
  205. package/dist/{radio-BNSwOt3B.js.map → radio-DZwL13j0.js.map} +1 -1
  206. package/dist/{select-1w2aebGQ.js → select-BFifYqHA.js} +6 -6
  207. package/dist/{select-1w2aebGQ.js.map → select-BFifYqHA.js.map} +1 -1
  208. package/dist/{sensitive-input-82Cez3vj.js → sensitive-input-DHLZcM73.js} +4 -4
  209. package/dist/{sensitive-input-82Cez3vj.js.map → sensitive-input-DHLZcM73.js.map} +1 -1
  210. package/dist/{sidebar-CAsCmSpM.js → sidebar-odGsdvG4.js} +6 -7
  211. package/dist/sidebar-odGsdvG4.js.map +1 -0
  212. package/dist/{signalflare-ai-logo-DDhxMJD6.js → signalflare-ai-logo-CNaDT_w8.js} +2 -2
  213. package/dist/{signalflare-ai-logo-DDhxMJD6.js.map → signalflare-ai-logo-CNaDT_w8.js.map} +1 -1
  214. package/dist/{skeleton-line-Do3UmGk9.js → skeleton-line-CxxYVTO2.js} +2 -2
  215. package/dist/{skeleton-line-Do3UmGk9.js.map → skeleton-line-CxxYVTO2.js.map} +1 -1
  216. package/dist/{sparkline-DdbeM4Ai.js → sparkline-BQ-4j2W2.js} +2 -2
  217. package/dist/{sparkline-DdbeM4Ai.js.map → sparkline-BQ-4j2W2.js.map} +1 -1
  218. package/dist/src/blocks/agent-harness/agent-harness.d.ts.map +1 -1
  219. package/dist/src/blocks/agent-harness/agent-harness.tsx +40 -16
  220. package/dist/src/blocks/commander/commander.tsx +15 -15
  221. package/dist/src/blocks/map-block/map-block.d.ts.map +1 -1
  222. package/dist/src/blocks/map-block/map-block.tsx +11 -7
  223. package/dist/src/components/ai-approval/ai-approval.d.ts.map +1 -1
  224. package/dist/src/components/ai-code-block/ai-code-block.d.ts +14 -13
  225. package/dist/src/components/ai-code-block/ai-code-block.d.ts.map +1 -1
  226. package/dist/src/components/ai-conversation/ai-conversation.d.ts +69 -37
  227. package/dist/src/components/ai-conversation/ai-conversation.d.ts.map +1 -1
  228. package/dist/src/components/ai-conversation/index.d.ts +2 -1
  229. package/dist/src/components/ai-conversation/index.d.ts.map +1 -1
  230. package/dist/src/components/ai-conversation/measurement-constants.d.ts +30 -0
  231. package/dist/src/components/ai-conversation/measurement-constants.d.ts.map +1 -0
  232. package/dist/src/components/ai-info-banner/ai-info-banner.d.ts.map +1 -1
  233. package/dist/src/components/ai-message/ai-message.d.ts +3 -0
  234. package/dist/src/components/ai-message/ai-message.d.ts.map +1 -1
  235. package/dist/src/components/ai-part-group/ai-part-group.d.ts.map +1 -1
  236. package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts +13 -3
  237. package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts.map +1 -1
  238. package/dist/src/components/ai-prompt-input/controller.d.ts.map +1 -1
  239. package/dist/src/components/ai-prompt-input/index.d.ts +1 -1
  240. package/dist/src/components/ai-prompt-input/index.d.ts.map +1 -1
  241. package/dist/src/components/ai-prompt-input/types.d.ts.map +1 -1
  242. package/dist/src/components/ai-question/ai-question.d.ts.map +1 -1
  243. package/dist/src/components/ai-reasoning/ai-reasoning.d.ts.map +1 -1
  244. package/dist/src/components/ai-response/ai-response.d.ts +12 -1
  245. package/dist/src/components/ai-response/ai-response.d.ts.map +1 -1
  246. package/dist/src/components/ai-streaming-text/ai-streaming-text.d.ts +27 -0
  247. package/dist/src/components/ai-streaming-text/ai-streaming-text.d.ts.map +1 -1
  248. package/dist/src/components/ai-streaming-text/index.d.ts +1 -1
  249. package/dist/src/components/ai-streaming-text/index.d.ts.map +1 -1
  250. package/dist/src/components/ai-subagent/ai-subagent.d.ts.map +1 -1
  251. package/dist/src/components/ai-task-list/ai-task-list.d.ts.map +1 -1
  252. package/dist/src/components/ai-tool/ai-tool.d.ts.map +1 -1
  253. package/dist/src/components/banner/banner.d.ts.map +1 -1
  254. package/dist/src/components/chart/echart.d.ts.map +1 -1
  255. package/dist/src/components/clipboard-text/clipboard-text.d.ts.map +1 -1
  256. package/dist/src/components/data-grid/data-grid.d.ts +2 -1
  257. package/dist/src/components/data-grid/data-grid.d.ts.map +1 -1
  258. package/dist/src/components/data-grid/features.d.ts +20 -0
  259. package/dist/src/components/data-grid/features.d.ts.map +1 -0
  260. package/dist/src/components/data-grid/types.d.ts +38 -7
  261. package/dist/src/components/data-grid/types.d.ts.map +1 -1
  262. package/dist/src/components/empty/empty.d.ts.map +1 -1
  263. package/dist/src/components/filters/filters.d.ts.map +1 -1
  264. package/dist/src/components/flow/use-children.d.ts +1 -1
  265. package/dist/src/components/link/link.d.ts.map +1 -1
  266. package/dist/src/components/sidebar/sidebar.d.ts +1 -1
  267. package/dist/src/components/signalflare-ai-logo/signalflare-ai-logo.d.ts.map +1 -1
  268. package/dist/src/components/stat-card/stat-card.d.ts +5 -0
  269. package/dist/src/components/stat-card/stat-card.d.ts.map +1 -1
  270. package/dist/src/components/text/text.d.ts +36 -1
  271. package/dist/src/components/text/text.d.ts.map +1 -1
  272. package/dist/src/components/text-roll/text-roll.d.ts.map +1 -1
  273. package/dist/src/components/theme-toggle/theme-toggle.d.ts.map +1 -1
  274. package/dist/src/components/toast/toast.d.ts.map +1 -1
  275. package/dist/src/components/tooltip/tooltip.d.ts.map +1 -1
  276. package/dist/src/index.d.ts +2 -2
  277. package/dist/src/index.d.ts.map +1 -1
  278. package/dist/src/utils/highlight-to-react.d.ts.map +1 -1
  279. package/dist/src/utils/index.d.ts +2 -0
  280. package/dist/src/utils/index.d.ts.map +1 -1
  281. package/dist/src/utils/measured-text.d.ts +40 -0
  282. package/dist/src/utils/measured-text.d.ts.map +1 -0
  283. package/dist/src/utils/use-measured-text.d.ts +59 -0
  284. package/dist/src/utils/use-measured-text.d.ts.map +1 -0
  285. package/dist/{stat-card-CEZscNh8.js → stat-card-Bspk4XFr.js} +30 -12
  286. package/dist/stat-card-Bspk4XFr.js.map +1 -0
  287. package/dist/styles/sf-binding.css +1 -1
  288. package/dist/styles/sf-standalone.css +2 -2
  289. package/dist/styles/shadcn.css +1 -1
  290. package/dist/styles/theme-minimal.css +9 -9
  291. package/dist/styles/theme-sf.css +14 -20
  292. package/dist/styles/theme-vesper.css +91 -0
  293. package/dist/{surface-BduI7Ehl.js → surface-CWdSFVUx.js} +3 -3
  294. package/dist/{surface-BduI7Ehl.js.map → surface-CWdSFVUx.js.map} +1 -1
  295. package/dist/{switch-CzZBRBL7.js → switch-TA4cByCJ.js} +5 -5
  296. package/dist/switch-TA4cByCJ.js.map +1 -0
  297. package/dist/{table-Rv4JMy0B.js → table-BM8JBGBs.js} +3 -3
  298. package/dist/{table-Rv4JMy0B.js.map → table-BM8JBGBs.js.map} +1 -1
  299. package/dist/{tabs-1cHrYoel.js → tabs-bnH2vGLv.js} +2 -2
  300. package/dist/{tabs-1cHrYoel.js.map → tabs-bnH2vGLv.js.map} +1 -1
  301. package/dist/{text-KJmGkwnf.js → text-iQ0YUFNg.js} +27 -6
  302. package/dist/text-iQ0YUFNg.js.map +1 -0
  303. package/dist/{text-roll-BZ3I1umc.js → text-roll-C3U2jd2u.js} +5 -2
  304. package/dist/text-roll-C3U2jd2u.js.map +1 -0
  305. package/dist/{theme-toggle-Bhu681D7.js → theme-toggle-BTVxD-fD.js} +10 -9
  306. package/dist/theme-toggle-BTVxD-fD.js.map +1 -0
  307. package/dist/{toast-Nw28a5Cx.js → toast-CgZVaAkw.js} +3 -3
  308. package/dist/{toast-Nw28a5Cx.js.map → toast-CgZVaAkw.js.map} +1 -1
  309. package/dist/{tooltip-Cb7QW-7H.js → tooltip-uobk6Oh-.js} +9 -3
  310. package/dist/tooltip-uobk6Oh-.js.map +1 -0
  311. package/dist/{use-agent-harness-BMyF8pTq.js → use-agent-harness-Dl8w6X5O.js} +3 -3
  312. package/dist/{use-agent-harness-BMyF8pTq.js.map → use-agent-harness-Dl8w6X5O.js.map} +1 -1
  313. package/dist/utils.js +4 -3
  314. package/package.json +27 -24
  315. package/scripts/component-registry/discovery.ts +11 -10
  316. package/scripts/component-registry/example-cleanup.ts +8 -8
  317. package/scripts/component-registry/index.ts +6 -6
  318. package/scripts/component-registry/schema-generator.ts +1 -1
  319. package/scripts/component-registry/sub-components.ts +35 -23
  320. package/scripts/component-registry/utils.ts +11 -11
  321. package/scripts/component-registry/variant-parser.ts +17 -15
  322. package/scripts/convert-demos-to-stories.ts +5 -5
  323. package/scripts/css-build.ts +1 -1
  324. package/scripts/theme-generator/config.ts +28 -146
  325. package/scripts/theme-generator/generate-css.ts +1 -2
  326. package/scripts/theme-generator/index.ts +0 -1
  327. package/scripts/theme-generator/migrate.ts +3 -3
  328. package/dist/ai-agent-card-BXHwhWAU.js.map +0 -1
  329. package/dist/ai-code-block-BgtIxtZZ.js.map +0 -1
  330. package/dist/ai-conversation-CArP7C8K.js +0 -184
  331. package/dist/ai-conversation-CArP7C8K.js.map +0 -1
  332. package/dist/ai-info-banner-uFxHHwBA.js.map +0 -1
  333. package/dist/ai-message-BjnFznXy.js.map +0 -1
  334. package/dist/ai-part-group-DBtgTgAn.js.map +0 -1
  335. package/dist/ai-prompt-input-CuluUzpf.js.map +0 -1
  336. package/dist/ai-reasoning-CnL6ZSr5.js.map +0 -1
  337. package/dist/ai-response-BEUg3xvd.js.map +0 -1
  338. package/dist/ai-streaming-text-CMfoThV0.js.map +0 -1
  339. package/dist/ai-subagent-DcPRqkAA.js.map +0 -1
  340. package/dist/ai-task-list-Da9zIm00.js.map +0 -1
  341. package/dist/ai-timeline-Cwu045IR.js.map +0 -1
  342. package/dist/ai-tool-Cn1O4xjP.js.map +0 -1
  343. package/dist/banner-B_6oBrsu.js.map +0 -1
  344. package/dist/chart-BK3sVPnD.js.map +0 -1
  345. package/dist/clipboard-text-ssybngLw.js.map +0 -1
  346. package/dist/command-palette-DGzioeki.js.map +0 -1
  347. package/dist/data-grid-CG76N_hK.js.map +0 -1
  348. package/dist/dist-1-gcEL2L.js.map +0 -1
  349. package/dist/dropdown-qnEYRFXZ.js.map +0 -1
  350. package/dist/empty-D2TypIId.js.map +0 -1
  351. package/dist/filters-Bw_U6ZTx.js.map +0 -1
  352. package/dist/flow-BRsYUCJa.js.map +0 -1
  353. package/dist/highlight-to-react-ClEfL81q.js.map +0 -1
  354. package/dist/link-provider-BUZKXaNE.js.map +0 -1
  355. package/dist/sidebar-CAsCmSpM.js.map +0 -1
  356. package/dist/stat-card-CEZscNh8.js.map +0 -1
  357. package/dist/styles/theme-blue-tint.css +0 -98
  358. package/dist/switch-CzZBRBL7.js.map +0 -1
  359. package/dist/text-KJmGkwnf.js.map +0 -1
  360. package/dist/text-roll-BZ3I1umc.js.map +0 -1
  361. package/dist/theme-toggle-Bhu681D7.js.map +0 -1
  362. package/dist/tooltip-Cb7QW-7H.js.map +0 -1
@@ -29,7 +29,9 @@
29
29
  "optional": true
30
30
  }
31
31
  },
32
- "examples": [],
32
+ "examples": [
33
+ "<AiActions>\n <AiAction tooltip=\"Copy\">\n <CopyIcon className=\"size-4\" />\n </AiAction>\n <AiAction tooltip=\"Retry\">\n <ArrowCounterClockwiseIcon className=\"size-4\" />\n </AiAction>\n <AiAction tooltip=\"Thumbs up\">\n <ThumbsUpIcon className=\"size-4\" />\n </AiAction>\n <AiAction tooltip=\"Thumbs down\">\n <ThumbsDownIcon className=\"size-4\" />\n </AiAction>\n </AiActions>"
34
+ ],
33
35
  "colors": ["text-sf-default", "text-sf-subtle"]
34
36
  },
35
37
  "AiAgentCard": {
@@ -132,7 +134,12 @@
132
134
  "optional": true
133
135
  }
134
136
  },
135
- "examples": [],
137
+ "examples": [
138
+ "<div className=\"flex flex-wrap gap-3\">\n <AiAgentCard\n name=\"Explore\"\n agentType=\"explore\"\n status=\"running\"\n modelId=\"claude-haiku-3.5\"\n currentTask=\"Scanning auth files for deprecated patterns...\"\n duration={4200}\n toolCallCount={3}\n />\n <AiAgentCard\n name=\"Execute\"\n agentType=\"execute\"\n status=\"running\"\n modelId=\"claude-sonnet-4\"\n currentTask=\"Rewriting jwt.ts using jose library...\"\n duration={8700}\n toolCallCount={1}\n />\n </div>",
139
+ "<div className=\"flex flex-wrap gap-3\">\n <AiAgentCard\n name=\"Explore\"\n agentType=\"explore\"\n status=\"idle\"\n modelId=\"claude-haiku-3.5\"\n />\n <AiAgentCard\n name=\"Plan\"\n agentType=\"plan\"\n status=\"running\"\n modelId=\"claude-sonnet-4\"\n currentTask=\"Drafting migration steps...\"\n duration={2100}\n toolCallCount={0}\n />\n <AiAgentCard\n name=\"Execute\"\n agentType=\"execute\"\n status=\"completed\"\n modelId=\"claude-sonnet-4\"\n currentTask=\"Rewrote 4 files successfully.\"\n duration={12_400}\n toolCallCount={7}\n />\n <AiAgentCard\n name=\"Test\"\n agentType=\"test\"\n status=\"error\"\n modelId=\"claude-haiku-3.5\"\n currentTask=\"3 tests failed: auth.spec.ts\"\n duration={3200}\n toolCallCount={2}\n />\n </div>",
140
+ "<div className=\"flex flex-wrap gap-3\">\n <AiAgentCard\n name=\"Explore\"\n agentType=\"explore\"\n status=\"completed\"\n modelId=\"claude-haiku-3.5\"\n duration={4200}\n toolCallCount={5}\n />\n <AiAgentCard\n name=\"Execute\"\n agentType=\"execute\"\n status=\"running\"\n modelId=\"claude-sonnet-4\"\n currentTask=\"Patching consumers...\"\n duration={6100}\n toolCallCount={3}\n selected\n />\n </div>",
141
+ "<div className=\"flex flex-wrap gap-2\">\n {[\n { name: \"Explore\", agentType: \"explore\", status: \"completed\" as const },\n { name: \"Plan\", agentType: \"plan\", status: \"completed\" as const },\n { name: \"Execute\", agentType: \"execute\", status: \"running\" as const },\n { name: \"Review\", agentType: \"review\", status: \"idle\" as const },\n ].map((agent) => (\n <AiAgentCard key={agent.name} size=\"sm\" {...agent} />\n ))}\n </div>"
142
+ ],
136
143
  "colors": [
137
144
  "bg-sf-brand",
138
145
  "bg-sf-danger",
@@ -233,7 +240,10 @@
233
240
  "optional": true
234
241
  }
235
242
  },
236
- "examples": [],
243
+ "examples": [
244
+ "<div className=\"w-full max-w-md\">\n <AiApproval\n kind=\"tool\"\n status={status}\n title=\"Execute shell command\"\n description=\"rm -rf /tmp/cache\"\n onApprove={() => setStatus(\"approved\")}\n onReject={() => setStatus(\"rejected\")}\n />\n </div>",
245
+ "<div className=\"w-full max-w-md\">\n <AiApproval\n kind=\"plan\"\n status={status}\n title=\"Deployment plan\"\n description=\"The agent proposes the following steps:\"\n items={[\n { id: \"1\", label: \"Run test suite\", description: \"All 142 tests\" },\n { id: \"2\", label: \"Build production bundle\" },\n { id: \"3\", label: \"Deploy to staging\", description: \"us-east-1\" },\n { id: \"4\", label: \"Run smoke tests\" },\n { id: \"5\", label: \"Promote to production\" },\n ]}\n showFeedback\n onApprove={() => setStatus(\"approved\")}\n onReject={() => setStatus(\"rejected\")}\n />\n </div>"
246
+ ],
237
247
  "colors": [
238
248
  "bg-sf-base",
239
249
  "bg-sf-brand",
@@ -251,7 +261,7 @@
251
261
  "AiCodeBlock": {
252
262
  "name": "AiCodeBlock",
253
263
  "type": "component",
254
- "description": "Displays a code block with monospace formatting and an optional copy button. Does not include a syntax highlighter — avoids the heavy `react-syntax-highlighter` dependency. Wrap with `AiCodeBlockCopyButton` for clipboard support.",
264
+ "description": "AiCodeBlock component",
255
265
  "importPath": "@signalflare-ai/ui",
256
266
  "category": "Other",
257
267
  "props": {
@@ -291,14 +301,30 @@
291
301
  "optional": true
292
302
  }
293
303
  },
294
- "examples": [],
304
+ "examples": [
305
+ "<AiCodeBlock code={CODE} language=\"tsx\">\n <AiCodeBlockCopyButton />\n </AiCodeBlock>",
306
+ "<AiCodeBlock\n code={`function greet(name: string) {\\n return \\`Hello, \\${name}!\\`;\\n}`}\n language=\"ts\"\n showLineNumbers\n >\n <AiCodeBlockCopyButton />\n </AiCodeBlock>",
307
+ "<AiCodeBlock code=\"npm install @signalflare-ai/ui\">\n <AiCodeBlockCopyButton />\n </AiCodeBlock>"
308
+ ],
295
309
  "colors": [
296
310
  "bg-sf-recessed",
297
311
  "border-sf-line",
298
312
  "text-sf-default",
299
313
  "text-sf-inactive",
300
314
  "text-sf-subtle"
301
- ]
315
+ ],
316
+ "subComponents": {
317
+ "CopyButton": {
318
+ "name": "CopyButton",
319
+ "description": "CopyButton sub-component",
320
+ "props": {
321
+ "timeout": {
322
+ "type": "number",
323
+ "optional": true
324
+ }
325
+ }
326
+ }
327
+ }
302
328
  },
303
329
  "AiConversation": {
304
330
  "name": "AiConversation",
@@ -328,7 +354,9 @@
328
354
  "optional": true
329
355
  }
330
356
  },
331
- "examples": [],
357
+ "examples": [
358
+ "<div className=\"h-80 w-full overflow-hidden rounded-lg border border-sf-line\">\n <AiConversation>\n <AiConversationContent>\n {MESSAGES.map((m) => (\n <AiMessage key={m.id} from={m.from}>\n <AiMessageContent>\n <AiResponse>{m.text}</AiResponse>\n </AiMessageContent>\n </AiMessage>\n ))}\n </AiConversationContent>\n </AiConversation>\n </div>"
359
+ ],
332
360
  "colors": []
333
361
  },
334
362
  "AiInfoBanner": {
@@ -376,7 +404,9 @@
376
404
  "optional": true
377
405
  }
378
406
  },
379
- "examples": [],
407
+ "examples": [
408
+ "<div className=\"flex w-full flex-col gap-3\">\n <AiInfoBanner level=\"info\">\n Follow-up message queued — will send after current response completes\n </AiInfoBanner>\n <AiInfoBanner level=\"change\">Switched to claude-opus-4-6</AiInfoBanner>\n <AiInfoBanner level=\"error\">\n Connection lost. Retrying in 3s…\n </AiInfoBanner>\n </div>"
409
+ ],
380
410
  "colors": [
381
411
  "border-sf-danger",
382
412
  "border-sf-info",
@@ -431,7 +461,11 @@
431
461
  "optional": true
432
462
  }
433
463
  },
434
- "examples": [],
464
+ "examples": [
465
+ "<div className=\"flex w-full flex-col gap-2 p-4\">\n <AiMessage from=\"user\">\n <AiMessageContent>What is the capital of France?</AiMessageContent>\n </AiMessage>\n <AiMessage from=\"assistant\">\n <AiMessageContent>\n <AiResponse>{\"The capital of France is **Paris**.\"}</AiResponse>\n </AiMessageContent>\n <AiMessageToolbar>\n <AiMessageActions>\n <AiMessageAction tooltip=\"Copy\">\n <CopyIcon className=\"size-4\" />\n </AiMessageAction>\n <AiMessageAction tooltip=\"Retry\">\n <ArrowCounterClockwiseIcon className=\"size-4\" />\n </AiMessageAction>\n </AiMessageActions>\n </AiMessageToolbar>\n </AiMessage>\n </div>",
466
+ "<AiMessage from=\"user\">\n <AiMessageContent>Can you summarise this document?</AiMessageContent>\n </AiMessage>",
467
+ "<AiMessage from=\"assistant\">\n <AiMessageContent>\n <AiResponse>\n {\n \"Here is the summary you requested. The document covers three main topics: **architecture**, **deployment**, and **monitoring**.\"\n }\n </AiResponse>\n </AiMessageContent>\n </AiMessage>"
468
+ ],
435
469
  "colors": [
436
470
  "bg-sf-control",
437
471
  "bg-sf-overlay",
@@ -515,7 +549,11 @@
515
549
  "optional": true
516
550
  }
517
551
  },
518
- "examples": [],
552
+ "examples": [
553
+ "<AiMissionHeader\n title=\"Refactor auth module\"\n taskList={{\n title: \"Refactor auth module\",\n tasks: [\n {\n id: \"t1\",\n content: \"Explore authentication codebase\",\n status: \"completed\",\n priority: \"high\",\n },\n {\n id: \"t2\",\n content: \"Identify deprecated patterns\",\n status: \"completed\",\n priority: \"high\",\n },\n {\n id: \"t3\",\n content: \"Write updated auth helpers\",\n status: \"in_progress\",\n priority: \"medium\",\n },\n {\n id: \"t4\",\n content: \"Update all consumers\",\n status: \"pending\",\n priority: \"medium\",\n },\n {\n id: \"t5\",\n content: \"Update tests\",\n status: \"pending\",\n priority: \"low\",\n },\n ],\n }}\n usage={{\n inputTokens: 12_480,\n outputTokens: 3256,\n totalTokens: 15_736,\n cost: 0.04,\n }}\n activeAgentCount={2}\n totalAgentCount={4}\n startedAt={startedAt}\n isRunning\n />",
554
+ "<AiMissionHeader\n title=\"Deploy to production\"\n taskList={{\n tasks: [\n {\n id: \"t1\",\n content: \"Run tests\",\n status: \"completed\",\n priority: \"high\",\n },\n {\n id: \"t2\",\n content: \"Build artifacts\",\n status: \"completed\",\n priority: \"high\",\n },\n {\n id: \"t3\",\n content: \"Deploy to staging\",\n status: \"completed\",\n priority: \"medium\",\n },\n {\n id: \"t4\",\n content: \"Smoke test\",\n status: \"completed\",\n priority: \"medium\",\n },\n {\n id: \"t5\",\n content: \"Deploy to production\",\n status: \"completed\",\n priority: \"high\",\n },\n ],\n }}\n usage={{ totalTokens: 28_400, cost: 0.12 }}\n activeAgentCount={0}\n totalAgentCount={3}\n startedAt={startedAt}\n endedAt={endedAt}\n isRunning={false}\n />",
555
+ "<AiMissionHeader\n title=\"Analyze codebase\"\n activeAgentCount={1}\n totalAgentCount={2}\n startedAt={startedAt}\n isRunning\n variant=\"compact\"\n />"
556
+ ],
519
557
  "colors": [
520
558
  "bg-sf-base",
521
559
  "bg-sf-brand",
@@ -569,7 +607,9 @@
569
607
  "optional": true
570
608
  }
571
609
  },
572
- "examples": [],
610
+ "examples": [
611
+ "<div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <Text variant=\"secondary\" size=\"sm\">\n Rolling window of 3 rows while streaming. Collapses to a single frozen\n line when complete.\n </Text>\n <Button\n onClick={() => setRunId((n) => n + 1)}\n size=\"sm\"\n variant=\"ghost\"\n >\n Run again\n </Button>\n </div>\n <div className=\"min-h-[6rem] rounded-md border border-sf-line/40 bg-sf-base/40 p-3\">\n <AiPartGroup\n complete={complete}\n groupKey={`activity-demo-${runId}`}\n max={3}\n title=\"Investigating failing auth tests\"\n >\n {steps.map((s) =>\n s.kind === \"tool\" ? (\n <AiToolCall\n duration={s.duration}\n key={s.part.toolCallId}\n part={s.part}\n variant=\"ephemeral\"\n />\n ) : (\n <AiReasoning\n duration={s.duration}\n isStreaming={s.isStreaming}\n key={s.id}\n part={{ text: s.text }}\n variant=\"ephemeral\"\n />\n )\n )}\n </AiPartGroup>\n </div>\n </div>"
612
+ ],
573
613
  "colors": [
574
614
  "bg-sf-tint",
575
615
  "border-sf-line",
@@ -649,7 +689,10 @@
649
689
  "optional": true
650
690
  }
651
691
  },
652
- "examples": [],
692
+ "examples": [
693
+ "<div className=\"w-full max-w-md\">\n <AiQuestion\n questionId=\"q-demo-1\"\n question=\"How should I handle the failing tests?\"\n header=\"Decision needed\"\n status={status}\n answeredWith={answer}\n options={[\n {\n label: \"Fix them\",\n description: \"Update the test expectations to match new behavior\",\n },\n {\n label: \"Skip them\",\n description: \"Mark as skipped for now and create a ticket\",\n },\n {\n label: \"Delete them\",\n description: \"Remove outdated tests entirely\",\n },\n ]}\n allowCustom\n onAnswer={(_id, ans) => {\n setAnswer(ans);\n setStatus(\"answered\");\n }}\n />\n </div>",
694
+ "<div className=\"w-full max-w-md\">\n <AiQuestion\n questionId=\"q-demo-2\"\n question=\"What should the commit message be for these changes?\"\n status={status}\n answeredWith={answer}\n allowCustom\n onAnswer={(_id, ans) => {\n setAnswer(ans);\n setStatus(\"answered\");\n }}\n />\n </div>"
695
+ ],
653
696
  "colors": [
654
697
  "bg-sf-base",
655
698
  "bg-sf-brand",
@@ -756,7 +799,15 @@
756
799
  "optional": true
757
800
  }
758
801
  },
759
- "examples": [],
802
+ "examples": [
803
+ "<AiReasoning\n part={{ text: SAMPLE_REASONING }}\n isStreaming={false}\n duration={3}\n defaultExpanded\n />",
804
+ "<AiReasoning\n part={{ text: \"Analysing context and forming a response...\" }}\n isStreaming\n />",
805
+ "<AiReasoning\n variant=\"inline\"\n part={{ text: SAMPLE_REASONING }}\n isStreaming={false}\n />",
806
+ "<AiReasoning\n variant=\"minimal\"\n part={{ text: SAMPLE_REASONING }}\n isStreaming={false}\n />",
807
+ "<AiReasoning\n part={{ text: RICH_MARKDOWN_REASONING }}\n isStreaming={false}\n duration={5}\n defaultExpanded\n />",
808
+ "<div className=\"flex flex-col gap-3\">\n <div className=\"flex items-center justify-between gap-3\">\n <Text variant=\"secondary\" size=\"sm\">\n Reasoning row evaporates 800ms after streaming ends.\n </Text>\n <Button\n onClick={() => setRunId((n) => n + 1)}\n size=\"sm\"\n variant=\"ghost\"\n >\n Think again\n </Button>\n </div>\n <div\n className={\n \"min-h-[3.5rem] rounded-md border border-sf-line/40 bg-sf-base/40 p-3\"\n }\n >\n <AiReasoning\n // `key` ensures each replay re-mounts to reset the dismiss state.\n key={runId}\n variant=\"ephemeral\"\n part={{\n text: \"**Reviewing diff** — checking for breaking changes in the migration.\",\n }}\n isStreaming={isStreaming}\n />\n </div>\n </div>",
809
+ "<AiReasoningGroup\n parts={[\n { text: \"**Step 1** — Understood the user intent and context.\" },\n { text: \"**Step 2** — Reviewed relevant data and constraints.\" },\n { text: \"**Step 3** — Formulated the final response structure.\" },\n ]}\n isStreaming={false}\n totalDuration={7}\n defaultExpanded\n />"
810
+ ],
760
811
  "colors": [
761
812
  "bg-sf-tint",
762
813
  "border-sf-line",
@@ -780,7 +831,13 @@
780
831
  "description": "Child elements"
781
832
  }
782
833
  },
783
- "examples": [],
834
+ "examples": [
835
+ "<AiResponse>{MARKDOWN_LIKE}</AiResponse>",
836
+ "<AiResponse>The capital of France is Paris.</AiResponse>",
837
+ "<AiResponse>{MARKDOWN_WITH_CODE}</AiResponse>",
838
+ "<AiResponse isAnimating={isAnimating}>{text}</AiResponse>",
839
+ "<div className=\"flex w-full flex-col gap-4\">\n <AiResponse\n components={{ a: LinkComponent } as Components}\n linkSafety={{ enabled: false }}\n >\n {DEEP_LINK_MARKDOWN}\n </AiResponse>\n {activeFile && (\n <div className=\"rounded-lg border border-sf-brand/30 bg-sf-brand/10 px-3 py-2 text-sm text-sf-default\">\n <span className=\"text-sf-subtle\">Opened file:</span>{\" \"}\n <code className=\"font-mono text-sf-brand\">{activeFile}</code>\n <button\n onClick={() => setActiveFile(null)}\n className=\"ml-3 text-xs text-sf-subtle hover:text-sf-default\"\n >\n Dismiss\n </button>\n </div>\n )}\n </div>"
840
+ ],
784
841
  "colors": ["text-sf-default"]
785
842
  },
786
843
  "AiShimmer": {
@@ -816,7 +873,11 @@
816
873
  "description": "Shimmer width multiplier relative to text length."
817
874
  }
818
875
  },
819
- "examples": [],
876
+ "examples": [
877
+ "<AiShimmer>Thinking...</AiShimmer>",
878
+ "<p className=\"text-sf-default text-sm\">\n The AI is{\" \"}\n <AiShimmer as=\"span\" duration={1.5}>\n generating a response\n </AiShimmer>\n .\n </p>",
879
+ "<AiShimmer duration={4}>Analysing your request...</AiShimmer>"
880
+ ],
820
881
  "colors": []
821
882
  },
822
883
  "AiStatusBadge": {
@@ -875,7 +936,12 @@
875
936
  "optional": true
876
937
  }
877
938
  },
878
- "examples": [],
939
+ "examples": [
940
+ "<AiStatusBadge\n icon={MagnifyingGlassIcon}\n label=\"web_search\"\n status=\"idle\"\n />",
941
+ "<div className=\"flex flex-wrap gap-2\">\n <AiStatusBadge icon={GlobeIcon} label=\"search_web\" status=\"idle\" />\n <AiStatusBadge icon={GlobeIcon} label=\"search_web\" status=\"running\" />\n <AiStatusBadge icon={GlobeIcon} label=\"search_web\" status=\"success\" />\n <AiStatusBadge icon={GlobeIcon} label=\"search_web\" status=\"error\" />\n </div>",
942
+ "<div className=\"flex flex-wrap gap-2\">\n <AiStatusBadge\n icon={DatabaseIcon}\n label=\"query_db\"\n info=\"3/5\"\n status=\"running\"\n />\n <AiStatusBadge\n icon={BrainIcon}\n label=\"analyse\"\n info=\"done\"\n status=\"success\"\n />\n </div>",
943
+ "<div className=\"flex flex-wrap gap-2\">\n <AiStatusBadge label=\"processing\" status=\"running\" />\n <AiStatusBadge label=\"complete\" status=\"success\" />\n </div>"
944
+ ],
879
945
  "colors": [
880
946
  "bg-sf-tint",
881
947
  "text-sf-brand",
@@ -900,7 +966,9 @@
900
966
  "description": "Child elements"
901
967
  }
902
968
  },
903
- "examples": [],
969
+ "examples": [
970
+ "<p className=\"max-w-sm text-sf-default text-sm\">\n {displayed}\n {streaming && (\n <span className=\"ml-0.5 inline-block h-4 w-0.5 animate-pulse bg-sf-brand\" />\n )}\n </p>"
971
+ ],
904
972
  "colors": []
905
973
  },
906
974
  "AiSubagent": {
@@ -978,12 +1046,15 @@
978
1046
  "optional": true
979
1047
  }
980
1048
  },
981
- "examples": [],
1049
+ "examples": [
1050
+ "<div className=\"w-full max-w-lg\">\n <AiSubagent\n name=\"Explore\"\n agentType=\"explore\"\n status=\"running\"\n modelId=\"claude-haiku-3.5\"\n defaultExpanded\n >\n <div className=\"flex flex-col gap-1.5 text-sm text-sf-subtle\">\n <p>Searching codebase for authentication patterns...</p>\n <div className=\"flex items-center gap-2 border-l-2 border-sf-fill py-1 pl-2 text-xs\">\n <span className=\"text-sf-brand\">Glob</span>\n <span className=\"text-sf-subtle\">src/**/*auth*</span>\n </div>\n <div className=\"flex items-center gap-2 border-l-2 border-sf-fill py-1 pl-2 text-xs\">\n <span className=\"text-sf-brand\">Read</span>\n <span className=\"text-sf-subtle\">src/middleware/auth.ts</span>\n </div>\n </div>\n </AiSubagent>\n </div>",
1051
+ "<div className=\"w-full max-w-lg\">\n <AiSubagent\n name=\"Execute\"\n agentType=\"execute\"\n status=\"completed\"\n modelId=\"claude-sonnet-4\"\n duration={12400}\n defaultExpanded={false}\n >\n <div className=\"text-sm text-sf-subtle\">\n <p>Refactored 3 files, added 2 new tests. All tests passing.</p>\n </div>\n </AiSubagent>\n </div>",
1052
+ "<div className=\"w-full max-w-lg\">\n <AiSubagent\n name=\"Plan\"\n agentType=\"plan\"\n status=\"completed\"\n modelId=\"claude-sonnet-4\"\n duration={28000}\n defaultExpanded\n >\n <div className=\"flex flex-col gap-2\">\n <p className=\"text-sm text-sf-subtle\">\n Breaking down the migration into subtasks...\n </p>\n <AiSubagent\n name=\"Explore\"\n agentType=\"explore\"\n status=\"completed\"\n modelId=\"claude-haiku-3.5\"\n duration={4200}\n defaultExpanded={false}\n >\n <p className=\"text-sm text-sf-subtle\">\n Found 12 files using deprecated API.\n </p>\n </AiSubagent>\n <AiSubagent\n name=\"Execute\"\n agentType=\"execute\"\n status=\"running\"\n modelId=\"claude-sonnet-4\"\n defaultExpanded\n >\n <p className=\"text-sm text-sf-subtle\">\n Updating import paths in batch 1/3...\n </p>\n </AiSubagent>\n </div>\n </AiSubagent>\n </div>"
1053
+ ],
982
1054
  "colors": [
983
1055
  "bg-sf-tint",
984
1056
  "text-sf-brand",
985
1057
  "text-sf-danger",
986
- "text-sf-default",
987
1058
  "text-sf-subtle",
988
1059
  "text-sf-success"
989
1060
  ]
@@ -1063,7 +1134,10 @@
1063
1134
  "optional": true
1064
1135
  }
1065
1136
  },
1066
- "examples": [],
1137
+ "examples": [
1138
+ "<div className=\"w-full max-w-sm\">\n <AiTaskList title=\"Agent tasks\" tasks={tasks} />\n </div>",
1139
+ "<div className=\"w-full max-w-sm\">\n <AiTaskList title=\"Cleanup tasks\" tasks={tasks} />\n </div>"
1140
+ ],
1067
1141
  "colors": [
1068
1142
  "bg-sf-brand",
1069
1143
  "bg-sf-danger",
@@ -1135,7 +1209,11 @@
1135
1209
  "optional": true
1136
1210
  }
1137
1211
  },
1138
- "examples": [],
1212
+ "examples": [
1213
+ "<AiTimeline\n timeOrigin={T0}\n pixelsPerSecond={25}\n showNowMarker\n nowMs={nowMs}\n >\n <AiTimelineLane\n label=\"Main\"\n agentType=\"main\"\n status=\"running\"\n modelId=\"claude-sonnet-4\"\n blocks={mainBlocks}\n timeOrigin={T0}\n nowMs={nowMs}\n pxPerMs={pxPerMs}\n />\n <AiTimelineLane\n label=\"Explore\"\n agentType=\"explore\"\n status=\"completed\"\n modelId=\"claude-haiku-3.5\"\n blocks={exploreBlocks}\n timeOrigin={T0}\n nowMs={nowMs}\n pxPerMs={pxPerMs}\n />\n <AiTimelineLane\n label=\"Plan\"\n agentType=\"plan\"\n status=\"completed\"\n modelId=\"claude-sonnet-4\"\n blocks={planBlocks}\n timeOrigin={T0}\n nowMs={nowMs}\n pxPerMs={pxPerMs}\n />\n <AiTimelineLane\n label=\"Execute\"\n agentType=\"execute\"\n status=\"running\"\n modelId=\"claude-sonnet-4\"\n blocks={executeBlocks}\n timeOrigin={T0}\n nowMs={nowMs}\n pxPerMs={pxPerMs}\n />\n </AiTimeline>",
1214
+ "<AiTimeline\n timeOrigin={T0}\n pixelsPerSecond={25}\n showNowMarker\n nowMs={nowMs}\n >\n <AiTimelineLane\n label=\"Explore\"\n agentType=\"explore\"\n status=\"completed\"\n blocks={exploreBlocks}\n timeOrigin={T0}\n nowMs={nowMs}\n pxPerMs={pxPerMs}\n density=\"compact\"\n />\n <AiTimelineLane\n label=\"Execute\"\n agentType=\"execute\"\n status=\"running\"\n blocks={executeBlocks}\n timeOrigin={T0}\n nowMs={nowMs}\n pxPerMs={pxPerMs}\n density=\"compact\"\n />\n </AiTimeline>",
1215
+ "<AiTimeline\n timeOrigin={t}\n pixelsPerSecond={30}\n showNowMarker={false}\n nowMs={nowMs}\n >\n <AiTimelineLane\n label=\"Agent\"\n blocks={allTypeBlocks}\n timeOrigin={t}\n nowMs={nowMs}\n pxPerMs={pxPerMs}\n />\n </AiTimeline>"
1216
+ ],
1139
1217
  "colors": [
1140
1218
  "bg-sf-base",
1141
1219
  "bg-sf-brand",
@@ -1312,7 +1390,10 @@
1312
1390
  "optional": true
1313
1391
  }
1314
1392
  },
1315
- "examples": [],
1393
+ "examples": [
1394
+ "<div className=\"w-full max-w-md rounded-lg border border-sf-line\">\n <AiUsageBar\n inputTokens={12480}\n outputTokens={3256}\n cost={0.04}\n modelId=\"claude-sonnet-4\"\n />\n </div>",
1395
+ "<div className=\"w-full max-w-sm rounded-lg border border-sf-line\">\n <AiUsageBar inputTokens={850} outputTokens={124} />\n </div>"
1396
+ ],
1316
1397
  "colors": ["text-sf-inactive", "text-sf-subtle"]
1317
1398
  },
1318
1399
  "Badge": {
@@ -1403,7 +1484,25 @@
1403
1484
  "optional": true
1404
1485
  }
1405
1486
  },
1406
- "examples": [],
1487
+ "examples": [
1488
+ "<div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"primary\">Primary</Badge>\n <Badge variant=\"secondary\">Secondary</Badge>\n <Badge variant=\"destructive\">Destructive</Badge>\n <Badge variant=\"outline\">Outline</Badge>\n <Badge variant=\"beta\">Beta</Badge>\n <Badge variant=\"success\">Success</Badge>\n <Badge variant=\"warning\">Warning</Badge>\n <Badge variant=\"info\">Info</Badge>\n <Badge variant=\"ghost\">Ghost</Badge>\n </div>",
1489
+ "<Badge variant=\"primary\">Primary</Badge>",
1490
+ "<Badge variant=\"secondary\">Secondary</Badge>",
1491
+ "<Badge variant=\"destructive\">Destructive</Badge>",
1492
+ "<Badge variant=\"outline\">Outline</Badge>",
1493
+ "<Badge variant=\"beta\">Beta</Badge>",
1494
+ "<Badge variant=\"success\">Success</Badge>",
1495
+ "<Badge variant=\"warning\">Warning</Badge>",
1496
+ "<Badge variant=\"info\">Info</Badge>",
1497
+ "<Badge variant=\"ghost\">Ghost</Badge>",
1498
+ "<p className=\"flex items-center gap-2\">\n Workers\n <Badge variant=\"beta\">Beta</Badge>\n </p>",
1499
+ "<div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"success\" icon={CheckCircleIcon}>\n Verified\n </Badge>\n <Badge variant=\"secondary\" icon={LightningIcon}>\n Boosted\n </Badge>\n <Badge variant=\"outline\" icon={TagIcon} iconPosition=\"right\">\n Tagged\n </Badge>\n </div>",
1500
+ "<div className=\"flex flex-wrap items-center gap-2\">\n {tags.map((tag) => (\n <Badge\n key={tag}\n variant=\"secondary\"\n onDismiss={() => setTags((t) => t.filter((v) => v !== tag))}\n >\n {tag}\n </Badge>\n ))}\n {tags.length === 0 && (\n <span className=\"text-sm text-sf-subtle\">All tags removed</span>\n )}\n </div>",
1501
+ "<div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"secondary\" loading>\n Syncing\n </Badge>\n <Badge variant=\"info\" loading>\n Deploying\n </Badge>\n </div>",
1502
+ "<div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"outline\" dot=\"green\">\n Online\n </Badge>\n <Badge variant=\"outline\" dot=\"red\">\n Offline\n </Badge>\n <Badge variant=\"outline\" dot=\"yellow\">\n Degraded\n </Badge>\n <Badge variant=\"outline\" dot=\"blue\">\n Deploying\n </Badge>\n </div>",
1503
+ "<div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"secondary\" onClick={handleBadgeClick}>\n Clickable\n </Badge>\n <Badge variant=\"info\" href=\"https://example.com\">\n Link badge\n </Badge>\n </div>",
1504
+ "<TooltipProvider>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Badge variant=\"success\" tooltip=\"Deployed 2 hours ago\" dot=\"green\">\n Production\n </Badge>\n <Badge variant=\"outline\" tooltip=\"3 of 5 tasks complete\">\n 3/5\n </Badge>\n </div>\n </TooltipProvider>"
1505
+ ],
1407
1506
  "colors": [
1408
1507
  "bg-sf-brand",
1409
1508
  "bg-sf-contrast",
@@ -1468,7 +1567,14 @@
1468
1567
  "description": "Additional CSS classes merged via `cn()`."
1469
1568
  }
1470
1569
  },
1471
- "examples": [],
1570
+ "examples": [
1571
+ "<div className=\"space-y-3\">\n <Banner>This is an informational banner.</Banner>\n <Banner variant=\"alert\">This is an alert banner.</Banner>\n <Banner variant=\"error\">This is an error banner.</Banner>\n </div>",
1572
+ "<Banner>This is an informational banner.</Banner>",
1573
+ "<Banner variant=\"alert\">Your session will expire soon.</Banner>",
1574
+ "<Banner variant=\"error\">We couldn't save your changes.</Banner>",
1575
+ "<Banner icon={<WarningCircleIcon />} variant=\"alert\">\n Review your billing information.\n </Banner>",
1576
+ "<Banner icon={<InfoIcon />}>\n <Text DANGEROUS_className=\"text-inherit\">\n This banner supports <strong>custom content</strong> with Text.\n </Text>\n </Banner>"
1577
+ ],
1472
1578
  "colors": [
1473
1579
  "bg-sf-danger",
1474
1580
  "bg-sf-danger-tint",
@@ -1517,7 +1623,13 @@
1517
1623
  "description": "Additional CSS classes merged via `cn()`."
1518
1624
  }
1519
1625
  },
1520
- "examples": [],
1626
+ "examples": [
1627
+ "<Breadcrumbs>\n <Breadcrumbs.Link href=\"#\">Home</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Link href=\"#\">Docs</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>Breadcrumbs</Breadcrumbs.Current>\n </Breadcrumbs>",
1628
+ "<Breadcrumbs>\n <Breadcrumbs.Link href=\"#\" icon={<HouseIcon size={16} />}>\n Home\n </Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Link href=\"#\">Projects</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>Current Project</Breadcrumbs.Current>\n </Breadcrumbs>",
1629
+ "<Breadcrumbs>\n <Breadcrumbs.Link href=\"#\" icon={<HouseIcon size={16} />}>\n Home\n </Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Link href=\"#\">Docs</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current loading />\n </Breadcrumbs>",
1630
+ "<Breadcrumbs>\n <Breadcrumbs.Current icon={<HouseIcon size={16} />}>\n Worker Analytics\n </Breadcrumbs.Current>\n </Breadcrumbs>",
1631
+ "<Breadcrumbs>\n <Breadcrumbs.Link href=\"#\">Home</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>Breadcrumbs</Breadcrumbs.Current>\n <Breadcrumbs.Clipboard text=\"#\" />\n </Breadcrumbs>"
1632
+ ],
1521
1633
  "colors": ["text-sf-inactive", "text-sf-subtle", "text-sf-success"],
1522
1634
  "subComponents": {
1523
1635
  "Link": {
@@ -1705,7 +1817,20 @@
1705
1817
  "optional": true
1706
1818
  }
1707
1819
  },
1708
- "examples": [],
1820
+ "examples": [
1821
+ "<div className=\"flex flex-wrap items-center gap-2\">\n <Button variant=\"secondary\">Button</Button>\n <Button\n variant=\"secondary\"\n shape=\"square\"\n icon={PlusIcon}\n aria-label=\"Add\"\n />\n </div>",
1822
+ "<Button variant=\"primary\">Primary</Button>",
1823
+ "<Button variant=\"secondary\">Secondary</Button>",
1824
+ "<Button variant=\"ghost\">Ghost</Button>",
1825
+ "<Button variant=\"destructive\">Destructive</Button>",
1826
+ "<Button variant=\"outline\">Outline</Button>",
1827
+ "<Button variant=\"secondary-destructive\">Secondary Destructive</Button>",
1828
+ "<div className=\"flex flex-wrap items-center gap-3\">\n <Button size=\"xs\" variant=\"secondary\">\n Extra Small\n </Button>\n <Button size=\"sm\" variant=\"secondary\">\n Small\n </Button>\n <Button size=\"base\" variant=\"secondary\">\n Base\n </Button>\n <Button size=\"lg\" variant=\"secondary\">\n Large\n </Button>\n </div>",
1829
+ "<Button variant=\"secondary\" icon={PlusIcon}>\n Create Worker\n </Button>",
1830
+ "<div className=\"flex flex-wrap items-center gap-3\">\n <Button\n variant=\"secondary\"\n shape=\"square\"\n icon={PlusIcon}\n aria-label=\"Add item\"\n />\n <Button\n variant=\"secondary\"\n shape=\"circle\"\n icon={PlusIcon}\n aria-label=\"Add item\"\n />\n </div>",
1831
+ "<Button variant=\"primary\" loading>\n Loading...\n </Button>",
1832
+ "<Button variant=\"secondary\" disabled>\n Disabled\n </Button>"
1833
+ ],
1709
1834
  "colors": [
1710
1835
  "bg-sf-base",
1711
1836
  "bg-sf-brand",
@@ -1798,7 +1923,17 @@
1798
1923
  "description": "Callback when checkbox value changes"
1799
1924
  }
1800
1925
  },
1801
- "examples": [],
1926
+ "examples": [
1927
+ "<Checkbox\n label=\"Accept terms and conditions\"\n checked={checked}\n onCheckedChange={setChecked}\n />",
1928
+ "<Checkbox\n label=\"Enable notifications\"\n checked={checked}\n onCheckedChange={setChecked}\n />",
1929
+ "<Checkbox label=\"I agree\" checked={checked} onCheckedChange={setChecked} />",
1930
+ "<Checkbox\n label=\"Select all\"\n indeterminate={indeterminate}\n onCheckedChange={setIndeterminate}\n />",
1931
+ "<Checkbox\n label=\"Remember me\"\n controlFirst={false}\n checked={checked}\n onCheckedChange={setChecked}\n />",
1932
+ "<Checkbox label=\"Disabled option\" disabled />",
1933
+ "<Checkbox label=\"Invalid option\" variant=\"error\" />",
1934
+ "<Checkbox.Group\n legend=\"Email preferences\"\n description=\"Choose how you'd like to receive updates\"\n value={preferences}\n onValueChange={setPreferences}\n >\n <Checkbox.Item value=\"email\" label=\"Email notifications\" />\n <Checkbox.Item value=\"sms\" label=\"SMS notifications\" />\n <Checkbox.Item value=\"push\" label=\"Push notifications\" />\n </Checkbox.Group>",
1935
+ "<Checkbox.Group\n legend=\"Required preferences\"\n error=\"Please select at least one notification method\"\n value={[]}\n onValueChange={() => {}}\n >\n <Checkbox.Item value=\"email\" label=\"Email\" variant=\"error\" />\n <Checkbox.Item value=\"sms\" label=\"SMS\" variant=\"error\" />\n </Checkbox.Group>"
1936
+ ],
1802
1937
  "colors": [
1803
1938
  "bg-sf-base",
1804
1939
  "bg-sf-contrast",
@@ -1932,7 +2067,13 @@
1932
2067
  "description": "Accessible labels for i18n."
1933
2068
  }
1934
2069
  },
1935
- "examples": [],
2070
+ "examples": [
2071
+ "<ClipboardText text=\"0c239dd2\" />",
2072
+ "<ClipboardText text=\"abc123\" />",
2073
+ "<ClipboardText text=\"sk_live_51H8...\" />",
2074
+ "<ClipboardText text=\"https://example.com/very/long/url/path\" />",
2075
+ "<ClipboardText\n text=\"npx sf add button\"\n tooltip={{ copiedText: \"Copied!\", side: \"top\", text: \"Copy\" }}\n />"
2076
+ ],
1936
2077
  "colors": [
1937
2078
  "bg-sf-base",
1938
2079
  "border-sf-line",
@@ -2046,7 +2187,13 @@
2046
2187
  "description": "Additional CSS classes merged via `cn()`."
2047
2188
  }
2048
2189
  },
2049
- "examples": [],
2190
+ "examples": [
2191
+ "<CodeBlock\n lang=\"tsx\"\n code={`const greeting = \"Hello, World!\";\nconsole.log(greeting);`}\n />",
2192
+ "<CodeBlock\n lang=\"tsx\"\n code={`interface User {\n id: string;\n name: string;\n email: string;\n}\n\nconst user: User = {\n id: \"1\",\n name: \"John Doe\",\n email: \"john@example.com\"\n};`}\n />",
2193
+ "<CodeBlock\n lang=\"bash\"\n code={`npm install @signalflare-ai/ui\nbun add @signalflare-ai/ui`}\n />",
2194
+ "<CodeBlock\n lang=\"jsonc\"\n code={`{\n \"name\": \"sf\",\n \"version\": \"1.0.0\",\n \"dependencies\": {\n \"react\": \"^19.0.0\"\n }\n}`}\n />",
2195
+ "<Code\n lang=\"bash\"\n code=\"export API_KEY={{apiKey}}\"\n values={{\n apiKey: { highlight: true, value: \"sk_live_123\" },\n }}\n />"
2196
+ ],
2050
2197
  "colors": ["bg-sf-recessed", "border-sf-line", "text-sf-default"],
2051
2198
  "subComponents": {
2052
2199
  "Block": {
@@ -2097,7 +2244,11 @@
2097
2244
  "description": "Callback when collapsed state changes"
2098
2245
  }
2099
2246
  },
2100
- "examples": [],
2247
+ "examples": [
2248
+ "<div className=\"w-full\">\n <Collapsible label=\"What is SF?\" open={isOpen} onOpenChange={setIsOpen}>\n A minimal, composable component library for building modern interfaces.\n </Collapsible>\n </div>",
2249
+ "<div className=\"w-full\">\n <Collapsible label=\"What is SF?\" open={isOpen} onOpenChange={setIsOpen}>\n A minimal, composable component library for building modern interfaces.\n </Collapsible>\n </div>",
2250
+ "<div className=\"w-full space-y-2\">\n <Collapsible label=\"What is SF?\" open={open1} onOpenChange={setOpen1}>\n A minimal, composable component library for building modern interfaces.\n </Collapsible>\n <Collapsible\n label=\"How do I use it?\"\n open={open2}\n onOpenChange={setOpen2}\n >\n Install the components and import them into your project.\n </Collapsible>\n <Collapsible\n label=\"Is it open source?\"\n open={open3}\n onOpenChange={setOpen3}\n >\n Check the repository for license information.\n </Collapsible>\n </div>"
2251
+ ],
2101
2252
  "colors": ["border-sf-fill", "text-sf-link"]
2102
2253
  },
2103
2254
  "Combobox": {
@@ -2176,7 +2327,14 @@
2176
2327
  "description": "Custom equality function for comparing items"
2177
2328
  }
2178
2329
  },
2179
- "examples": [],
2330
+ "examples": [
2331
+ "<Combobox\n value={value}\n onValueChange={(v) => setValue(v as string | null)}\n items={fruits}\n >\n <Combobox.TriggerInput placeholder=\"Please select\" />\n <Combobox.Content>\n <Combobox.Empty />\n <Combobox.List>\n {(item: string) => (\n <Combobox.Item key={item} value={item}>\n {item}\n </Combobox.Item>\n )}\n </Combobox.List>\n </Combobox.Content>\n </Combobox>",
2332
+ "<Combobox\n value={value}\n onValueChange={(v) => setValue(v as Language)}\n items={languages}\n >\n <Combobox.TriggerValue className=\"w-[200px]\" />\n <Combobox.Content>\n <Combobox.Input placeholder=\"Search languages\" />\n <Combobox.Empty />\n <Combobox.List>\n {(item: Language) => (\n <Combobox.Item key={item.value} value={item}>\n {item.emoji} {item.label}\n </Combobox.Item>\n )}\n </Combobox.List>\n </Combobox.Content>\n </Combobox>",
2333
+ "<Combobox\n value={value}\n onValueChange={(v) => setValue(v as ServerLocation | null)}\n items={servers}\n >\n <Combobox.TriggerInput\n className=\"w-[200px]\"\n placeholder=\"Select server\"\n />\n <Combobox.Content>\n <Combobox.Empty />\n <Combobox.List>\n {(group: ServerLocationGroup) => (\n <Combobox.Group key={group.value} items={group.items}>\n <Combobox.GroupLabel>{group.value}</Combobox.GroupLabel>\n <Combobox.Collection>\n {(item: ServerLocation) => (\n <Combobox.Item key={item.value} value={item}>\n {item.label}\n </Combobox.Item>\n )}\n </Combobox.Collection>\n </Combobox.Group>\n )}\n </Combobox.List>\n </Combobox.Content>\n </Combobox>",
2334
+ "<div className=\"flex gap-2\">\n <Combobox\n value={value}\n onValueChange={setValue}\n items={bots}\n isItemEqualToValue={(bot: BotItem, selected: BotItem) =>\n bot.value === selected.value\n }\n multiple\n >\n <Combobox.TriggerMultipleWithInput\n className=\"w-[400px]\"\n placeholder=\"Select bots\"\n renderItem={(selected: BotItem) => (\n <Combobox.Chip key={selected.value}>{selected.label}</Combobox.Chip>\n )}\n inputSide=\"right\"\n />\n <Combobox.Content className=\"max-h-[200px] min-w-auto overflow-y-auto\">\n <Combobox.Empty />\n <Combobox.List>\n {(item: BotItem) => (\n <Combobox.Item key={item.value} value={item}>\n <div className=\"flex gap-2\">\n <Text>{item.label}</Text>\n <Text variant=\"secondary\">{item.author}</Text>\n </div>\n </Combobox.Item>\n )}\n </Combobox.List>\n </Combobox.Content>\n </Combobox>\n <Button variant=\"primary\">Submit</Button>\n </div>",
2335
+ "<div className=\"w-80\">\n <Combobox\n items={databases}\n value={value}\n onValueChange={setValue}\n label=\"Database\"\n description=\"Select your preferred database\"\n >\n <Combobox.TriggerInput placeholder=\"Select database\" />\n <Combobox.Content>\n <Combobox.Empty />\n <Combobox.List>\n {(item: DatabaseItem) => (\n <Combobox.Item key={item.value} value={item}>\n {item.label}\n </Combobox.Item>\n )}\n </Combobox.List>\n </Combobox.Content>\n </Combobox>\n </div>",
2336
+ "<div className=\"w-80\">\n <Combobox\n items={databases}\n value={value}\n onValueChange={setValue}\n label=\"Database\"\n error={{ match: true, message: \"Please select a database\" }}\n >\n <Combobox.TriggerInput placeholder=\"Select database\" />\n <Combobox.Content>\n <Combobox.Empty />\n <Combobox.List>\n {(item: DatabaseItem) => (\n <Combobox.Item key={item.value} value={item}>\n {item.label}\n </Combobox.Item>\n )}\n </Combobox.List>\n </Combobox.Content>\n </Combobox>\n </div>"
2337
+ ],
2180
2338
  "colors": [
2181
2339
  "bg-sf-control",
2182
2340
  "bg-sf-fill-hover",
@@ -2299,7 +2457,12 @@
2299
2457
  "description": "Child content - typically one or more Panel components"
2300
2458
  }
2301
2459
  },
2302
- "examples": [],
2460
+ "examples": [
2461
+ "<div className=\"flex flex-col items-start gap-4\">\n <Button onClick={() => setOpen(true)}>Open Command Palette</Button>\n {selectedItem && (\n <p className=\"text-sm text-sf-subtle\">\n Last selected: <span className=\"text-sf-default\">{selectedItem}</span>\n </p>\n )}\n\n <CommandPalette.Root\n open={open}\n onOpenChange={setOpen}\n items={sampleGroups}\n value={search}\n onValueChange={setSearch}\n itemToStringValue={(group) => group.label}\n onSelect={(item, { newTab }) => {\n console.log(\"Selected:\", item.title, newTab ? \"(new tab)\" : \"\");\n handleSelect(item);\n }}\n getSelectableItems={getSelectableItems}\n >\n <CommandPalette.Input placeholder=\"Type a command or search...\" />\n <CommandPalette.List>\n <CommandPalette.Results>\n {(group: CommandGroup) => (\n <CommandPalette.Group key={group.id}>\n <CommandPalette.GroupLabel>\n {group.label}\n </CommandPalette.GroupLabel>\n <CommandPalette.Items>\n {(item: CommandItem) => (\n <CommandPalette.Item\n key={item.id}\n value={item}\n onClick={() => handleSelect(item)}\n >\n <span className=\"flex items-center gap-3\">\n {item.icon && (\n <span className=\"text-sf-subtle\">{item.icon}</span>\n )}\n <span>{item.title}</span>\n </span>\n </CommandPalette.Item>\n )}\n </CommandPalette.Items>\n </CommandPalette.Group>\n )}\n </CommandPalette.Results>\n <CommandPalette.Empty>No commands found</CommandPalette.Empty>\n </CommandPalette.List>\n <CommandPalette.Footer>\n <span className=\"flex items-center gap-2\">\n <kbd className=\"rounded border border-sf-line bg-sf-base px-1.5 py-0.5 text-[10px]\">\n ↑↓\n </kbd>\n <span>Navigate</span>\n </span>\n <span className=\"flex items-center gap-2\">\n <kbd className=\"rounded border border-sf-line bg-sf-base px-1.5 py-0.5 text-[10px]\">\n ↵\n </kbd>\n <span>Select</span>\n </span>\n </CommandPalette.Footer>\n </CommandPalette.Root>\n </div>",
2462
+ "<div>\n <Button onClick={() => setOpen(true)}>Open Simple Palette</Button>\n\n <CommandPalette.Root\n open={open}\n onOpenChange={setOpen}\n items={simpleItems}\n value={search}\n onValueChange={setSearch}\n itemToStringValue={(item) => item.title}\n onSelect={(item) => {\n console.log(\"Selected:\", item.title);\n setOpen(false);\n }}\n getSelectableItems={(items) => items}\n >\n <CommandPalette.Input placeholder=\"Search actions...\" />\n <CommandPalette.List>\n <CommandPalette.Results>\n {(item: SimpleItem) => (\n <CommandPalette.Item\n key={item.id}\n value={item}\n onClick={() => {\n console.log(\"Clicked:\", item.title);\n setOpen(false);\n }}\n >\n {item.title}\n </CommandPalette.Item>\n )}\n </CommandPalette.Results>\n <CommandPalette.Empty>No actions found</CommandPalette.Empty>\n </CommandPalette.List>\n </CommandPalette.Root>\n </div>",
2463
+ "<div>\n <Button onClick={handleOpen}>Open with Loading</Button>\n\n <CommandPalette.Root\n open={open}\n onOpenChange={setOpen}\n items={loading ? [] : sampleGroups}\n value={search}\n onValueChange={setSearch}\n itemToStringValue={(group) => group.label}\n getSelectableItems={getSelectableItems}\n >\n <CommandPalette.Input placeholder=\"Search...\" />\n <CommandPalette.List>\n {loading ? (\n <CommandPalette.Loading />\n ) : (\n <>\n <CommandPalette.Results>\n {(group: CommandGroup) => (\n <CommandPalette.Group key={group.id}>\n <CommandPalette.GroupLabel>\n {group.label}\n </CommandPalette.GroupLabel>\n <CommandPalette.Items>\n {(item: CommandItem) => (\n <CommandPalette.Item\n key={item.id}\n value={item}\n onClick={() => setOpen(false)}\n >\n <span className=\"flex items-center gap-3\">\n {item.icon && (\n <span className=\"text-sf-subtle\">\n {item.icon}\n </span>\n )}\n <span>{item.title}</span>\n </span>\n </CommandPalette.Item>\n )}\n </CommandPalette.Items>\n </CommandPalette.Group>\n )}\n </CommandPalette.Results>\n <CommandPalette.Empty>No results found</CommandPalette.Empty>\n </>\n )}\n </CommandPalette.List>\n </CommandPalette.Root>\n </div>",
2464
+ "<div>\n <Button onClick={() => setOpen(true)}>Open with ResultItem</Button>\n\n <CommandPalette.Root\n open={open}\n onOpenChange={setOpen}\n items={searchResults}\n value={search}\n onValueChange={setSearch}\n itemToStringValue={(item) => item.title}\n getSelectableItems={(items) => items}\n >\n <CommandPalette.Input placeholder=\"Search documentation...\" />\n <CommandPalette.List>\n <CommandPalette.Results>\n {(item: SearchResult) => (\n <CommandPalette.ResultItem\n key={item.id}\n value={item}\n title={item.title}\n breadcrumbs={item.breadcrumbs}\n icon={item.icon}\n onClick={() => {\n console.log(\"Navigate to:\", item.title);\n setOpen(false);\n }}\n />\n )}\n </CommandPalette.Results>\n <CommandPalette.Empty>No pages found</CommandPalette.Empty>\n </CommandPalette.List>\n <CommandPalette.Footer>\n <span className=\"flex items-center gap-2\">\n <kbd className=\"rounded border border-sf-line bg-sf-base px-1.5 py-0.5 text-[10px]\">\n ↑↓\n </kbd>\n <span>Navigate</span>\n </span>\n <span className=\"flex items-center gap-2\">\n <kbd className=\"rounded border border-sf-line bg-sf-base px-1.5 py-0.5 text-[10px]\">\n ⌘↵\n </kbd>\n <span>Open in new tab</span>\n </span>\n </CommandPalette.Footer>\n </CommandPalette.Root>\n </div>"
2465
+ ],
2303
2466
  "colors": [
2304
2467
  "bg-sf-elevated",
2305
2468
  "bg-sf-overlay",
@@ -2335,7 +2498,16 @@
2335
2498
  "description": "Child elements"
2336
2499
  }
2337
2500
  },
2338
- "examples": [],
2501
+ "examples": [
2502
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <DataGrid data={sampleUsers} columns={columns} enableSorting>\n <DataGrid.Content />\n </DataGrid>\n </LayerCard.Primary>\n </LayerCard>",
2503
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <DataGrid\n data={paginatedData}\n columns={columns.slice(0, 3)}\n pageSize={pageSize}\n pageIndex={pageIndex}\n onPaginationChange={({ pageIndex: newPage }) => setPageIndex(newPage)}\n totalCount={totalCount}\n manualPagination\n >\n <DataGrid.Content />\n <DataGrid.Pagination />\n </DataGrid>\n </LayerCard.Primary>\n </LayerCard>",
2504
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <DataGrid\n data={sampleUsers.slice(0, 4)}\n columns={columns}\n enableRowSelection\n rowSelection={rowSelection}\n onRowSelectionChange={setRowSelection}\n >\n <DataGrid.Content />\n </DataGrid>\n <div className=\"border-t border-sf-line p-3 text-sm\">\n <p className=\"text-sf-subtle\">\n Selected: {Object.keys(rowSelection).length} rows\n </p>\n </div>\n </LayerCard.Primary>\n </LayerCard>",
2505
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <DataGrid\n data={sampleUsers.slice(0, 4)}\n columns={columns}\n columnVisibility={columnVisibility}\n onColumnVisibilityChange={setColumnVisibility}\n >\n <DataGrid.Toolbar className=\"p-3\">\n <DataGrid.ColumnToggle />\n </DataGrid.Toolbar>\n <DataGrid.Content />\n </DataGrid>\n </LayerCard.Primary>\n </LayerCard>",
2506
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <DataGrid data={sampleUsers} columns={columns} enableSorting>\n <DataGrid.Toolbar className=\"flex items-center justify-between p-3\">\n <span className=\"text-sm font-medium\">Users</span>\n <DataGrid.ColumnToggle />\n </DataGrid.Toolbar>\n <DataGrid.Content />\n </DataGrid>\n </LayerCard.Primary>\n </LayerCard>",
2507
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <DataGrid\n data={[]}\n columns={columns.slice(0, 3)}\n emptyState={\n <div className=\"flex flex-col items-center justify-center py-12 text-center\">\n <p className=\"text-sf-strong font-medium\">No users found</p>\n <p className=\"text-sf-subtle mt-1 text-sm\">\n Try adjusting your filters or add new users\n </p>\n </div>\n }\n >\n <DataGrid.Content />\n </DataGrid>\n </LayerCard.Primary>\n </LayerCard>",
2508
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <DataGrid\n data={[]}\n columns={columns.slice(0, 3)}\n loading\n loadingRows={3}\n >\n <DataGrid.Content />\n </DataGrid>\n </LayerCard.Primary>\n </LayerCard>",
2509
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <DataGrid\n data={sampleUsers}\n columns={resizableColumns}\n enableSorting\n enableColumnResizing\n columnResizeMode=\"onEnd\"\n >\n <DataGrid.Content />\n </DataGrid>\n </LayerCard.Primary>\n </LayerCard>"
2510
+ ],
2339
2511
  "colors": [
2340
2512
  "bg-sf-base",
2341
2513
  "bg-sf-brand",
@@ -2390,7 +2562,16 @@
2390
2562
  "description": "Child elements"
2391
2563
  }
2392
2564
  },
2393
- "examples": [],
2565
+ "examples": [
2566
+ "<div className=\"flex flex-col gap-4\">\n <DatePicker\n mode=\"single\"\n selected={date}\n onChange={(d) => {\n if (d) {\n setDate(d);\n }\n }}\n />\n <p className=\"text-sm text-sf-subtle\">\n Selected: {date ? date.toLocaleDateString() : \"None\"}\n </p>\n </div>",
2567
+ "<div className=\"flex flex-col gap-4\">\n <DatePicker\n mode=\"multiple\"\n selected={dates}\n onChange={setDates}\n max={5}\n />\n <p className=\"text-sm text-sf-subtle\">\n Selected: {dates?.length ?? 0} date(s)\n </p>\n </div>",
2568
+ "<div className=\"flex flex-col gap-4\">\n <DatePicker\n mode=\"range\"\n selected={range}\n onChange={setRange}\n numberOfMonths={2}\n />\n <p className=\"text-sm text-sf-subtle\">\n Range:{\" \"}\n {range?.from\n ? `${range.from.toLocaleDateString()} - ${range.to?.toLocaleDateString() ?? \"...\"}`\n : \"None\"}\n </p>\n </div>",
2569
+ "<div className=\"flex flex-col gap-4\">\n <DatePicker\n mode=\"range\"\n selected={range}\n onChange={setRange}\n min={3}\n max={7}\n footer={\n <span className=\"text-xs text-sf-subtle\">Select 3-7 nights</span>\n }\n />\n </div>",
2570
+ "<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"outline\" icon={CalendarDotsIcon}>\n {date ? date.toLocaleDateString() : \"Pick a date\"}\n </Button>\n </Popover.Trigger>\n <Popover.Content className=\"p-3\">\n <DatePicker mode=\"single\" selected={date} onChange={setDate} />\n </Popover.Content>\n </Popover>",
2571
+ "<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"outline\" icon={CalendarDotsIcon}>\n {formatRange()}\n </Button>\n </Popover.Trigger>\n <Popover.Content className=\"p-3\">\n <DatePicker\n mode=\"range\"\n selected={range}\n onChange={setRange}\n numberOfMonths={2}\n />\n </Popover.Content>\n </Popover>",
2572
+ "<Popover>\n <Popover.Trigger asChild>\n <Button variant=\"outline\" icon={CalendarDotsIcon}>\n {formatRange()}\n </Button>\n </Popover.Trigger>\n <Popover.Content className=\"p-0\">\n <div className=\"flex\">\n <div className=\"flex flex-col gap-1 border-r border-sf-line p-2 text-sm\">\n {presets.map((preset) => {\n const isActive = isPresetActive(preset);\n return (\n <button\n key={preset.label}\n type=\"button\"\n onClick={() => handlePresetClick(preset)}\n className={`rounded-md px-3 py-1.5 text-left whitespace-nowrap ${\n isActive\n ? \"bg-sf-bg-inverse text-sf-text-inverse\"\n : \"text-sf-strong hover:bg-sf-control\"\n }`}\n >\n {preset.label}\n </button>\n );\n })}\n </div>\n <div className=\"p-3\">\n <DatePicker\n mode=\"range\"\n selected={range}\n onChange={setRange}\n month={month}\n onMonthChange={setMonth}\n numberOfMonths={2}\n />\n </div>\n </div>\n </Popover.Content>\n </Popover>",
2573
+ "<DatePicker\n mode=\"multiple\"\n selected={dates}\n onChange={setDates}\n max={maxDays}\n disabled={unavailableDates}\n fixedWeeks\n footer={\n <p className=\"text-xs text-sf-subtle pt-2 w-full\">\n {selectedCount}/{maxDays} days selected. Grayed dates are unavailable.\n </p>\n }\n />"
2574
+ ],
2394
2575
  "colors": ["bg-sf-base"]
2395
2576
  },
2396
2577
  "DateRangePicker": {
@@ -2544,7 +2725,14 @@
2544
2725
  "default": "base"
2545
2726
  }
2546
2727
  },
2547
- "examples": [],
2728
+ "examples": [
2729
+ "<Dialog.Root>\n <Dialog.Trigger render={(p) => <Button {...p}>Click me</Button>} />\n <Dialog className=\"p-8\">\n <div className=\"mb-4 flex items-start justify-between gap-4\">\n <Dialog.Title className=\"text-2xl font-semibold\">\n Modal Title\n </Dialog.Title>\n <Dialog.Close\n aria-label=\"Close\"\n render={(props) => (\n <Button\n {...props}\n variant=\"secondary\"\n shape=\"square\"\n icon={<XIcon />}\n aria-label=\"Close\"\n />\n )}\n />\n </div>\n <Dialog.Description className=\"text-sf-subtle\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\n eiusmod tempor incididunt ut labore et dolore magna aliqua.\n </Dialog.Description>\n </Dialog>\n </Dialog.Root>",
2730
+ "<Dialog.Root>\n <Dialog.Trigger render={(p) => <Button {...p}>Delete</Button>} />\n <Dialog className=\"p-8\">\n <div className=\"mb-4 flex items-start justify-between gap-4\">\n <Dialog.Title className=\"text-2xl font-semibold\">\n Modal Title\n </Dialog.Title>\n <Dialog.Close\n aria-label=\"Close\"\n render={(props) => (\n <Button\n {...props}\n variant=\"secondary\"\n shape=\"square\"\n icon={<XIcon />}\n aria-label=\"Close\"\n />\n )}\n />\n </div>\n <Dialog.Description className=\"text-sf-subtle\">\n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do\n eiusmod tempor incididunt ut labore et dolore magna aliqua.\n </Dialog.Description>\n <div className=\"mt-8 flex justify-end gap-2\">\n <Dialog.Close\n render={(props) => (\n <Button variant=\"secondary\" {...props}>\n Cancel\n </Button>\n )}\n />\n <Dialog.Close\n render={(props) => (\n <Button variant=\"destructive\" {...props}>\n Delete\n </Button>\n )}\n />\n </div>\n </Dialog>\n </Dialog.Root>",
2731
+ "<Dialog.Root disablePointerDismissal>\n <Dialog.Trigger\n render={(p) => (\n <Button {...p} variant=\"destructive\">\n Delete Project\n </Button>\n )}\n />\n <Dialog className=\"p-8\">\n <div className=\"mb-4 flex items-center gap-3\">\n <div className=\"flex h-10 w-10 items-center justify-center rounded-full bg-sf-danger/20\">\n <WarningIcon size={20} className=\"text-sf-danger\" />\n </div>\n <Dialog.Title className=\"text-xl font-semibold\">\n Delete Project?\n </Dialog.Title>\n </div>\n <Dialog.Description className=\"text-sf-subtle\">\n This action cannot be undone. This will permanently delete the project\n and all associated data.\n </Dialog.Description>\n <div className=\"mt-8 flex justify-end gap-2\">\n <Dialog.Close\n render={(props) => (\n <Button variant=\"secondary\" {...props}>\n Cancel\n </Button>\n )}\n />\n <Dialog.Close\n render={(props) => (\n <Button variant=\"destructive\" {...props}>\n Delete\n </Button>\n )}\n />\n </div>\n </Dialog>\n </Dialog.Root>",
2732
+ "<Dialog.Root>\n <Dialog.Trigger render={(p) => <Button {...p}>Open Form</Button>} />\n <Dialog className=\"p-8\">\n <div className=\"mb-4 flex items-start justify-between gap-4\">\n <Dialog.Title className=\"text-2xl font-semibold\">\n Create Resource\n </Dialog.Title>\n <Dialog.Close\n aria-label=\"Close\"\n render={(props) => (\n <Button\n {...props}\n variant=\"secondary\"\n shape=\"square\"\n icon={<XIcon />}\n aria-label=\"Close\"\n />\n )}\n />\n </div>\n <Dialog.Description className=\"mb-4 text-sf-subtle\">\n Select a region for your new resource.\n </Dialog.Description>\n <Select\n className=\"w-full\"\n renderValue={(v) =>\n regions.find((r) => r.value === v)?.label ?? \"Select region...\"\n }\n >\n {regions.map((region) => (\n <Select.Option key={region.value} value={region.value}>\n {region.label}\n </Select.Option>\n ))}\n </Select>\n <div className=\"mt-8 flex justify-end gap-2\">\n <Dialog.Close\n render={(props) => (\n <Button variant=\"secondary\" {...props}>\n Cancel\n </Button>\n )}\n />\n <Button variant=\"primary\">Create</Button>\n </div>\n </Dialog>\n </Dialog.Root>",
2733
+ "<Dialog.Root>\n <Dialog.Trigger render={(p) => <Button {...p}>Open Form</Button>} />\n <Dialog className=\"p-8\">\n <div className=\"mb-4 flex items-start justify-between gap-4\">\n <Dialog.Title className=\"text-2xl font-semibold\">\n Create Resource\n </Dialog.Title>\n <Dialog.Close\n aria-label=\"Close\"\n render={(props) => (\n <Button\n {...props}\n variant=\"secondary\"\n shape=\"square\"\n icon={<XIcon />}\n aria-label=\"Close\"\n />\n )}\n />\n </div>\n <Dialog.Description className=\"mb-4 text-sf-subtle\">\n Search and select a region for your new resource.\n </Dialog.Description>\n <Combobox value={value} onValueChange={setValue} items={regions}>\n <Combobox.TriggerInput\n className=\"w-full\"\n placeholder=\"Search regions...\"\n />\n <Combobox.Content>\n <Combobox.Empty>No regions found</Combobox.Empty>\n <Combobox.List>\n {(item: { value: string; label: string }) => (\n <Combobox.Item key={item.value} value={item}>\n {item.label}\n </Combobox.Item>\n )}\n </Combobox.List>\n </Combobox.Content>\n </Combobox>\n <div className=\"mt-8 flex justify-end gap-2\">\n <Dialog.Close\n render={(props) => (\n <Button variant=\"secondary\" {...props}>\n Cancel\n </Button>\n )}\n />\n <Button variant=\"primary\">Create</Button>\n </div>\n </Dialog>\n </Dialog.Root>",
2734
+ "<Dialog.Root>\n <Dialog.Trigger render={(p) => <Button {...p}>Open Form</Button>} />\n <Dialog className=\"p-8\">\n <div className=\"mb-4 flex items-start justify-between gap-4\">\n <Dialog.Title className=\"text-2xl font-semibold\">\n Resource Actions\n </Dialog.Title>\n <Dialog.Close\n aria-label=\"Close\"\n render={(props) => (\n <Button\n {...props}\n variant=\"secondary\"\n shape=\"square\"\n icon={<XIcon />}\n aria-label=\"Close\"\n />\n )}\n />\n </div>\n <Dialog.Description className=\"mb-4 text-sf-subtle\">\n Choose an action for the selected resource.\n </Dialog.Description>\n <DropdownMenu>\n <DropdownMenu.Trigger render={<Button>Actions</Button>} />\n <DropdownMenu.Content>\n <DropdownMenu.Item>Edit</DropdownMenu.Item>\n <DropdownMenu.Item>Duplicate</DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item variant=\"danger\">Delete</DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu>\n <div className=\"mt-8 flex justify-end\">\n <Dialog.Close\n render={(props) => (\n <Button variant=\"secondary\" {...props}>\n Close\n </Button>\n )}\n />\n </div>\n </Dialog>\n </Dialog.Root>"
2735
+ ],
2548
2736
  "colors": [
2549
2737
  "bg-sf-elevated",
2550
2738
  "bg-sf-overlay",
@@ -2824,7 +3012,14 @@
2824
3012
  "description": "Additional CSS classes merged via `cn()`."
2825
3013
  }
2826
3014
  },
2827
- "examples": [],
3015
+ "examples": [
3016
+ "<Empty\n icon={<PackageIcon size={48} />}\n title=\"No packages found\"\n description=\"Get started by installing your first package.\"\n commandLine=\"npm install @signalflare-ai/ui\"\n contents={\n <div className=\"flex items-center gap-2\">\n <Button icon={<CodeIcon />}>See examples</Button>\n <Button icon={<GlobeIcon />} variant=\"primary\">\n View documentation\n </Button>\n </div>\n }\n />",
3017
+ "<div className=\"flex flex-col gap-8\">\n <div>\n <p className=\"mb-2 text-sm text-sf-subtle\">Small</p>\n <Empty\n size=\"sm\"\n icon={<DatabaseIcon size={32} className=\"text-sf-inactive\" />}\n title=\"No data available\"\n description=\"There is no data to display.\"\n />\n </div>\n <div>\n <p className=\"mb-2 text-sm text-sf-subtle\">Base</p>\n <Empty\n size=\"base\"\n icon={<DatabaseIcon size={48} className=\"text-sf-inactive\" />}\n title=\"No data available\"\n description=\"There is no data to display.\"\n />\n </div>\n <div>\n <p className=\"mb-2 text-sm text-sf-subtle\">Large</p>\n <Empty\n size=\"lg\"\n icon={<DatabaseIcon size={64} className=\"text-sf-inactive\" />}\n title=\"No data available\"\n description=\"There is no data to display.\"\n />\n </div>\n </div>",
3018
+ "<Empty\n icon={<FolderOpenIcon size={48} className=\"text-sf-inactive\" />}\n title=\"No projects found\"\n description=\"Get started by creating your first project using the command below.\"\n commandLine=\"npm create sf-project\"\n />",
3019
+ "<Empty\n icon={<CloudSlashIcon size={48} className=\"text-sf-inactive\" />}\n title=\"No connection\"\n description=\"Unable to connect to the server. Please check your connection and try again.\"\n contents={\n <div className=\"flex gap-2\">\n <Button variant=\"primary\">Retry</Button>\n <Button variant=\"secondary\">Go Back</Button>\n </div>\n }\n />",
3020
+ "<Empty title=\"Nothing here\" />",
3021
+ "<Empty\n title=\"No results found\"\n description=\"Try adjusting your search or filter to find what you're looking for.\"\n />"
3022
+ ],
2828
3023
  "colors": [
2829
3024
  "bg-sf-control",
2830
3025
  "bg-sf-overlay",
@@ -2963,7 +3158,13 @@
2963
3158
  "description": "CSS classes for the filter menu popup"
2964
3159
  }
2965
3160
  },
2966
- "examples": [],
3161
+ "examples": [
3162
+ "<div className=\"w-full rounded-lg border border-sf-line bg-sf-base p-4\">\n <Filters filters={filters} fields={filterFields} onChange={setFilters} />\n <div className=\"mt-4 rounded bg-sf-elevated p-3 font-mono text-xs\">\n <p className=\"text-sf-subtle mb-1\">Active filters:</p>\n <pre className=\"text-sf-strong overflow-x-auto\">\n {JSON.stringify(filters, null, 2)}\n </pre>\n </div>\n </div>",
3163
+ "<div className=\"w-full rounded-lg border border-sf-line bg-sf-base p-4\">\n <Filters\n filters={filters}\n fields={filterFields.slice(0, 3)}\n onChange={setFilters}\n size=\"sm\"\n />\n </div>",
3164
+ "<div className=\"w-full rounded-lg border border-sf-line bg-sf-base p-4\">\n <Filters\n filters={filters}\n fields={filterFields}\n onChange={setFilters}\n size=\"lg\"\n />\n </div>",
3165
+ "<div className=\"w-full rounded-lg border border-sf-line bg-sf-base p-4\">\n <Filters\n filters={filters}\n fields={filterFields}\n onChange={setFilters}\n showSearchInput\n />\n <p className=\"text-sf-subtle mt-3 text-xs\">\n Open the \"Add Filter\" menu to see grouped fields (General, User Details)\n </p>\n </div>",
3166
+ "<div className=\"w-full rounded-lg border border-sf-line bg-sf-base p-4\">\n <Filters\n filters={filters}\n fields={filterFields.slice(0, 3)}\n onChange={setFilters}\n enableShortcut\n shortcutKey=\"k\"\n shortcutLabel=\"Cmd+K\"\n />\n <p className=\"text-sf-subtle mt-3 text-xs\">\n Press Cmd+K (or Ctrl+K) to quickly open the add filter menu\n </p>\n </div>"
3167
+ ],
2967
3168
  "colors": [
2968
3169
  "bg-sf-fill",
2969
3170
  "bg-sf-line",
@@ -3069,7 +3270,13 @@
3069
3270
  }
3070
3271
  }
3071
3272
  },
3072
- "examples": [],
3273
+ "examples": [
3274
+ "<Grid variant=\"2up\" gap=\"base\">\n <GridItem>\n <Tile>\n <div>Item 1</div>\n <div className=\"mt-1\">First grid item</div>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <div>Item 2</div>\n <div className=\"mt-1\">Second grid item</div>\n </Tile>\n </GridItem>\n </Grid>",
3275
+ "<div className=\"flex flex-col gap-8\">\n <div>\n <p className=\"mb-2 text-sf-subtle\">variant=\"2up\"</p>\n <Grid variant=\"2up\" gap=\"sm\">\n <GridItem>\n <Tile>\n <span className=\"block text-center\">1</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">2</span>\n </Tile>\n </GridItem>\n </Grid>\n </div>\n\n <div>\n <p className=\"mb-2 text-sf-subtle\">variant=\"3up\"</p>\n <Grid variant=\"3up\" gap=\"sm\">\n <GridItem>\n <Tile>\n <span className=\"block text-center\">1</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">2</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">3</span>\n </Tile>\n </GridItem>\n </Grid>\n </div>\n\n <div>\n <p className=\"mb-2 text-sf-subtle\">variant=\"4up\"</p>\n <Grid variant=\"4up\" gap=\"sm\">\n <GridItem>\n <Tile>\n <span className=\"block text-center\">1</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">2</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">3</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">4</span>\n </Tile>\n </GridItem>\n </Grid>\n </div>\n </div>",
3276
+ "<div className=\"flex flex-col gap-8\">\n <div>\n <p className=\"mb-2 text-sf-subtle\">variant=\"2-1\" (66% / 33%)</p>\n <Grid variant=\"2-1\" gap=\"sm\">\n <GridItem>\n <Tile>\n <div>Main Content</div>\n <div className=\"mt-1\">Two-thirds width</div>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <div>Sidebar</div>\n <div className=\"mt-1\">One-third width</div>\n </Tile>\n </GridItem>\n </Grid>\n </div>\n\n <div>\n <p className=\"mb-2 text-sf-subtle\">variant=\"1-2\" (33% / 66%)</p>\n <Grid variant=\"1-2\" gap=\"sm\">\n <GridItem>\n <Tile>\n <div>Sidebar</div>\n <div className=\"mt-1\">One-third width</div>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <div>Main Content</div>\n <div className=\"mt-1\">Two-thirds width</div>\n </Tile>\n </GridItem>\n </Grid>\n </div>\n </div>",
3277
+ "<div className=\"flex flex-col gap-8\">\n <div>\n <p className=\"mb-2 text-sf-subtle\">gap=\"none\"</p>\n <Grid variant=\"side-by-side\" gap=\"none\">\n <GridItem>\n <Tile>\n <span className=\"block text-center\">1</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">2</span>\n </Tile>\n </GridItem>\n </Grid>\n </div>\n\n <div>\n <p className=\"mb-2 text-sf-subtle\">gap=\"sm\"</p>\n <Grid variant=\"side-by-side\" gap=\"sm\">\n <GridItem>\n <Tile>\n <span className=\"block text-center\">1</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">2</span>\n </Tile>\n </GridItem>\n </Grid>\n </div>\n\n <div>\n <p className=\"mb-2 text-sf-subtle\">gap=\"base\" (default, responsive)</p>\n <Grid variant=\"side-by-side\" gap=\"base\">\n <GridItem>\n <Tile>\n <span className=\"block text-center\">1</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">2</span>\n </Tile>\n </GridItem>\n </Grid>\n </div>\n\n <div>\n <p className=\"mb-2 text-sf-subtle\">gap=\"lg\"</p>\n <Grid variant=\"side-by-side\" gap=\"lg\">\n <GridItem>\n <Tile>\n <span className=\"block text-center\">1</span>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <span className=\"block text-center\">2</span>\n </Tile>\n </GridItem>\n </Grid>\n </div>\n </div>",
3278
+ "<Grid variant=\"4up\" gap=\"base\" mobileDivider>\n <GridItem>\n <Tile>\n <div>Item 1</div>\n <div className=\"mt-1\">Has divider on mobile</div>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <div>Item 2</div>\n <div className=\"mt-1\">Has divider on mobile</div>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <div>Item 3</div>\n <div className=\"mt-1\">Has divider on mobile</div>\n </Tile>\n </GridItem>\n <GridItem>\n <Tile>\n <div>Item 4</div>\n <div className=\"mt-1\">Has divider on mobile</div>\n </Tile>\n </GridItem>\n </Grid>"
3279
+ ],
3073
3280
  "colors": ["border-sf-line"]
3074
3281
  },
3075
3282
  "Input": {
@@ -3142,7 +3349,19 @@
3142
3349
  "default": "default"
3143
3350
  }
3144
3351
  },
3145
- "examples": [],
3352
+ "examples": [
3353
+ "<Input\n label=\"Email\"\n placeholder=\"you@example.com\"\n description=\"We'll never share your email\"\n />",
3354
+ "<Input\n label=\"Username\"\n placeholder=\"Choose a username\"\n description=\"3-20 characters, alphanumeric only\"\n />",
3355
+ "<Input\n label=\"Email\"\n placeholder=\"you@example.com\"\n value=\"invalid-email\"\n variant=\"error\"\n error=\"Please enter a valid email address\"\n />",
3356
+ "<Input\n label=\"Password\"\n type=\"password\"\n value=\"short\"\n variant=\"error\"\n error={{\n match: \"tooShort\",\n message: \"Password must be at least 8 characters\",\n }}\n minLength={8}\n />",
3357
+ "<div className=\"flex flex-col gap-4\">\n <Input size=\"xs\" label=\"Extra Small\" placeholder=\"Extra small input\" />\n <Input size=\"sm\" label=\"Small\" placeholder=\"Small input\" />\n <Input label=\"Base\" placeholder=\"Base input (default)\" />\n <Input size=\"lg\" label=\"Large\" placeholder=\"Large input\" />\n </div>",
3358
+ "<Input label=\"Disabled field\" placeholder=\"Cannot edit\" disabled />",
3359
+ "<Input placeholder=\"Search...\" aria-label=\"Search products\" />",
3360
+ "<div className=\"flex flex-col gap-4\">\n <Input type=\"email\" label=\"Email\" placeholder=\"you@example.com\" />\n <Input type=\"password\" label=\"Password\" placeholder=\"••••••••\" />\n <Input type=\"number\" label=\"Age\" placeholder=\"18\" />\n <Input type=\"tel\" label=\"Phone\" placeholder=\"+1 (555) 000-0000\" />\n </div>",
3361
+ "<Input\n label=\"Phone Number\"\n required={false}\n placeholder=\"+1 (555) 000-0000\"\n />",
3362
+ "<Input\n label=\"API Key\"\n labelTooltip=\"Find this in your dashboard under Settings > API Keys\"\n placeholder=\"sk_live_...\"\n />",
3363
+ "<Input\n label={\n <span>\n Email for <strong>billing</strong>\n </span>\n }\n required\n placeholder=\"billing@company.com\"\n type=\"email\"\n />"
3364
+ ],
3146
3365
  "colors": [
3147
3366
  "bg-sf-control",
3148
3367
  "ring-sf-danger",
@@ -3240,7 +3459,14 @@
3240
3459
  "description": "When true, only renders the inline content (indicators, tooltip) without the outer label element with font styling. Useful when composed inside another label element that already provides the text styling."
3241
3460
  }
3242
3461
  },
3243
- "examples": [],
3462
+ "examples": [
3463
+ "<div className=\"flex flex-col gap-4\">\n <Label>Default Label</Label>\n <Label showOptional>Optional Label</Label>\n <Label tooltip=\"More information about this field\">\n Label with Tooltip\n </Label>\n </div>",
3464
+ "<Input label=\"Phone Number\" required={false} placeholder=\"+1 555-0000\" />",
3465
+ "<Input\n label=\"API Key\"\n labelTooltip=\"Find this in your dashboard settings under API > Keys\"\n placeholder=\"sk_live_...\"\n />",
3466
+ "<Checkbox\n label={\n <span>\n I agree to the <strong>Terms of Service</strong>\n </span>\n }\n />",
3467
+ "<div className=\"flex max-w-md flex-col gap-4\">\n <Input label=\"Full Name\" placeholder=\"John Doe\" />\n <Input\n label=\"Email\"\n labelTooltip=\"We'll send your receipt here\"\n placeholder=\"john@example.com\"\n type=\"email\"\n />\n <Input label=\"Company\" required={false} placeholder=\"Acme Inc.\" />\n <Select label=\"Country\" hideLabel={false} placeholder=\"Select a country\">\n <Select.Option value=\"us\">United States</Select.Option>\n <Select.Option value=\"uk\">United Kingdom</Select.Option>\n <Select.Option value=\"ca\">Canada</Select.Option>\n </Select>\n </div>",
3468
+ "<div className=\"flex flex-col gap-3\">\n <Label>Default</Label>\n <Label showOptional>Optional</Label>\n <Label tooltip=\"Important field\">With Tooltip</Label>\n </div>"
3469
+ ],
3244
3470
  "colors": ["text-sf-default", "text-sf-strong"]
3245
3471
  },
3246
3472
  "LayerCard": {
@@ -3260,7 +3486,11 @@
3260
3486
  "description": "Additional CSS classes merged via `cn()`."
3261
3487
  }
3262
3488
  },
3263
- "examples": [],
3489
+ "examples": [
3490
+ "<LayerCard>\n <LayerCard.Secondary className=\"flex items-center justify-between\">\n <div>Next Steps</div>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n shape=\"square\"\n aria-label=\"Go to next steps\"\n >\n <ArrowRightIcon size={16} />\n </Button>\n </LayerCard.Secondary>\n\n <LayerCard.Primary>Get started with SF</LayerCard.Primary>\n </LayerCard>",
3491
+ "<LayerCard className=\"w-[250px]\">\n <LayerCard.Secondary>Getting Started</LayerCard.Secondary>\n <LayerCard.Primary>\n <p className=\"text-sm text-sf-subtle\">\n Quick start guide for new users\n </p>\n </LayerCard.Primary>\n </LayerCard>",
3492
+ "<div className=\"flex gap-4\">\n <LayerCard className=\"w-[200px]\">\n <LayerCard.Secondary>Components</LayerCard.Secondary>\n <LayerCard.Primary>\n <p className=\"text-sm\">Browse all components</p>\n </LayerCard.Primary>\n </LayerCard>\n <LayerCard className=\"w-[200px]\">\n <LayerCard.Secondary>Examples</LayerCard.Secondary>\n <LayerCard.Primary>\n <p className=\"text-sm\">View code examples</p>\n </LayerCard.Primary>\n </LayerCard>\n </div>"
3493
+ ],
3264
3494
  "colors": [
3265
3495
  "bg-sf-base",
3266
3496
  "bg-sf-elevated",
@@ -3272,12 +3502,22 @@
3272
3502
  "Primary": {
3273
3503
  "name": "Primary",
3274
3504
  "description": "Primary sub-component",
3275
- "props": {}
3505
+ "props": {
3506
+ "className": {
3507
+ "type": "string",
3508
+ "optional": true
3509
+ }
3510
+ }
3276
3511
  },
3277
3512
  "Secondary": {
3278
3513
  "name": "Secondary",
3279
3514
  "description": "Secondary sub-component",
3280
- "props": {}
3515
+ "props": {
3516
+ "className": {
3517
+ "type": "string",
3518
+ "optional": true
3519
+ }
3520
+ }
3281
3521
  }
3282
3522
  },
3283
3523
  "styling": {
@@ -3405,7 +3645,13 @@
3405
3645
  "description": "Allows you to replace the component's HTML element with a different tag, or compose it with another component.\n\nAccepts a `ReactElement` or a function that returns the element to render."
3406
3646
  }
3407
3647
  },
3408
- "examples": [],
3648
+ "examples": [
3649
+ "<div className=\"grid gap-x-6 gap-y-4 text-base md:grid-cols-3\">\n <Link href=\"#\">Default inline link</Link>\n <Link href=\"#\" variant=\"current\">\n Current color link\n </Link>\n <Link href=\"#\" variant=\"plain\">\n Plain inline link\n </Link>\n </div>",
3650
+ "<p className=\"mx-auto max-w-md text-base leading-relaxed text-sf-default\">\n This is a paragraph with an <Link href=\"#\">inline link</Link> that flows\n naturally with the surrounding text. Links maintain proper underline\n offset for readability.\n </p>",
3651
+ "<Link\n href=\"https://cloudflare.com\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-base\"\n >\n Visit Cloudflare <Link.ExternalIcon />\n </Link>",
3652
+ "<p className=\"text-base text-sf-danger\">\n This error message contains a{\" \"}\n <Link href=\"#\" variant=\"current\">\n link\n </Link>{\" \"}\n that inherits the red color from its parent.\n </p>",
3653
+ "<div className=\"flex flex-col gap-x-6 gap-y-4 text-base md:flex-row\">\n <Link render={<CustomRouterLink href=\"/dashboard\" />} variant=\"inline\">\n Dashboard (via render)\n </Link>\n <Link\n render={\n <CustomRouterLink\n href=\"https://developers.cloudflare.com\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n />\n }\n variant=\"inline\"\n >\n Cloudflare Docs <Link.ExternalIcon />\n </Link>\n </div>"
3654
+ ],
3409
3655
  "colors": [],
3410
3656
  "subComponents": {
3411
3657
  "ExternalIcon": {
@@ -3440,7 +3686,11 @@
3440
3686
  "default": "base"
3441
3687
  }
3442
3688
  },
3443
- "examples": [],
3689
+ "examples": [
3690
+ "<Loader />",
3691
+ "<div className=\"flex items-center gap-4\">\n <Loader size=\"sm\" />\n <Loader size=\"base\" />\n <Loader size=\"lg\" />\n </div>",
3692
+ "<Loader size={24} />"
3693
+ ],
3444
3694
  "colors": []
3445
3695
  },
3446
3696
  "MenuBar": {
@@ -3471,7 +3721,11 @@
3471
3721
  "description": "When true, each option's `id` field is used for matching instead of its array index."
3472
3722
  }
3473
3723
  },
3474
- "examples": [],
3724
+ "examples": [
3725
+ "<MenuBar\n isActive=\"bold\"\n optionIds\n options={[\n {\n icon: <TextBolderIcon />,\n id: \"bold\",\n onClick: () => {},\n tooltip: \"Bold\",\n },\n {\n icon: <TextItalicIcon />,\n id: \"italic\",\n onClick: () => {},\n tooltip: \"Italic\",\n },\n ]}\n />",
3726
+ "<MenuBar\n isActive=\"bold\"\n optionIds\n options={[\n {\n icon: <TextBolderIcon />,\n id: \"bold\",\n onClick: () => {},\n tooltip: \"Bold\",\n },\n {\n icon: <TextItalicIcon />,\n id: \"italic\",\n onClick: () => {},\n tooltip: \"Italic\",\n },\n ]}\n />",
3727
+ "<MenuBar\n isActive=\"\"\n optionIds\n options={[\n {\n icon: <TextBolderIcon />,\n id: \"bold\",\n onClick: () => {},\n tooltip: \"Bold\",\n },\n {\n icon: <TextItalicIcon />,\n id: \"italic\",\n onClick: () => {},\n tooltip: \"Italic\",\n },\n ]}\n />"
3728
+ ],
3475
3729
  "colors": ["bg-sf-base", "bg-sf-fill", "border-sf-fill"],
3476
3730
  "styling": {
3477
3731
  "container": {
@@ -3532,7 +3786,14 @@
3532
3786
  "description": "Minimum value of the meter (default: 0)"
3533
3787
  }
3534
3788
  },
3535
- "examples": [],
3789
+ "examples": [
3790
+ "<Meter label=\"Storage used\" value={65} />",
3791
+ "<Meter label=\"API requests\" value={75} customValue=\"750 / 1,000\" />",
3792
+ "<Meter label=\"Progress\" value={40} showValue={false} />",
3793
+ "<Meter label=\"Quota reached\" value={100} />",
3794
+ "<Meter label=\"Memory usage\" value={15} />",
3795
+ "<Meter\n label=\"Upload progress\"\n value={80}\n indicatorClassName=\"from-green-500 via-green-500 to-green-500\"\n />"
3796
+ ],
3536
3797
  "colors": ["bg-sf-fill", "text-sf-default", "text-sf-strong"]
3537
3798
  },
3538
3799
  "Pagination": {
@@ -3578,7 +3839,14 @@
3578
3839
  "description": "Method to provide custom pagination text"
3579
3840
  }
3580
3841
  },
3581
- "examples": [],
3842
+ "examples": [
3843
+ "<Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />",
3844
+ "<Pagination\n page={page}\n setPage={setPage}\n perPage={10}\n totalCount={100}\n controls=\"simple\"\n />",
3845
+ "<Pagination\n page={page}\n setPage={setPage}\n perPage={10}\n totalCount={100}\n controls=\"full\"\n />",
3846
+ "<Pagination page={page} setPage={setPage} perPage={10} totalCount={100} />",
3847
+ "<Pagination page={page} setPage={setPage} perPage={25} totalCount={1250} />",
3848
+ "<Pagination\n text={({ perPage }) => `Page ${page} - showing ${perPage} per page`}\n page={page}\n setPage={setPage}\n perPage={25}\n totalCount={100}\n />"
3849
+ ],
3582
3850
  "colors": ["text-sf-strong"],
3583
3851
  "styling": {
3584
3852
  "layout": {
@@ -3612,7 +3880,14 @@
3612
3880
  "default": "bottom"
3613
3881
  }
3614
3882
  },
3615
- "examples": [],
3883
+ "examples": [
3884
+ "<Popover>\n <Popover.Trigger asChild>\n <Button shape=\"square\" icon={BellIcon} aria-label=\"Notifications\" />\n </Popover.Trigger>\n <Popover.Content>\n <Popover.Title>Notifications</Popover.Title>\n <Popover.Description>\n You are all caught up. Good job!\n </Popover.Description>\n </Popover.Content>\n </Popover>",
3885
+ "<Popover>\n <Popover.Trigger asChild>\n <Button>Open Popover</Button>\n </Popover.Trigger>\n <Popover.Content>\n <Popover.Title>Popover Title</Popover.Title>\n <Popover.Description>\n This is a basic popover with a title and description.\n </Popover.Description>\n </Popover.Content>\n </Popover>",
3886
+ "<Popover>\n <Popover.Trigger asChild>\n <Button>Open Settings</Button>\n </Popover.Trigger>\n <Popover.Content>\n <Popover.Title>Settings</Popover.Title>\n <Popover.Description>\n Configure your preferences below.\n </Popover.Description>\n <div className=\"mt-3\">\n <Popover.Close asChild>\n <Button variant=\"secondary\" size=\"sm\">\n Close\n </Button>\n </Popover.Close>\n </div>\n </Popover.Content>\n </Popover>",
3887
+ "<div className=\"flex flex-wrap gap-4\">\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Bottom</Button>\n </Popover.Trigger>\n <Popover.Content side=\"bottom\">\n <Popover.Title>Bottom</Popover.Title>\n <Popover.Description>\n Popover on bottom (default).\n </Popover.Description>\n </Popover.Content>\n </Popover>\n\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Top</Button>\n </Popover.Trigger>\n <Popover.Content side=\"top\">\n <Popover.Title>Top</Popover.Title>\n <Popover.Description>Popover on top.</Popover.Description>\n </Popover.Content>\n </Popover>\n\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Left</Button>\n </Popover.Trigger>\n <Popover.Content side=\"left\">\n <Popover.Title>Left</Popover.Title>\n <Popover.Description>Popover on left.</Popover.Description>\n </Popover.Content>\n </Popover>\n\n <Popover>\n <Popover.Trigger asChild>\n <Button variant=\"secondary\">Right</Button>\n </Popover.Trigger>\n <Popover.Content side=\"right\">\n <Popover.Title>Right</Popover.Title>\n <Popover.Description>Popover on right.</Popover.Description>\n </Popover.Content>\n </Popover>\n </div>",
3888
+ "<Popover>\n <Popover.Trigger asChild>\n <Button>User Profile</Button>\n </Popover.Trigger>\n <Popover.Content className=\"w-64\">\n <div className=\"flex items-center gap-3\">\n <div className=\"size-10 rounded-full bg-sf-recessed\" />\n <div>\n <Popover.Title>Jane Doe</Popover.Title>\n <p className=\"text-sm text-sf-subtle\">jane@example.com</p>\n </div>\n </div>\n <div className=\"mt-3 flex gap-2 border-t border-sf-line pt-3\">\n <Button variant=\"secondary\" size=\"sm\" className=\"flex-1\">\n Profile\n </Button>\n <Popover.Close asChild>\n <Button variant=\"ghost\" size=\"sm\" className=\"flex-1\">\n Sign Out\n </Button>\n </Popover.Close>\n </div>\n </Popover.Content>\n </Popover>",
3889
+ "<Popover>\n <Popover.Trigger openOnHover delay={200} asChild>\n <Button variant=\"secondary\">Hover Me</Button>\n </Popover.Trigger>\n <Popover.Content>\n <Popover.Title>Hover Triggered</Popover.Title>\n <Popover.Description>\n This popover opens on hover with a 200ms delay. It can still contain\n interactive content like buttons and links.\n </Popover.Description>\n <div className=\"mt-3\">\n <Popover.Close asChild>\n <Button variant=\"secondary\" size=\"sm\">\n Got it\n </Button>\n </Popover.Close>\n </div>\n </Popover.Content>\n </Popover>"
3890
+ ],
3616
3891
  "colors": [
3617
3892
  "bg-sf-elevated",
3618
3893
  "fill-sf-elevated",
@@ -3626,12 +3901,38 @@
3626
3901
  "Trigger": {
3627
3902
  "name": "Trigger",
3628
3903
  "description": "Trigger sub-component",
3629
- "props": {}
3904
+ "props": {
3905
+ "asChild": {
3906
+ "type": "boolean",
3907
+ "optional": true
3908
+ }
3909
+ }
3630
3910
  },
3631
3911
  "Content": {
3632
3912
  "name": "Content",
3633
3913
  "description": "Content sub-component",
3634
- "props": {}
3914
+ "props": {
3915
+ "align": {
3916
+ "type": "PopoverAlign",
3917
+ "optional": true
3918
+ },
3919
+ "sideOffset": {
3920
+ "type": "number",
3921
+ "optional": true
3922
+ },
3923
+ "alignOffset": {
3924
+ "type": "number",
3925
+ "optional": true
3926
+ },
3927
+ "className": {
3928
+ "type": "string",
3929
+ "optional": true
3930
+ },
3931
+ "children": {
3932
+ "type": "ReactNode",
3933
+ "optional": true
3934
+ }
3935
+ }
3635
3936
  },
3636
3937
  "Title": {
3637
3938
  "name": "Title",
@@ -3646,7 +3947,12 @@
3646
3947
  "Close": {
3647
3948
  "name": "Close",
3648
3949
  "description": "Close sub-component",
3649
- "props": {}
3950
+ "props": {
3951
+ "asChild": {
3952
+ "type": "boolean",
3953
+ "optional": true
3954
+ }
3955
+ }
3650
3956
  }
3651
3957
  }
3652
3958
  },
@@ -3678,9 +3984,15 @@
3678
3984
  "description": "Content rendered in the collapsible back layer (e.g. HITL approvals, task lists). When provided the prompt input is wrapped in a LayerCard shell with a header row containing a chevron toggle. Use `PromptInputBackLayer` to compose structured content for this slot."
3679
3985
  },
3680
3986
  "backLayerTitle": {
3681
- "type": "string",
3987
+ "type": "ReactNode",
3988
+ "optional": true,
3989
+ "description": "Header content shown in the back layer header row. Strings render as plain text; pass JSX to compose with icons/spinners/badges. Defaults to `\"Context\"`."
3990
+ },
3991
+ "backLayerStatus": {
3992
+ "type": "enum",
3682
3993
  "optional": true,
3683
- "description": "Title shown in the back layer header row. Defaults to `\"Context\"`."
3994
+ "description": "Optional status indicator rendered next to the title. `\"running\"` shows a small spinner; `\"error\"` shows an inline error icon. Use this instead of composing JSX into `backLayerTitle` for the common case of an agent doing work.",
3995
+ "values": ["idle", "running", "error"]
3684
3996
  },
3685
3997
  "backLayerOpen": {
3686
3998
  "type": "boolean",
@@ -3725,6 +4037,7 @@
3725
4037
  "ring-sf-line",
3726
4038
  "ring-sf-ring",
3727
4039
  "text-sf-brand",
4040
+ "text-sf-danger",
3728
4041
  "text-sf-default",
3729
4042
  "text-sf-inactive",
3730
4043
  "text-sf-strong",
@@ -3734,7 +4047,12 @@
3734
4047
  "BackLayer": {
3735
4048
  "name": "BackLayer",
3736
4049
  "description": "BackLayer sub-component",
3737
- "props": {}
4050
+ "props": {
4051
+ "className": {
4052
+ "type": "string",
4053
+ "optional": true
4054
+ }
4055
+ }
3738
4056
  },
3739
4057
  "Textarea": {
3740
4058
  "name": "Textarea",
@@ -3774,12 +4092,22 @@
3774
4092
  "Tags": {
3775
4093
  "name": "Tags",
3776
4094
  "description": "Tags sub-component",
3777
- "props": {}
4095
+ "props": {
4096
+ "children": {
4097
+ "type": "(tag: PromptInputTagData) => ReactNode",
4098
+ "required": true
4099
+ }
4100
+ }
3778
4101
  },
3779
4102
  "Tag": {
3780
4103
  "name": "Tag",
3781
4104
  "description": "Tag sub-component",
3782
- "props": {}
4105
+ "props": {
4106
+ "data": {
4107
+ "type": "PromptInputTagData",
4108
+ "required": true
4109
+ }
4110
+ }
3783
4111
  },
3784
4112
  "AttachButton": {
3785
4113
  "name": "AttachButton",
@@ -3789,12 +4117,22 @@
3789
4117
  "Attachments": {
3790
4118
  "name": "Attachments",
3791
4119
  "description": "Attachments sub-component",
3792
- "props": {}
4120
+ "props": {
4121
+ "children": {
4122
+ "type": "(attachment: AttachmentFile) => ReactNode",
4123
+ "required": true
4124
+ }
4125
+ }
3793
4126
  },
3794
4127
  "Attachment": {
3795
4128
  "name": "Attachment",
3796
4129
  "description": "Attachment sub-component",
3797
- "props": {}
4130
+ "props": {
4131
+ "data": {
4132
+ "type": "AttachmentFile",
4133
+ "required": true
4134
+ }
4135
+ }
3798
4136
  }
3799
4137
  }
3800
4138
  },
@@ -3858,7 +4196,15 @@
3858
4196
  "description": "Additional CSS classes"
3859
4197
  }
3860
4198
  },
3861
- "examples": [],
4199
+ "examples": [
4200
+ "<Radio.Group\n legend=\"Notification preference\"\n value={value}\n onValueChange={setValue}\n >\n <Radio.Item label=\"Email\" value=\"email\" />\n <Radio.Item label=\"SMS\" value=\"sms\" />\n <Radio.Item label=\"Push notification\" value=\"push\" />\n </Radio.Group>",
4201
+ "<Radio.Group legend=\"Account type\" value={value} onValueChange={setValue}>\n <Radio.Item label=\"Personal\" value=\"personal\" />\n <Radio.Item label=\"Business\" value=\"business\" />\n <Radio.Item label=\"Enterprise\" value=\"enterprise\" />\n </Radio.Group>",
4202
+ "<Radio.Group\n legend=\"Size\"\n orientation=\"horizontal\"\n value={value}\n onValueChange={setValue}\n >\n <Radio.Item label=\"Small\" value=\"sm\" />\n <Radio.Item label=\"Medium\" value=\"md\" />\n <Radio.Item label=\"Large\" value=\"lg\" />\n </Radio.Group>",
4203
+ "<Radio.Group\n legend=\"Shipping method\"\n description=\"Choose how you'd like to receive your order\"\n value={value}\n onValueChange={setValue}\n >\n <Radio.Item label=\"Standard (5-7 days)\" value=\"standard\" />\n <Radio.Item label=\"Express (2-3 days)\" value=\"express\" />\n <Radio.Item label=\"Overnight\" value=\"overnight\" />\n </Radio.Group>",
4204
+ "<Radio.Group\n legend=\"Payment method\"\n error=\"Please select a payment method to continue\"\n >\n <Radio.Item label=\"Credit Card\" value=\"card\" variant=\"error\" />\n <Radio.Item label=\"PayPal\" value=\"paypal\" variant=\"error\" />\n <Radio.Item label=\"Bank Transfer\" value=\"bank\" variant=\"error\" />\n </Radio.Group>",
4205
+ "<div className=\"flex flex-col gap-6\">\n <Radio.Group legend=\"Disabled group\" disabled defaultValue=\"a\">\n <Radio.Item label=\"Option A\" value=\"a\" />\n <Radio.Item label=\"Option B\" value=\"b\" />\n </Radio.Group>\n <Radio.Group legend=\"Individual disabled\" defaultValue=\"available\">\n <Radio.Item label=\"Available\" value=\"available\" />\n <Radio.Item label=\"Unavailable\" value=\"unavailable\" disabled />\n </Radio.Group>\n </div>",
4206
+ "<Radio.Group legend=\"Preferences\" controlPosition=\"end\" defaultValue=\"a\">\n <Radio.Item label=\"Label before radio\" value=\"a\" />\n <Radio.Item label=\"Another option\" value=\"b\" />\n </Radio.Group>"
4207
+ ],
3862
4208
  "colors": [
3863
4209
  "bg-sf-base",
3864
4210
  "bg-sf-contrast",
@@ -3947,7 +4293,16 @@
3947
4293
  "description": "Initial value for uncontrolled mode"
3948
4294
  }
3949
4295
  },
3950
- "examples": [],
4296
+ "examples": [
4297
+ "<Select\n className=\"w-[200px]\"\n value={value}\n onValueChange={(v) => setValue(v ?? \"apple\")}\n items={{ apple: \"Apple\", banana: \"Banana\", cherry: \"Cherry\" }}\n >\n <Select.Option value=\"apple\">Apple</Select.Option>\n <Select.Option value=\"banana\">Banana</Select.Option>\n <Select.Option value=\"cherry\">Cherry</Select.Option>\n </Select>",
4298
+ "<Select\n className=\"w-[200px]\"\n value={value}\n onValueChange={(v) => setValue(v as string)}\n items={{\n bug: \"Bug\",\n documentation: \"Documentation\",\n feature: \"Feature\",\n }}\n >\n <Select.Option value=\"bug\">Bug</Select.Option>\n <Select.Option value=\"documentation\">Documentation</Select.Option>\n <Select.Option value=\"feature\">Feature</Select.Option>\n </Select>",
4299
+ "<Select\n className=\"w-[200px]\"\n value={value}\n onValueChange={(v) => setValue(v as string | null)}\n items={[\n { label: \"Please select\", value: null },\n { label: \"Bug\", value: \"bug\" },\n { label: \"Documentation\", value: \"documentation\" },\n { label: \"Feature\", value: \"feature\" },\n ]}\n >\n <Select.Option value=\"bug\">Bug</Select.Option>\n <Select.Option value=\"documentation\">Documentation</Select.Option>\n <Select.Option value=\"feature\">Feature</Select.Option>\n </Select>",
4300
+ "<Select\n className=\"w-[200px]\"\n renderValue={(v) => (\n <span>\n {v.emoji} {v.label}\n </span>\n )}\n value={value}\n onValueChange={(v) => setValue(v as (typeof languages)[0])}\n >\n {languages.map((language) => (\n <Select.Option key={language.value} value={language}>\n {language.emoji} {language.label}\n </Select.Option>\n ))}\n </Select>",
4301
+ "<Select className=\"w-[200px]\" loading />",
4302
+ "<Select\n className=\"w-[200px]\"\n loading={loading}\n value={value}\n onValueChange={(v) => setValue(v as string | null)}\n placeholder=\"Please select\"\n >\n {data?.map((item) => (\n <Select.Option key={item} value={item}>\n {item}\n </Select.Option>\n ))}\n </Select>",
4303
+ "<Select\n className=\"w-[250px]\"\n multiple\n renderValue={(value) => {\n if (value.length > 3) {\n return (\n <span className=\"line-clamp-1\">\n {value.slice(2).join(\", \") + ` and ${value.length - 2} more`}\n </span>\n );\n }\n return <span>{value.join(\", \")}</span>;\n }}\n value={value}\n onValueChange={(v) => setValue(v as string[])}\n >\n <Select.Option value=\"Name\">Name</Select.Option>\n <Select.Option value=\"Location\">Location</Select.Option>\n <Select.Option value=\"Size\">Size</Select.Option>\n <Select.Option value=\"Read\">Read</Select.Option>\n <Select.Option value=\"Write\">Write</Select.Option>\n <Select.Option value=\"CreatedAt\">Created At</Select.Option>\n </Select>",
4304
+ "<Select\n className=\"w-[200px]\"\n onValueChange={(v) => setValue(v as (typeof authors)[0] | null)}\n value={value}\n isItemEqualToValue={(item, value) => item?.id === value?.id}\n renderValue={(author) => author?.name ?? \"Please select author\"}\n >\n {authors.map((author) => (\n <Select.Option key={author.id} value={author}>\n <div className=\"flex w-[300px] items-center justify-between gap-2\">\n <Text>{author.name}</Text>\n <Text variant=\"secondary\">{author.title}</Text>\n </div>\n </Select.Option>\n ))}\n </Select>"
4305
+ ],
3951
4306
  "colors": [
3952
4307
  "bg-sf-control",
3953
4308
  "bg-sf-overlay",
@@ -4108,7 +4463,12 @@
4108
4463
  "description": "Error message or validation error object"
4109
4464
  }
4110
4465
  },
4111
- "examples": [],
4466
+ "examples": [
4467
+ "<div className=\"w-80\">\n <SensitiveInput label=\"API Key\" defaultValue=\"sk_live_abc123xyz789\" />\n </div>",
4468
+ "<div className=\"flex flex-col gap-4\">\n {sizes.map((size) => (\n <div key={size} className=\"flex items-center gap-2\">\n <span className=\"w-12 text-sm text-sf-subtle\">{size}</span>\n <SensitiveInput\n label={`${size} size`}\n size={size}\n defaultValue=\"secret-api-key-123\"\n />\n </div>\n ))}\n </div>",
4469
+ "<div className=\"flex w-80 flex-col gap-4\">\n <SensitiveInput\n label=\"Controlled Secret\"\n value={value}\n onValueChange={setValue}\n />\n <div className=\"text-sm text-sf-subtle\">\n Current value: <code className=\"text-sf-default\">{value}</code>\n </div>\n <div className=\"flex gap-2\">\n <Button\n onClick={() => setValue(\"new-secret-\" + Date.now())}\n variant=\"primary\"\n size=\"sm\"\n >\n Change value\n </Button>\n <Button onClick={() => setValue(\"\")} variant=\"secondary\" size=\"sm\">\n Clear\n </Button>\n </div>\n </div>",
4470
+ "<div className=\"flex w-80 flex-col gap-4\">\n <SensitiveInput\n label=\"Error State\"\n variant=\"error\"\n defaultValue=\"invalid-key\"\n error=\"This API key is not valid\"\n />\n <SensitiveInput label=\"Disabled\" defaultValue=\"cannot-edit\" disabled />\n <SensitiveInput\n label=\"Read-only\"\n defaultValue=\"view-only-secret-key\"\n readOnly\n />\n <SensitiveInput\n label=\"With Description\"\n defaultValue=\"my-secret-value\"\n description=\"Keep this value secure and don't share it\"\n />\n </div>"
4471
+ ],
4112
4472
  "colors": [
4113
4473
  "bg-sf-brand",
4114
4474
  "bg-sf-control",
@@ -4199,7 +4559,14 @@
4199
4559
  "description": "Additional CSS classes for the wrapper div."
4200
4560
  }
4201
4561
  },
4202
- "examples": [],
4562
+ "examples": [
4563
+ "<DemoContainer>\n <Sidebar.Provider defaultOpen className=\"min-h-0! h-full\">\n <Sidebar>\n <Sidebar.Content>\n <Sidebar.Group>\n <Sidebar.GroupLabel>Overview</Sidebar.GroupLabel>\n <Sidebar.Menu>\n <Sidebar.MenuButton icon={HouseIcon} active>\n Home\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={ChartBarIcon}>\n Analytics\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={GlobeIcon}>\n Domains\n </Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.Group>\n\n <Sidebar.Group>\n <Sidebar.GroupLabel>Build</Sidebar.GroupLabel>\n <Sidebar.Menu>\n <Sidebar.MenuItem>\n <Sidebar.Collapsible defaultOpen>\n <Sidebar.CollapsibleTrigger\n render={\n <Sidebar.MenuButton icon={CodeIcon}>\n Compute\n <Sidebar.MenuChevron />\n </Sidebar.MenuButton>\n }\n />\n <Sidebar.CollapsibleContent>\n <Sidebar.MenuSub>\n <Sidebar.MenuSubButton>Workers</Sidebar.MenuSubButton>\n <Sidebar.MenuSubButton>\n Durable Objects\n </Sidebar.MenuSubButton>\n </Sidebar.MenuSub>\n </Sidebar.CollapsibleContent>\n </Sidebar.Collapsible>\n </Sidebar.MenuItem>\n <Sidebar.MenuButton icon={DatabaseIcon}>\n Storage\n </Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.Group>\n </Sidebar.Content>\n </Sidebar>\n <DemoMain />\n </Sidebar.Provider>\n </DemoContainer>",
4564
+ "<DemoContainer>\n <Sidebar.Provider defaultOpen className=\"min-h-0! h-full\">\n <Sidebar>\n <Sidebar.Content>\n <Sidebar.Group collapsible defaultOpen>\n <Sidebar.GroupLabel>Overview</Sidebar.GroupLabel>\n <Sidebar.GroupContent>\n <Sidebar.Menu>\n <Sidebar.MenuButton icon={HouseIcon} active>\n Home\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={ChartBarIcon}>\n Analytics\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={GlobeIcon}>\n Domains\n </Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.GroupContent>\n </Sidebar.Group>\n\n <Sidebar.Group collapsible defaultOpen={false}>\n <Sidebar.GroupLabel>Settings</Sidebar.GroupLabel>\n <Sidebar.GroupContent>\n <Sidebar.Menu>\n <Sidebar.MenuButton icon={ShieldCheckIcon}>\n Security\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={LockIcon}>\n Access Control\n </Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.GroupContent>\n </Sidebar.Group>\n </Sidebar.Content>\n </Sidebar>\n <DemoMain />\n </Sidebar.Provider>\n </DemoContainer>",
4565
+ "<DemoContainer>\n <Sidebar.Provider defaultOpen className=\"min-h-0! h-full\">\n <Sidebar>\n <Sidebar.Header>\n <BrandLogo />\n </Sidebar.Header>\n <Sidebar.Content>\n <Sidebar.Group>\n <Sidebar.Menu>\n <Sidebar.MenuButton icon={HouseIcon} tooltip=\"Home\" active>\n Home\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={ChartBarIcon} tooltip=\"Analytics\">\n Analytics\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={CodeIcon} tooltip=\"Compute\">\n Compute\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={DatabaseIcon} tooltip=\"Storage\">\n Storage\n </Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.Group>\n </Sidebar.Content>\n <Sidebar.Footer>\n <Sidebar.Trigger />\n </Sidebar.Footer>\n </Sidebar>\n <DemoMain>\n <ToggleButton />\n <p className=\"text-sm\">\n Click the button or the sidebar trigger to toggle\n </p>\n </DemoMain>\n </Sidebar.Provider>\n </DemoContainer>",
4566
+ "<DemoContainer>\n <Sidebar.Provider defaultOpen className=\"min-h-0! h-full\">\n <Sidebar>\n <Sidebar.Header>\n <BrandLogo />\n </Sidebar.Header>\n\n <Sidebar.Content>\n <div className=\"px-1 pb-2\">\n <Sidebar.Input placeholder=\"Quick search...\" shortcut=\"⌘K\" />\n </div>\n\n <Sidebar.Group>\n <Sidebar.GroupLabel>Overview</Sidebar.GroupLabel>\n <Sidebar.Menu>\n <Sidebar.MenuButton icon={HouseIcon} active>\n Home\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={ChartBarIcon}>\n Analytics\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={GlobeIcon}>\n Domains\n </Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.Group>\n\n <Sidebar.Separator />\n\n <Sidebar.Group>\n <Sidebar.GroupLabel>Build</Sidebar.GroupLabel>\n <Sidebar.Menu>\n <Sidebar.MenuItem>\n <Sidebar.Collapsible defaultOpen>\n <Sidebar.CollapsibleTrigger\n render={\n <Sidebar.MenuButton icon={CodeIcon}>\n Compute\n <Sidebar.MenuChevron />\n </Sidebar.MenuButton>\n }\n />\n <Sidebar.CollapsibleContent>\n <Sidebar.MenuSub>\n <Sidebar.MenuSubButton>Workers</Sidebar.MenuSubButton>\n <Sidebar.MenuSubButton>\n Durable Objects\n </Sidebar.MenuSubButton>\n <Sidebar.MenuSubButton>\n Containers\n <Sidebar.MenuBadge>Beta</Sidebar.MenuBadge>\n </Sidebar.MenuSubButton>\n </Sidebar.MenuSub>\n </Sidebar.CollapsibleContent>\n </Sidebar.Collapsible>\n </Sidebar.MenuItem>\n <Sidebar.MenuButton icon={DatabaseIcon}>\n Storage\n </Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.Group>\n\n <Sidebar.Group>\n <Sidebar.GroupLabel>Security</Sidebar.GroupLabel>\n <Sidebar.Menu>\n <Sidebar.MenuButton icon={ShieldCheckIcon}>\n Firewall\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={LockIcon}>\n Access\n <Sidebar.MenuBadge>Beta</Sidebar.MenuBadge>\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={BellIcon}>\n Notifications\n </Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.Group>\n </Sidebar.Content>\n\n <Sidebar.Footer>\n <Sidebar.MenuButton icon={GearIcon}>Settings</Sidebar.MenuButton>\n </Sidebar.Footer>\n </Sidebar>\n <DemoMain />\n </Sidebar.Provider>\n </DemoContainer>",
4567
+ "<DemoContainer>\n <Sidebar.Provider\n defaultOpen\n resizable\n defaultWidth={240}\n minWidth={180}\n maxWidth={400}\n className=\"min-h-0! h-full\"\n >\n <Sidebar>\n <Sidebar.Header>\n <BrandLogo />\n </Sidebar.Header>\n <Sidebar.Content>\n <Sidebar.Group>\n <Sidebar.Menu>\n <Sidebar.MenuButton icon={HouseIcon} active>\n Home\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={ChartBarIcon}>\n Analytics\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={GlobeIcon}>\n Domains\n </Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.Group>\n </Sidebar.Content>\n <Sidebar.ResizeHandle />\n </Sidebar>\n <DemoMain>\n <p className=\"text-sm\">Drag the sidebar edge to resize</p>\n </DemoMain>\n </Sidebar.Provider>\n </DemoContainer>",
4568
+ "<DemoContainer>\n <Sidebar.Provider defaultOpen side=\"right\" className=\"min-h-0! h-full\">\n <DemoMain>\n <p className=\"text-sm\">Sidebar on the right</p>\n </DemoMain>\n <Sidebar>\n <Sidebar.Content>\n <Sidebar.Group>\n <Sidebar.GroupLabel>Details</Sidebar.GroupLabel>\n <Sidebar.Menu>\n <Sidebar.MenuButton icon={GearIcon} active>\n Properties\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={ChartBarIcon}>\n Metrics\n </Sidebar.MenuButton>\n <Sidebar.MenuButton icon={BellIcon}>Alerts</Sidebar.MenuButton>\n </Sidebar.Menu>\n </Sidebar.Group>\n </Sidebar.Content>\n </Sidebar>\n </Sidebar.Provider>\n </DemoContainer>"
4569
+ ],
4203
4570
  "colors": [
4204
4571
  "bg-sf-base",
4205
4572
  "bg-sf-brand",
@@ -5461,7 +5828,19 @@
5461
5828
  "default": "full"
5462
5829
  }
5463
5830
  },
5464
- "examples": [],
5831
+ "examples": [
5832
+ "<SignalFlareAILogo className=\"w-72\" />",
5833
+ "<SignalFlareAILogo variant=\"glyph\" className=\"w-16\" />",
5834
+ "<div className=\"flex flex-wrap items-center gap-8\">\n <SignalFlareAILogo className=\"w-32\" color=\"brand\" />\n <SignalFlareAILogo className=\"w-32\" color=\"mono\" />\n <div className=\"rounded-lg bg-white p-4\">\n <SignalFlareAILogo className=\"w-32\" color=\"black\" />\n </div>\n <div className=\"rounded-lg bg-black p-4\">\n <SignalFlareAILogo className=\"w-32\" color=\"white\" />\n </div>\n </div>",
5835
+ "<div className=\"flex flex-wrap items-center gap-8\">\n <SignalFlareAILogo variant=\"glyph\" className=\"w-10\" color=\"brand\" />\n <SignalFlareAILogo variant=\"glyph\" className=\"w-10\" color=\"mono\" />\n <div className=\"rounded-lg bg-white p-4\">\n <SignalFlareAILogo variant=\"glyph\" className=\"w-10\" color=\"black\" />\n </div>\n <div className=\"rounded-lg bg-black p-4\">\n <SignalFlareAILogo variant=\"glyph\" className=\"w-10\" color=\"white\" />\n </div>\n </div>",
5836
+ "<div className=\"flex flex-wrap items-end gap-6\">\n <SignalFlareAILogo className=\"w-24\" />\n <SignalFlareAILogo className=\"w-36\" />\n <SignalFlareAILogo className=\"w-52\" />\n </div>",
5837
+ "<div className=\"flex items-center gap-4\">\n <DropdownMenu>\n <DropdownMenu.Trigger>\n <button\n type=\"button\"\n className=\"flex items-center gap-2 rounded-lg bg-[#4188ff] px-4 py-3 text-white transition-opacity hover:opacity-80\"\n >\n <SignalFlareAILogo variant=\"glyph\" color=\"white\" className=\"w-6\" />\n <span className=\"font-medium\">Logo</span>\n </button>\n </DropdownMenu.Trigger>\n <DropdownMenu.Content>\n <DropdownMenu.Item\n icon={MapPinIcon}\n onSelect={() =>\n copyToClipboard(\n generateSignalFlareAILogoSvg({ variant: \"glyph\" }),\n \"glyph\"\n )\n }\n >\n {copied === \"glyph\" ? \"Copied!\" : \"Copy icon as SVG\"}\n </DropdownMenu.Item>\n <DropdownMenu.Item\n icon={CodeIcon}\n onSelect={() =>\n copyToClipboard(\n generateSignalFlareAILogoSvg({ variant: \"full\" }),\n \"full\"\n )\n }\n >\n {copied === \"full\" ? \"Copied!\" : \"Copy full logo as SVG\"}\n </DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item\n icon={ArrowSquareOutIcon}\n onSelect={() =>\n window.open(\"https://signalflare.ai\", \"_blank\", \"noopener\")\n }\n >\n Visit SignalFlare AI\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu>\n\n <span className=\"text-sm text-sf-subtle\">\n Click to open the brand assets menu\n </span>\n </div>",
5838
+ "<PoweredBySignalFlareAI />",
5839
+ "<div className=\"flex flex-wrap items-center gap-4\">\n <PoweredBySignalFlareAI color=\"brand\" />\n <PoweredBySignalFlareAI color=\"mono\" />\n <PoweredBySignalFlareAI color=\"black\" />\n <div className=\"rounded-lg bg-black p-3\">\n <PoweredBySignalFlareAI color=\"white\" />\n </div>\n </div>",
5840
+ "<footer className=\"flex w-full items-center justify-between rounded-lg border border-sf-line bg-sf-elevated px-6 py-4\">\n <span className=\"text-sm text-sf-subtle\">\n &copy; 2026 Your Company. All rights reserved.\n </span>\n <PoweredBySignalFlareAI />\n </footer>",
5841
+ "<PoweredByNavigator />",
5842
+ "<div className=\"flex flex-wrap items-center gap-4\">\n <PoweredByNavigator color=\"brand\" />\n <PoweredByNavigator color=\"mono\" />\n <PoweredByNavigator color=\"black\" />\n <div className=\"rounded-lg bg-black p-3\">\n <PoweredByNavigator color=\"white\" />\n </div>\n </div>"
5843
+ ],
5465
5844
  "colors": ["bg-sf-base", "ring-sf-line", "text-sf-default"]
5466
5845
  },
5467
5846
  "Sparkline": {
@@ -5480,13 +5859,17 @@
5480
5859
  "description": "Child elements"
5481
5860
  }
5482
5861
  },
5483
- "examples": [],
5862
+ "examples": [
5863
+ "<Sparkline echarts={echarts} data={sample} isDarkMode={isDarkMode} />",
5864
+ "<Sparkline\n echarts={echarts}\n data={sample}\n variant=\"area\"\n isDarkMode={isDarkMode}\n />",
5865
+ "<Sparkline\n echarts={echarts}\n data={sample}\n variant=\"bars\"\n isDarkMode={isDarkMode}\n />"
5866
+ ],
5484
5867
  "colors": []
5485
5868
  },
5486
5869
  "StatCard": {
5487
5870
  "name": "StatCard",
5488
5871
  "type": "component",
5489
- "description": "StatCard — compact KPI tile displaying a label, a primary value, and an optional delta + trend sparkline.",
5872
+ "description": "StatCard — compact KPI tile displaying a label, a primary value, and an optional delta + trend sparkline. Uses pretext-driven `Text` for consistent spacing and wrapping: - Labels use `wrap=\"balance\"` for even multiline breaks - Values use `wrap=\"shrink\"` so sparklines tuck tight against numbers - Hints use `wrap=\"natural\"` (numeric content rarely wraps)",
5490
5873
  "importPath": "@signalflare-ai/ui",
5491
5874
  "category": "Other",
5492
5875
  "props": {
@@ -5533,7 +5916,12 @@
5533
5916
  "description": "Additional CSS classes merged via `cn()`."
5534
5917
  }
5535
5918
  },
5536
- "examples": [],
5919
+ "examples": [
5920
+ "<StatCard\n label=\"Active users\"\n value=\"12,384\"\n delta={{ value: 0.12, label: \"vs last week\" }}\n />",
5921
+ "<StatCard\n label=\"Error rate\"\n value=\"2.1%\"\n delta={{ value: -0.08, label: \"vs last week\", positiveDirection: \"down\" }}\n />",
5922
+ "<StatCard size=\"sm\" label=\"MRR\" value=\"$128,420\" hint=\"30-day avg\" />",
5923
+ "<StatCard label=\"Signups\" value=\"—\" loading />"
5924
+ ],
5537
5925
  "colors": [
5538
5926
  "bg-sf-elevated",
5539
5927
  "bg-sf-fill",
@@ -5567,7 +5955,11 @@
5567
5955
  "description": "Content rendered inside the surface."
5568
5956
  }
5569
5957
  },
5570
- "examples": [],
5958
+ "examples": [
5959
+ "<Surface className=\"rounded-lg p-6\">\n <Text size=\"lg\" bold>\n Surface Component\n </Text>\n <div className=\"mt-2\">\n <Text variant=\"secondary\">\n A container with consistent elevation and border styling.\n </Text>\n </div>\n </Surface>",
5960
+ "<div className=\"flex flex-col gap-4\">\n <Surface as=\"section\" className=\"rounded-lg p-4\">\n <Text bold>As section element</Text>\n </Surface>\n <Surface as=\"article\" className=\"rounded-lg p-4\">\n <Text bold>As article element</Text>\n </Surface>\n <Surface as=\"aside\" className=\"rounded-lg p-4\">\n <Text bold>As aside element</Text>\n </Surface>\n </div>",
5961
+ "<Surface className=\"rounded-lg p-6\">\n <Text bold>Outer Surface</Text>\n <Surface className=\"mt-4 rounded-md bg-sf-elevated p-4\">\n <Text variant=\"secondary\">Nested Surface</Text>\n </Surface>\n </Surface>"
5962
+ ],
5571
5963
  "colors": ["bg-sf-base", "ring-sf-line"]
5572
5964
  },
5573
5965
  "Switch": {
@@ -5674,7 +6066,12 @@
5674
6066
  "description": "Callback when switch is clicked"
5675
6067
  }
5676
6068
  },
5677
- "examples": [],
6069
+ "examples": [
6070
+ "<Switch label=\"Switch\" checked={checked} onCheckedChange={setChecked} />",
6071
+ "<Switch label=\"Switch\" checked={false} onCheckedChange={() => {}} />",
6072
+ "<Switch label=\"Switch\" checked={true} onCheckedChange={() => {}} />",
6073
+ "<Switch label=\"Disabled\" checked={false} disabled />"
6074
+ ],
5678
6075
  "colors": [
5679
6076
  "bg-sf-brand",
5680
6077
  "bg-sf-brand-hover",
@@ -5763,7 +6160,13 @@
5763
6160
  "description": "Child elements"
5764
6161
  }
5765
6162
  },
5766
- "examples": [],
6163
+ "examples": [
6164
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <Table>\n <Table.Header>\n <Table.Row>\n <Table.Head>Subject</Table.Head>\n <Table.Head>From</Table.Head>\n <Table.Head>Date</Table.Head>\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {emailData.slice(0, 3).map((row) => (\n <Table.Row key={row.id}>\n <Table.Cell>{row.subject}</Table.Cell>\n <Table.Cell>{row.from}</Table.Cell>\n <Table.Cell>{row.date}</Table.Cell>\n </Table.Row>\n ))}\n </Table.Body>\n </Table>\n </LayerCard.Primary>\n </LayerCard>",
6165
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <Table>\n <Table.Header>\n <Table.Row>\n <Table.CheckHead\n checked={selectedIds.size === rows.length}\n indeterminate={\n selectedIds.size > 0 && selectedIds.size < rows.length\n }\n onValueChange={toggleAll}\n aria-label=\"Select all rows\"\n />\n <Table.Head>Subject</Table.Head>\n <Table.Head>From</Table.Head>\n <Table.Head>Date</Table.Head>\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {rows.map((row) => (\n <Table.Row key={row.id}>\n <Table.CheckCell\n checked={selectedIds.has(row.id)}\n onValueChange={() => toggleRow(row.id)}\n aria-label={`Select ${row.subject}`}\n />\n <Table.Cell>{row.subject}</Table.Cell>\n <Table.Cell>{row.from}</Table.Cell>\n <Table.Cell>{row.date}</Table.Cell>\n </Table.Row>\n ))}\n </Table.Body>\n </Table>\n </LayerCard.Primary>\n </LayerCard>",
6166
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <Table>\n <Table.Header>\n <Table.Row>\n <Table.CheckHead\n checked={selectedIds.size === rows.length}\n indeterminate={\n selectedIds.size > 0 && selectedIds.size < rows.length\n }\n onValueChange={toggleAll}\n aria-label=\"Select all rows\"\n />\n <Table.Head>Subject</Table.Head>\n <Table.Head>From</Table.Head>\n <Table.Head>Date</Table.Head>\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {rows.map((row) => (\n <Table.Row\n key={row.id}\n variant={selectedIds.has(row.id) ? \"selected\" : \"default\"}\n >\n <Table.CheckCell\n checked={selectedIds.has(row.id)}\n onValueChange={() => toggleRow(row.id)}\n aria-label={`Select ${row.subject}`}\n />\n <Table.Cell>{row.subject}</Table.Cell>\n <Table.Cell>{row.from}</Table.Cell>\n <Table.Cell>{row.date}</Table.Cell>\n </Table.Row>\n ))}\n </Table.Body>\n </Table>\n </LayerCard.Primary>\n </LayerCard>",
6167
+ "<LayerCard>\n <LayerCard.Primary className=\"p-0\">\n <Table layout=\"fixed\">\n <colgroup>\n <col />\n <col className=\"w-[150px]\" />\n <col className=\"w-[150px]\" />\n </colgroup>\n <Table.Header>\n <Table.Row>\n <Table.Head>Subject</Table.Head>\n <Table.Head>From</Table.Head>\n <Table.Head>Date</Table.Head>\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {emailData.map((row) => (\n <Table.Row key={row.id}>\n <Table.Cell>{row.subject}</Table.Cell>\n <Table.Cell>{row.from}</Table.Cell>\n <Table.Cell>{row.date}</Table.Cell>\n </Table.Row>\n ))}\n </Table.Body>\n </Table>\n </LayerCard.Primary>\n </LayerCard>",
6168
+ "<LayerCard>\n <LayerCard.Primary className=\"w-full overflow-x-auto p-0\">\n <Table layout=\"fixed\">\n <colgroup>\n <col />{\" \"}\n {/* Checkbox column - width handled by Table.CheckHead/CheckCell */}\n <col />\n <col style={{ width: \"150px\" }} />\n <col style={{ width: \"120px\" }} />\n <col style={{ width: \"50px\" }} />\n </colgroup>\n <Table.Header>\n <Table.Row>\n <Table.CheckHead\n checked={selectedIds.size === emailData.length}\n indeterminate={\n selectedIds.size > 0 && selectedIds.size < emailData.length\n }\n onValueChange={toggleAll}\n aria-label=\"Select all rows\"\n />\n <Table.Head>Subject</Table.Head>\n <Table.Head>From</Table.Head>\n <Table.Head>Date</Table.Head>\n <Table.Head />\n </Table.Row>\n </Table.Header>\n <Table.Body>\n {emailData.map((row) => (\n <Table.Row\n key={row.id}\n variant={selectedIds.has(row.id) ? \"selected\" : \"default\"}\n >\n <Table.CheckCell\n checked={selectedIds.has(row.id)}\n onValueChange={() => toggleRow(row.id)}\n aria-label={`Select ${row.subject}`}\n />\n <Table.Cell>\n <div className=\"flex items-center gap-2\">\n <EnvelopeSimpleIcon size={16} />\n <span className=\"truncate\">{row.subject}</span>\n {row.tags && (\n <div className=\"ml-2 inline-flex gap-1\">\n {row.tags.map((tag) => (\n <Badge key={tag}>{tag}</Badge>\n ))}\n </div>\n )}\n </div>\n </Table.Cell>\n <Table.Cell>\n <span className=\"truncate\">{row.from}</span>\n </Table.Cell>\n <Table.Cell>\n <span className=\"truncate\">{row.date}</span>\n </Table.Cell>\n <Table.Cell className=\"text-right\">\n <DropdownMenu>\n <DropdownMenu.Trigger\n render={\n <Button\n variant=\"ghost\"\n size=\"sm\"\n shape=\"square\"\n aria-label=\"More options\"\n >\n <DotsThreeIcon weight=\"bold\" size={16} />\n </Button>\n }\n />\n <DropdownMenu.Content>\n <DropdownMenu.Item icon={EyeIcon}>View</DropdownMenu.Item>\n <DropdownMenu.Item icon={PencilSimpleIcon}>\n Edit\n </DropdownMenu.Item>\n <DropdownMenu.Separator />\n <DropdownMenu.Item icon={TrashIcon} variant=\"danger\">\n Delete\n </DropdownMenu.Item>\n </DropdownMenu.Content>\n </DropdownMenu>\n </Table.Cell>\n </Table.Row>\n ))}\n </Table.Body>\n </Table>\n </LayerCard.Primary>\n </LayerCard>"
6169
+ ],
5767
6170
  "colors": [
5768
6171
  "bg-sf-base",
5769
6172
  "bg-sf-ring",
@@ -5873,7 +6276,15 @@
5873
6276
  "description": "Callback when active tab changes"
5874
6277
  }
5875
6278
  },
5876
- "examples": [],
6279
+ "examples": [
6280
+ "<div className=\"flex flex-col gap-6\">\n <div>\n <p className=\"mb-2 text-sm text-sf-subtle\">Segmented (default)</p>\n <Tabs\n variant=\"segmented\"\n tabs={[\n { label: \"Tab 1\", value: \"tab1\" },\n { label: \"Tab 2\", value: \"tab2\" },\n { label: \"Tab 3\", value: \"tab3\" },\n ]}\n selectedValue=\"tab1\"\n />\n </div>\n <div>\n <p className=\"mb-2 text-sm text-sf-subtle\">Underline</p>\n <Tabs\n variant=\"underline\"\n tabs={[\n { label: \"Tab 1\", value: \"tab1\" },\n { label: \"Tab 2\", value: \"tab2\" },\n { label: \"Tab 3\", value: \"tab3\" },\n ]}\n selectedValue=\"tab1\"\n />\n </div>\n <div>\n <p className=\"mb-2 text-sm text-sf-subtle\">Pill</p>\n <Tabs\n variant=\"pill\"\n tabs={[\n { label: \"Tab 1\", value: \"tab1\" },\n { label: \"Tab 2\", value: \"tab2\" },\n { label: \"Tab 3\", value: \"tab3\" },\n ]}\n selectedValue=\"tab1\"\n />\n </div>\n </div>",
6281
+ "<Tabs\n variant=\"segmented\"\n tabs={[\n { label: \"Tab 1\", value: \"tab1\" },\n { label: \"Tab 2\", value: \"tab2\" },\n { label: \"Tab 3\", value: \"tab3\" },\n ]}\n selectedValue=\"tab1\"\n />",
6282
+ "<Tabs\n variant=\"underline\"\n tabs={[\n { label: \"Tab 1\", value: \"tab1\" },\n { label: \"Tab 2\", value: \"tab2\" },\n { label: \"Tab 3\", value: \"tab3\" },\n ]}\n selectedValue=\"tab1\"\n />",
6283
+ "<div className=\"space-y-4\">\n <Tabs\n tabs={[\n { label: \"Tab 1\", value: \"tab1\" },\n { label: \"Tab 2\", value: \"tab2\" },\n { label: \"Tab 3\", value: \"tab3\" },\n ]}\n value={activeTab}\n onValueChange={setActiveTab}\n />\n <p className=\"text-sm text-sf-subtle\">\n Active tab: <code className=\"text-sm\">{activeTab}</code>\n </p>\n </div>",
6284
+ "<Tabs\n tabs={[\n { label: \"Overview\", value: \"overview\" },\n { label: \"Analytics\", value: \"analytics\" },\n { label: \"Reports\", value: \"reports\" },\n { label: \"Notifications\", value: \"notifications\" },\n { label: \"Settings\", value: \"settings\" },\n { label: \"Billing\", value: \"billing\" },\n ]}\n selectedValue=\"overview\"\n />",
6285
+ "<Tabs\n tabs={[\n {\n label: \"Regular Tab\",\n value: \"tab1\",\n },\n {\n label: \"Link Tab\",\n render: (props) => <a {...props} href=\"#tab2\" />,\n value: \"tab2\",\n },\n {\n label: \"Another Link\",\n render: (props) => <a {...props} href=\"#tab3\" />,\n value: \"tab3\",\n },\n ]}\n selectedValue=\"tab1\"\n />",
6286
+ "<Tabs\n variant=\"pill\"\n tabs={[\n { label: \"Overview\", value: \"overview\" },\n { label: \"Analytics\", value: \"analytics\" },\n { label: \"Reports\", value: \"reports\" },\n ]}\n selectedValue=\"overview\"\n />"
6287
+ ],
5877
6288
  "colors": [
5878
6289
  "bg-sf-brand",
5879
6290
  "bg-sf-overlay",
@@ -5989,9 +6400,21 @@
5989
6400
  "type": "ReactNode",
5990
6401
  "optional": true,
5991
6402
  "description": "Text content."
6403
+ },
6404
+ "wrap": {
6405
+ "type": "MeasuredTextMode | boolean",
6406
+ "optional": true,
6407
+ "description": "Text layout strategy using pretext-driven measurement.\n- `\"natural\"` — No measurement, normal browser wrapping (default for body).\n- `\"balance\"` — Even wrapping, smallest maxWidth without adding lines (default for headings).\n- `\"shrink\"` — Hug widest natural line (maxWidth = line width). Good for chat bubbles.\n- `\"reserve\"` — Reserve height based on line count. Good for streaming text."
6408
+ },
6409
+ "reserveLines": {
6410
+ "type": "number",
6411
+ "optional": true,
6412
+ "description": "For `wrap=\"reserve\"`: reserve this many lines of height. If omitted, measures current content to determine line count."
5992
6413
  }
5993
6414
  },
5994
- "examples": [],
6415
+ "examples": [
6416
+ "<div className=\"grid w-full grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text variant=\"heading1\">Heading 1</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-3xl (30px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text variant=\"heading2\">Heading 2</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-2xl (24px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text variant=\"heading3\">Heading 3</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-lg (16px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text>Body</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-base (14px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text bold>Body bold</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-base (14px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text size=\"lg\">Body lg</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-lg (16px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text size=\"sm\">Body sm</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-sm (13px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text size=\"xs\">Body xs</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-xs (12px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text variant=\"secondary\">Body secondary</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-base (14px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text variant=\"mono\">Monospace</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-sm (13px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text variant=\"mono\" size=\"lg\">\n Monospace lg\n </Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-base (14px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text variant=\"mono-secondary\">Monospace secondary</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-sm (13px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text variant=\"success\">Success</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-base (14px)</p>\n </div>\n <div className=\"flex flex-col justify-end gap-1 rounded-lg border border-sf-line bg-sf-base p-4\">\n <Text variant=\"error\">Error</Text>\n <p className=\"font-mono text-xs text-sf-subtle\">text-base (14px)</p>\n </div>\n </div>"
6417
+ ],
5995
6418
  "colors": [
5996
6419
  "text-sf-danger",
5997
6420
  "text-sf-default",
@@ -6208,7 +6631,11 @@
6208
6631
  "description": "Content to display in the tooltip"
6209
6632
  }
6210
6633
  },
6211
- "examples": [],
6634
+ "examples": [
6635
+ "<TooltipProvider>\n <Tooltip content=\"Add new item\">\n <Button shape=\"square\" icon={PlusIcon} aria-label=\"Add new item\" />\n </Tooltip>\n </TooltipProvider>",
6636
+ "<TooltipProvider>\n <Tooltip content=\"Add\">\n <Button shape=\"square\" icon={PlusIcon} aria-label=\"Add\" />\n </Tooltip>\n </TooltipProvider>",
6637
+ "<TooltipProvider>\n <div className=\"flex gap-2\">\n <Tooltip content=\"Add\">\n <Button shape=\"square\" icon={PlusIcon} aria-label=\"Add\" />\n </Tooltip>\n <Tooltip content=\"Change language\">\n <Button\n shape=\"square\"\n icon={TranslateIcon}\n aria-label=\"Change language\"\n />\n </Tooltip>\n </div>\n </TooltipProvider>"
6638
+ ],
6212
6639
  "colors": [
6213
6640
  "bg-sf-elevated",
6214
6641
  "fill-sf-elevated",
@@ -6377,7 +6804,10 @@
6377
6804
  "values": ["select", "cycle"]
6378
6805
  }
6379
6806
  },
6380
- "examples": [],
6807
+ "examples": [
6808
+ "<div className=\"flex flex-col gap-3 w-full\">\n {/* Controls */}\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-2\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-xs font-medium text-sf-subtle\">Scenario:</span>\n {([\"full\", \"question\", \"plan\"] as Scenario[]).map((s) => (\n <button\n key={s}\n type=\"button\"\n onClick={() => handleScenario(s)}\n className={[\n \"rounded-full px-2.5 py-1 text-xs font-medium transition-colors border\",\n scenario === s\n ? \"bg-sf-brand text-white border-sf-brand\"\n : \"border-sf-line bg-sf-elevated text-sf-strong hover:bg-sf-tint\",\n ].join(\" \")}\n >\n {SCENARIO_LABELS[s]}\n </button>\n ))}\n </div>\n\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-xs font-medium text-sf-subtle\">HITL:</span>\n {([\"inline\", \"back-layer\"] as Placement[]).map((p) => (\n <button\n key={p}\n type=\"button\"\n onClick={() => handlePlacement(p)}\n className={[\n \"rounded-full px-2.5 py-1 text-xs font-medium transition-colors border\",\n placement === p\n ? \"bg-sf-brand text-white border-sf-brand\"\n : \"border-sf-line bg-sf-elevated text-sf-strong hover:bg-sf-tint\",\n ].join(\" \")}\n >\n {PLACEMENT_LABELS[p]}\n </button>\n ))}\n </div>\n\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-xs font-medium text-sf-subtle\">Activity:</span>\n {(\n [\n { value: false, label: \"Stacked\" },\n { value: true, label: \"Grouped\" },\n ] as const\n ).map((opt) => (\n <button\n key={opt.label}\n type=\"button\"\n onClick={() => handleGroupActivity(opt.value)}\n className={[\n \"rounded-full px-2.5 py-1 text-xs font-medium transition-colors border\",\n groupActivity === opt.value\n ? \"bg-sf-brand text-white border-sf-brand\"\n : \"border-sf-line bg-sf-elevated text-sf-strong hover:bg-sf-tint\",\n ].join(\" \")}\n >\n {opt.label}\n </button>\n ))}\n </div>\n\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-xs font-medium text-sf-subtle\">Pickers:</span>\n {([\"select\", \"cycle\"] as const).map((v) => (\n <button\n key={v}\n type=\"button\"\n onClick={() => setPickerVariant(v)}\n className={[\n \"rounded-full px-2.5 py-1 text-xs font-medium transition-colors border\",\n pickerVariant === v\n ? \"bg-sf-brand text-white border-sf-brand\"\n : \"border-sf-line bg-sf-elevated text-sf-strong hover:bg-sf-tint\",\n ].join(\" \")}\n >\n {v === \"select\" ? \"Dropdown\" : \"Cycle\"}\n </button>\n ))}\n </div>\n </div>\n\n {/* The block — key forces remount + clean state on every scenario/placement change */}\n <div style={{ height: 560 }}>\n <AgentHarness\n key={runKey}\n adapter={adapter}\n hitlPlacement={placement}\n groupActivity={groupActivity}\n showUsage\n showTaskList\n availableModes={[\n { modeId: \"build\", modeName: \"Build\" },\n { modeId: \"plan\", modeName: \"Plan\" },\n { modeId: \"research\", modeName: \"Research\" },\n ]}\n availableModels={[\n { value: \"anthropic/claude-sonnet-4\", label: \"Claude Sonnet 4\" },\n { value: \"anthropic/claude-opus-4\", label: \"Claude Opus 4\" },\n { value: \"openai/gpt-4o\", label: \"GPT-4o\" },\n ]}\n modeVariant={pickerVariant}\n modelVariant={pickerVariant}\n placeholder=\"Type a message…\"\n suggestions={[\n \"Refactor the auth module\",\n \"Explain the JWT flow\",\n \"Add refresh token rotation\",\n ]}\n footer=\"AI can make mistakes. Review changes before applying.\"\n />\n </div>\n </div>",
6809
+ "<div style={{ height: 400 }}>\n <AgentHarness\n adapter={adapter}\n hitlPlacement=\"inline\"\n showUsage={false}\n showTaskList={false}\n placeholder=\"Send a message…\"\n emptyState={\n <div className=\"flex flex-col items-center gap-2\">\n <span className=\"text-3xl\">🤖</span>\n <p className=\"text-sm text-sf-subtle\">Ready when you are.</p>\n </div>\n }\n />\n </div>"
6810
+ ],
6381
6811
  "colors": [
6382
6812
  "bg-sf-base",
6383
6813
  "bg-sf-elevated",
@@ -6469,7 +6899,11 @@
6469
6899
  "description": "Empty state shown when no agents have run yet."
6470
6900
  }
6471
6901
  },
6472
- "examples": [],
6902
+ "examples": [
6903
+ "<div className=\"flex flex-col gap-3 w-full\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-sf-subtle\">\n Simulated multi-agent mission\n </span>\n <button\n type=\"button\"\n onClick={replay}\n className=\"rounded-full border border-sf-line bg-sf-elevated px-2.5 py-1 text-xs text-sf-strong hover:bg-sf-tint transition-colors\"\n >\n ↺ Replay\n </button>\n </div>\n <div style={{ height: 520 }}>\n <Commander\n key={runKey}\n adapter={adapter}\n title=\"Refactor auth module\"\n pixelsPerSecond={20}\n layout=\"timeline-cards\"\n />\n </div>\n </div>",
6904
+ "<div style={{ height: 300 }}>\n <Commander\n adapter={adapter}\n title=\"Refactor auth module\"\n pixelsPerSecond={20}\n layout=\"timeline-only\"\n />\n </div>",
6905
+ "<div style={{ height: 280 }}>\n <Commander\n adapter={adapter}\n title=\"Refactor auth module\"\n pixelsPerSecond={20}\n layout=\"cards-only\"\n />\n </div>"
6906
+ ],
6473
6907
  "colors": ["bg-sf-base", "border-sf-line", "text-sf-subtle"],
6474
6908
  "files": ["commander/commander.tsx", "commander/commander.stories.tsx"],
6475
6909
  "dependencies": []
@@ -6504,7 +6938,9 @@
6504
6938
  "optional": true
6505
6939
  }
6506
6940
  },
6507
- "examples": [],
6941
+ "examples": [
6942
+ "<DashboardGrid>\n <DashboardGrid.Cell span={3}>\n <StatCard\n label=\"Active users\"\n value=\"12,384\"\n delta={{ value: 0.12, label: \"vs last week\" }}\n />\n </DashboardGrid.Cell>\n <DashboardGrid.Cell span={3}>\n <StatCard\n label=\"MRR\"\n value=\"$128,420\"\n delta={{ value: 0.04, label: \"vs last month\" }}\n />\n </DashboardGrid.Cell>\n <DashboardGrid.Cell span={3}>\n <StatCard\n label=\"Error rate\"\n value=\"2.1%\"\n delta={{\n value: -0.08,\n label: \"vs last week\",\n positiveDirection: \"down\",\n }}\n />\n </DashboardGrid.Cell>\n <DashboardGrid.Cell span={3}>\n <StatCard label=\"Signups\" value=\"1,284\" hint=\"30-day total\" />\n </DashboardGrid.Cell>\n <DashboardGrid.Cell span={8}>\n <Surface className=\"flex h-48 items-center justify-center p-4 text-sm text-sf-subtle\">\n Primary chart area (span=8)\n </Surface>\n </DashboardGrid.Cell>\n <DashboardGrid.Cell span={4}>\n <Surface className=\"flex h-48 items-center justify-center p-4 text-sm text-sf-subtle\">\n Secondary (span=4)\n </Surface>\n </DashboardGrid.Cell>\n </DashboardGrid>"
6943
+ ],
6508
6944
  "colors": [],
6509
6945
  "subComponents": {
6510
6946
  "Row": {
@@ -6604,7 +7040,11 @@
6604
7040
  "description": "Error message to display if the delete action fails"
6605
7041
  }
6606
7042
  },
6607
- "examples": [],
7043
+ "examples": [
7044
+ "<>\n <Button variant=\"destructive\" onClick={() => setOpen(true)}>\n Delete Zone\n </Button>\n <DeleteResource\n open={open}\n onOpenChange={setOpen}\n resourceType=\"Zone\"\n resourceName=\"example.com\"\n onDelete={handleDelete}\n isDeleting={isDeleting}\n />\n </>",
7045
+ "<>\n <Button variant=\"destructive\" onClick={() => setOpen(true)}>\n Delete Worker\n </Button>\n <DeleteResource\n open={open}\n onOpenChange={setOpen}\n resourceType=\"Worker\"\n resourceName=\"api-gateway-worker\"\n onDelete={handleDelete}\n isDeleting={isDeleting}\n />\n </>",
7046
+ "<>\n <Button variant=\"destructive\" onClick={() => setOpen(true)}>\n Delete Zone\n </Button>\n <DeleteResource\n open={open}\n onOpenChange={setOpen}\n resourceType=\"Zone\"\n resourceName=\"example.com\"\n onDelete={handleDelete}\n isDeleting={isDeleting}\n errorMessage={errorMsg}\n />\n </>"
7047
+ ],
6608
7048
  "colors": [
6609
7049
  "bg-sf-fill",
6610
7050
  "bg-sf-tint",
@@ -6702,7 +7142,10 @@
6702
7142
  "description": "Additional CSS classes merged via `cn()`."
6703
7143
  }
6704
7144
  },
6705
- "examples": [],
7145
+ "examples": [
7146
+ "<MetricsOverview\n title=\"Revenue overview\"\n description=\"Last 72 hours · hourly granularity\"\n kpis={[\n {\n id: \"mrr\",\n label: \"MRR\",\n value: \"$128,420\",\n delta: { value: 0.12, label: \"vs last month\" },\n trend: (\n <Sparkline\n echarts={echarts}\n data={sparkData}\n variant=\"area\"\n isDarkMode={isDarkMode}\n />\n ),\n },\n {\n id: \"arpu\",\n label: \"ARPU\",\n value: \"$42.10\",\n delta: { value: 0.03, label: \"vs last month\" },\n },\n {\n id: \"churn\",\n label: \"Churn\",\n value: \"1.4%\",\n delta: {\n value: -0.01,\n label: \"vs last month\",\n positiveDirection: \"down\",\n },\n },\n {\n id: \"users\",\n label: \"Active users\",\n value: \"12,384\",\n delta: { value: 0.08, label: \"vs last week\" },\n },\n ]}\n chart={\n <TimeseriesChart\n echarts={echarts}\n data={[\n series(\"Revenue\", 0, ChartPalette.semantic(\"Neutral\", isDarkMode)),\n series(\"Cost\", 20, ChartPalette.semantic(\"Attention\", isDarkMode)),\n ]}\n height={260}\n gradient\n isDarkMode={isDarkMode}\n />\n }\n />",
7147
+ "<MetricsOverview\n title=\"Revenue overview\"\n loading\n kpis={[\n { id: \"mrr\", label: \"MRR\", value: \"—\" },\n { id: \"arpu\", label: \"ARPU\", value: \"—\" },\n { id: \"churn\", label: \"Churn\", value: \"—\" },\n { id: \"users\", label: \"Active users\", value: \"—\" },\n ]}\n />"
7148
+ ],
6706
7149
  "colors": ["bg-sf-elevated", "text-sf-strong", "text-sf-subtle"],
6707
7150
  "files": [
6708
7151
  "metrics-overview/metrics-overview.tsx",
@@ -6762,7 +7205,16 @@
6762
7205
  "optional": true
6763
7206
  }
6764
7207
  },
6765
- "examples": [],
7208
+ "examples": [
7209
+ "<PageHeader\n className=\"w-full\"\n breadcrumbs={\n <Breadcrumbs>\n <Breadcrumbs.Link icon={<HouseIcon size={16} />} href=\"#\">\n Workers & Pages\n </Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>cloudflare-dev-platform</Breadcrumbs.Current>\n </Breadcrumbs>\n }\n tabs={[\n { label: \"Overview\", value: \"overview\" },\n { label: \"Metrics\", value: \"metrics\" },\n { label: \"Deployments\", value: \"deployments\" },\n { label: \"Bindings\", value: \"bindings\" },\n { label: \"Observability\", value: \"observability\" },\n { label: \"Settings\", value: \"settings\" },\n ]}\n defaultTab=\"overview\"\n onValueChange={(v) => console.log(v)}\n >\n <Button icon={<CodeIcon />} className=\"h-8\">\n Edit code\n </Button>\n <Button icon={<GlobeIcon />} variant=\"primary\" className=\"h-8\">\n Visit\n </Button>\n </PageHeader>",
7210
+ "<PageHeader\n breadcrumbs={\n <Breadcrumbs>\n <Breadcrumbs.Link href=\"#\">Home</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>Dashboard</Breadcrumbs.Current>\n </Breadcrumbs>\n }\n />",
7211
+ "<PageHeader\n breadcrumbs={\n <Breadcrumbs>\n <Breadcrumbs.Link icon={<HouseIcon size={16} />} href=\"#\">\n Home\n </Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current icon={<GearIcon size={16} />}>\n Settings\n </Breadcrumbs.Current>\n </Breadcrumbs>\n }\n />",
7212
+ "<PageHeader\n breadcrumbs={\n <Breadcrumbs>\n <Breadcrumbs.Link href=\"#\">Home</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>Settings</Breadcrumbs.Current>\n </Breadcrumbs>\n }\n tabs={[\n { label: \"General\", value: \"general\" },\n { label: \"Security\", value: \"security\" },\n { label: \"Notifications\", value: \"notifications\" },\n ]}\n defaultTab=\"general\"\n />",
7213
+ "<PageHeader\n breadcrumbs={\n <Breadcrumbs>\n <Breadcrumbs.Link href=\"#\">Home</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Link href=\"#\">Projects</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>My Project</Breadcrumbs.Current>\n </Breadcrumbs>\n }\n tabs={[\n { label: \"Overview\", value: \"overview\" },\n { label: \"Settings\", value: \"settings\" },\n ]}\n defaultTab=\"overview\"\n >\n <Button variant=\"primary\" size=\"base\">\n Deploy\n </Button>\n </PageHeader>",
7214
+ "<PageHeader\n breadcrumbs={\n <Breadcrumbs>\n <Breadcrumbs.Link href=\"#\">Home</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Link href=\"#\">Products</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>Page title</Breadcrumbs.Current>\n </Breadcrumbs>\n }\n title=\"Page title\"\n />",
7215
+ "<PageHeader\n breadcrumbs={\n <Breadcrumbs>\n <Breadcrumbs.Link href=\"#\">Home</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Link href=\"#\">Products</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>Page title</Breadcrumbs.Current>\n </Breadcrumbs>\n }\n title=\"Page title\"\n description=\"Action-led, value-oriented description of what this page does. Optional second sentence with use cases or prerequisites.\"\n />",
7216
+ "<PageHeader\n breadcrumbs={\n <Breadcrumbs>\n <Breadcrumbs.Link href=\"#\">Home</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Link href=\"#\">Products</Breadcrumbs.Link>\n <Breadcrumbs.Separator />\n <Breadcrumbs.Current>Page title</Breadcrumbs.Current>\n </Breadcrumbs>\n }\n title=\"Page title\"\n description=\"Action-led, value-oriented description of what this page does.\"\n tabs={[\n { label: \"Overview\", value: \"overview\" },\n { label: \"Analytics\", value: \"analytics\" },\n { label: \"Settings\", value: \"settings\" },\n ]}\n defaultTab=\"overview\"\n >\n <Button variant=\"outline\" size=\"sm\">\n Export\n </Button>\n <Button variant=\"primary\" size=\"sm\" icon={<PlusIcon size={16} />}>\n New Item\n </Button>\n </PageHeader>"
7217
+ ],
6766
7218
  "colors": ["border-sf-line", "text-sf-default", "text-sf-subtle"],
6767
7219
  "files": [
6768
7220
  "page-header/page-header.tsx",