@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
@@ -1,98 +0,0 @@
1
- /**
2
- * AUTO-GENERATED FILE - DO NOT EDIT DIRECTLY
3
- *
4
- * This file is generated by the theme generator.
5
- * To modify tokens, edit: scripts/theme-generator/config.ts
6
- * Then run: bun run codegen:themes
7
- */
8
-
9
- [data-theme="blue-tint"] {
10
- --text-color-sf-default: light-dark(oklch(0.145 0 0), oklch(0.985 0 0));
11
- --text-color-sf-strong: light-dark(oklch(0.556 0 0), oklch(0.65 0 0));
12
- --text-color-sf-subtle: light-dark(
13
- var(--color-neutral-500, oklch(55.6% 0 0)),
14
- var(--color-neutral-50, oklch(98.5% 0 0))
15
- );
16
- --text-color-sf-inactive: light-dark(
17
- var(--color-neutral-400, oklch(70.8% 0 0)),
18
- var(--color-neutral-600, oklch(70.8% 0 0))
19
- );
20
- --text-color-sf-danger: light-dark(
21
- oklch(0.577 0.245 27.325),
22
- oklch(0.55 0.18 25)
23
- );
24
- --text-color-sf-warning: light-dark(
25
- var(--color-yellow-800, oklch(47.6% 0.114 61.907)),
26
- var(--color-yellow-400, oklch(85.2% 0.199 91.936))
27
- );
28
- --color-sf-canvas: light-dark(
29
- var(--color-neutral-50, oklch(0.985 0 0)),
30
- var(--color-neutral-950, oklch(0.14 0 0))
31
- );
32
- --color-sf-base: light-dark(oklch(1 0 0), oklch(0.21 0.005 252));
33
- --color-sf-elevated: light-dark(oklch(0.99 0 0), oklch(0.24 0.005 252));
34
- --color-sf-recessed: light-dark(
35
- var(--color-neutral-250, oklch(0.9 0 0)),
36
- var(--color-neutral-750, oklch(0.31 0 0))
37
- );
38
- --color-sf-overlay: light-dark(
39
- var(--color-neutral-50, oklch(98.5% 0 0)),
40
- var(--color-neutral-950, oklch(0.1 0 0))
41
- );
42
- --color-sf-contrast: light-dark(oklch(0.205 0 0), oklch(0.55 0.01 40));
43
- --color-sf-control: light-dark(
44
- var(--color-white, #fff),
45
- var(--color-neutral-900, oklch(21% 0.006 285.885))
46
- );
47
- --color-sf-tint: light-dark(
48
- var(--color-neutral-150, oklch(0.96 0 0)),
49
- var(--color-neutral-850, oklch(0.23 0 0))
50
- );
51
- --color-sf-fill: light-dark(
52
- var(--color-neutral-200, oklch(92.2% 0 0)),
53
- var(--color-neutral-800, oklch(26.9% 0 0))
54
- );
55
- --color-sf-fill-hover: light-dark(
56
- var(--color-neutral-200, oklch(92.2% 0 0)),
57
- var(--color-neutral-700, oklch(37.1% 0 0))
58
- );
59
- --color-sf-brand: light-dark(
60
- oklch(0.5772 0.2324 260),
61
- oklch(0.5772 0.2324 260)
62
- );
63
- --color-sf-brand-hover: light-dark(
64
- var(--color-blue-700, oklch(48.8% 0.243 264.376)),
65
- var(--color-blue-700, oklch(48.8% 0.243 264.376))
66
- );
67
- --color-sf-line: light-dark(oklch(0.922 0 0), oklch(0.3 0.015 250));
68
- --color-sf-ring: light-dark(oklch(0.708 0 0), oklch(0.465 0.015 250));
69
- --color-sf-tip-shadow: light-dark(
70
- var(--color-gray-200, oklch(92.8% 0.006 264.531)),
71
- transparent
72
- );
73
- --color-sf-tip-stroke: light-dark(
74
- transparent,
75
- var(--color-neutral-800, oklch(26.9% 0 0))
76
- );
77
- --color-sf-info: light-dark(
78
- var(--color-blue-500, oklch(62.3% 0.214 259.815)),
79
- var(--color-blue-700, oklch(48.8% 0.243 264.376))
80
- );
81
- --color-sf-info-tint: light-dark(
82
- var(--color-blue-300, oklch(80.9% 0.105 251.813)),
83
- var(--color-blue-900, oklch(37.9% 0.146 265.522))
84
- );
85
- --color-sf-warning: light-dark(
86
- var(--color-yellow-500, oklch(79.5% 0.184 86.047)),
87
- var(--color-yellow-700, oklch(55.4% 0.135 66.442))
88
- );
89
- --color-sf-warning-tint: light-dark(
90
- var(--color-yellow-300, oklch(90.5% 0.182 98.111)),
91
- var(--color-yellow-900, oklch(42.1% 0.095 57.708))
92
- );
93
- --color-sf-danger: light-dark(oklch(0.577 0.245 27.325), oklch(0.55 0.18 25));
94
- --color-sf-danger-tint: light-dark(
95
- var(--color-red-300, oklch(80.8% 0.114 19.571)),
96
- var(--color-red-900, oklch(39.6% 0.141 25.723))
97
- );
98
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"switch-CzZBRBL7.js","names":[],"sources":["../src/components/switch/switch.tsx"],"sourcesContent":["import { Fieldset } from \"@base-ui/react/fieldset\";\nimport { Switch as BaseSwitch } from \"@base-ui/react/switch\";\nimport {\n forwardRef,\n type ButtonHTMLAttributes,\n type Ref,\n type ReactNode,\n createContext,\n useContext,\n} from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { Field } from \"../field/field\";\n\n/** Switch size and variant definitions mapping names to their Tailwind classes. */\nexport const SF_SWITCH_VARIANTS = {\n size: {\n sm: {\n classes: \"h-5.5 w-8.5\",\n description: \"Small switch for compact UIs\",\n },\n base: {\n classes: \"h-6.5 w-10.5\",\n description: \"Default switch size\",\n },\n lg: {\n classes: \"h-7.5 w-12.5\",\n description: \"Large switch for prominent toggles\",\n },\n },\n variant: {\n default: {\n classes: \"\",\n description: \"Default switch appearance\",\n },\n error: {\n classes: \"ring-sf-danger\",\n description: \"Error state for validation failures\",\n },\n },\n} as const;\n\nexport const SF_SWITCH_DEFAULT_VARIANTS = {\n size: \"base\",\n variant: \"default\",\n} as const;\n\n// Derived types from SF_SWITCH_VARIANTS\nexport type SFSwitchSize = keyof typeof SF_SWITCH_VARIANTS.size;\nexport type SFSwitchVariant = keyof typeof SF_SWITCH_VARIANTS.variant;\n\nexport interface SFSwitchVariantsProps {\n /**\n * Switch size.\n * - `\"sm\"` — Small for compact UIs\n * - `\"base\"` — Default size\n * - `\"lg\"` — Large for prominent toggles\n * @default \"base\"\n */\n size?: SFSwitchSize;\n /**\n * Visual variant.\n * - `\"default\"` — Standard switch appearance\n * - `\"error\"` — Error state for validation failures\n * @default \"default\"\n */\n variant?: SFSwitchVariant;\n}\n\nexport function switchVariants({\n size = SF_SWITCH_DEFAULT_VARIANTS.size,\n variant = SF_SWITCH_DEFAULT_VARIANTS.variant,\n}: SFSwitchVariantsProps = {}) {\n return cn(\n SF_SWITCH_VARIANTS.size[size].classes,\n SF_SWITCH_VARIANTS.variant[variant].classes\n );\n}\n\n// Legacy type aliases for backwards compatibility\nexport type SwitchSize = SFSwitchSize;\nexport type SwitchVariant = SFSwitchVariant;\n\n// Context for passing controlFirst from Group to Items\nconst SwitchGroupContext = createContext<{ controlFirst: boolean }>({\n controlFirst: true,\n});\n\n/**\n * Single switch component props (with built-in Field)\n *\n * Usage patterns:\n *\n * Basic usage:\n * ```tsx\n * <Switch label=\"Enable notifications\" checked={true} onCheckedChange={setChecked} />\n * ```\n *\n * Label first layout:\n * ```tsx\n * <Switch label=\"Dark mode\" checked={false} onCheckedChange={setChecked} controlFirst={false} />\n * ```\n *\n * Error variant (visual only, no error text):\n * ```tsx\n * <Switch label=\"Required setting\" variant=\"error\" checked={false} onCheckedChange={setChecked} />\n * ```\n *\n * @property {string} label - Label text for the switch (Field wrapper is built-in)\n * @property {boolean} [controlFirst] - When true (default), switch appears before label\n */\nexport type SwitchProps = Omit<\n ButtonHTMLAttributes<HTMLButtonElement>,\n \"children\"\n> & {\n /** Visual variant: \"default\" or \"error\" for validation failures (visual only, no error text) */\n variant?: SwitchVariant;\n /** Label content for the switch (Field wrapper is built-in) - can be a string or any React node. Optional when used standalone for visual-only purposes. */\n label?: ReactNode;\n /** Tooltip content to display next to the label via an info icon */\n labelTooltip?: ReactNode;\n /**\n * Whether the switch is required.\n * When explicitly false, shows \"(optional)\" text after the label.\n */\n required?: boolean;\n /** When true (default), switch appears before label. When false, label appears before switch. */\n controlFirst?: boolean;\n size?: SFSwitchSize;\n checked?: boolean;\n disabled?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n transitioning?: boolean;\n};\n\n/**\n * Switch group component props (with built-in Fieldset)\n *\n * Usage:\n * ```tsx\n * <Switch.Group\n * legend=\"Notification settings\"\n * error=\"You must enable at least one notification type\"\n * >\n * <Switch.Item label=\"Email notifications\" value=\"email\" />\n * <Switch.Item label=\"SMS notifications\" value=\"sms\" />\n * </Switch.Group>\n * ```\n */\nexport interface SwitchGroupProps {\n /** Legend text for the group */\n legend: string;\n /** Child Switch.Item components */\n children: ReactNode;\n /** Error message for the group (only appears in groups, not single switches) */\n error?: string;\n /** Helper text for the group */\n description?: ReactNode;\n /** Whether all switches in the group are disabled */\n disabled?: boolean;\n /** When true (default), switch appears before label. When false, label appears before switch. */\n controlFirst?: boolean;\n /** Additional CSS classes */\n className?: string;\n}\n\n/**\n * Individual switch item within a group\n */\nexport type SwitchItemProps = {\n /** Visual variant: \"default\" or \"error\" for validation failures */\n variant?: SwitchVariant;\n /** Label text displayed next to switch */\n label: string;\n /** Additional CSS classes for the label wrapper */\n className?: string;\n checked?: boolean;\n disabled?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n size?: SFSwitchSize;\n transitioning?: boolean;\n};\n\n// Single switch with built-in Field\nconst SwitchBase = forwardRef<HTMLButtonElement, SwitchProps>(\n (\n {\n className,\n checked,\n disabled,\n size = \"base\",\n variant = \"default\",\n label,\n labelTooltip,\n required,\n controlFirst = true,\n onCheckedChange,\n transitioning,\n ...props\n },\n ref\n ) => {\n // For aria-label, only use string labels (ReactNode labels can't be used for aria-label)\n const ariaLabelFallback = typeof label === \"string\" ? label : \"Switch\";\n const switchControl = (\n <BaseSwitch.Root\n ref={ref}\n checked={checked}\n disabled={disabled}\n onCheckedChange={onCheckedChange}\n nativeButton\n render={(rootProps, state) => {\n const {\n ref: rootRef,\n className: baseClassName,\n role: baseRole,\n \"aria-checked\": _ariaChecked,\n \"aria-pressed\": _ariaPressed,\n ...restRootProps\n } = rootProps as typeof rootProps & {\n ref?: Ref<HTMLButtonElement>;\n className?: string;\n role?: string;\n \"aria-checked\"?: boolean;\n \"aria-pressed\"?: boolean;\n };\n\n const mergedClassName = cn(\n \"interactive flex items-center gap-2 rounded-full border border-transparent bg-sf-recessed p-1 transition-colors\",\n switchVariants({ size, variant }),\n {\n \"bg-sf-brand\": state.checked && !disabled && variant !== \"error\",\n \"bg-sf-danger\": state.checked && !disabled && variant === \"error\",\n \"hover:bg-sf-brand-hover\":\n state.checked &&\n !transitioning &&\n !disabled &&\n variant !== \"error\",\n \"hover:bg-sf-danger/90\":\n state.checked &&\n !transitioning &&\n !disabled &&\n variant === \"error\",\n \"hover:bg-sf-interact\":\n !state.checked && !transitioning && !disabled,\n \"cursor-not-allowed opacity-50\": disabled,\n },\n transitioning ? \"cursor-wait\" : !disabled ? \"cursor-pointer\" : \"\",\n className,\n baseClassName\n );\n\n const role =\n (props.role as string | undefined) ?? baseRole ?? \"switch\";\n const checkedA11yProps =\n role === \"switch\"\n ? { \"aria-checked\": state.checked }\n : { \"aria-pressed\": state.checked };\n\n return (\n <button\n {...restRootProps}\n {...props}\n ref={rootRef}\n type=\"button\"\n role={role}\n {...checkedA11yProps}\n aria-busy={transitioning || undefined}\n aria-label={props[\"aria-label\"] ?? ariaLabelFallback}\n className={mergedClassName}\n >\n <BaseSwitch.Thumb\n className={cn(\n \"pointer-events-none aspect-square h-full rounded-full bg-white transition-all\",\n {\n \"translate-x-full rtl:translate-x-[-100%]\": state.checked,\n }\n )}\n />\n </button>\n );\n }}\n />\n );\n\n // Wrap in Field (built-in) - no description for single switches\n // If no label provided, return bare switch (for use in other components)\n if (!label) {\n return switchControl;\n }\n\n return (\n <Field\n label={label}\n required={required}\n labelTooltip={labelTooltip}\n controlFirst={controlFirst}\n >\n {switchControl}\n </Field>\n );\n }\n);\n\nSwitchBase.displayName = \"Switch\";\n\n// Switch.Item for use within Switch.Group\nconst SwitchItem = forwardRef<HTMLButtonElement, SwitchItemProps>(\n (\n {\n className,\n checked,\n disabled,\n size = \"base\",\n variant = \"default\",\n label,\n onCheckedChange,\n transitioning,\n },\n ref\n ) => {\n const { controlFirst } = useContext(SwitchGroupContext);\n\n return (\n <label\n className={cn(\n \"relative inline-flex items-center gap-2\",\n // Control first (default): switch before label\n // Label first: label before switch using flex-row-reverse\n !controlFirst && \"flex-row-reverse justify-end\",\n disabled ? \"cursor-not-allowed opacity-50\" : \"cursor-pointer\",\n className\n )}\n >\n <BaseSwitch.Root\n ref={ref}\n checked={checked}\n disabled={disabled}\n onCheckedChange={onCheckedChange}\n nativeButton\n render={(rootProps, state) => {\n const {\n ref: rootRef,\n className: baseClassName,\n role: baseRole,\n \"aria-checked\": _ariaChecked,\n \"aria-pressed\": _ariaPressed,\n ...restRootProps\n } = rootProps as typeof rootProps & {\n ref?: Ref<HTMLButtonElement>;\n className?: string;\n role?: string;\n \"aria-checked\"?: boolean;\n \"aria-pressed\"?: boolean;\n };\n\n const mergedClassName = cn(\n \"interactive flex items-center gap-2 rounded-full border border-transparent bg-sf-recessed p-1 transition-colors\",\n switchVariants({ size, variant }),\n {\n \"bg-sf-brand\":\n state.checked && !disabled && variant !== \"error\",\n \"bg-sf-danger\":\n state.checked && !disabled && variant === \"error\",\n \"hover:bg-sf-brand-hover\":\n state.checked &&\n !transitioning &&\n !disabled &&\n variant !== \"error\",\n \"hover:bg-sf-danger/90\":\n state.checked &&\n !transitioning &&\n !disabled &&\n variant === \"error\",\n \"hover:bg-sf-interact\":\n !state.checked && !transitioning && !disabled,\n \"cursor-not-allowed opacity-50\": disabled,\n },\n transitioning ? \"cursor-wait\" : !disabled ? \"cursor-pointer\" : \"\",\n baseClassName\n );\n\n const role = baseRole ?? \"switch\";\n const checkedA11yProps =\n role === \"switch\"\n ? { \"aria-checked\": state.checked }\n : { \"aria-pressed\": state.checked };\n\n return (\n <button\n {...restRootProps}\n ref={rootRef}\n type=\"button\"\n role={role}\n {...checkedA11yProps}\n aria-busy={transitioning || undefined}\n className={mergedClassName}\n >\n <BaseSwitch.Thumb\n className={cn(\n \"pointer-events-none aspect-square h-full rounded-full bg-white transition-all\",\n {\n \"translate-x-full rtl:translate-x-[-100%]\": state.checked,\n }\n )}\n />\n </button>\n );\n }}\n />\n <span className=\"text-base font-medium text-sf-default\">{label}</span>\n </label>\n );\n }\n);\n\nSwitchItem.displayName = \"Switch.Item\";\n\n// Switch.Group with built-in Fieldset\nfunction SwitchGroup({\n legend,\n children,\n error,\n description,\n disabled,\n controlFirst = true,\n className,\n}: SwitchGroupProps) {\n return (\n <SwitchGroupContext.Provider value={{ controlFirst }}>\n <Fieldset.Root\n className={cn(\n \"flex flex-col gap-4 rounded-lg border border-sf-line p-4\",\n className\n )}\n disabled={disabled}\n >\n <Fieldset.Legend className=\"text-lg font-medium text-sf-default\">\n {legend}\n </Fieldset.Legend>\n <div className=\"flex flex-col gap-2\">{children}</div>\n {error && <p className=\"text-sm text-sf-danger\">{error}</p>}\n {description && <p className=\"text-sm text-sf-subtle\">{description}</p>}\n </Fieldset.Root>\n </SwitchGroupContext.Provider>\n );\n}\n\n// Compound component\nexport const Switch = Object.assign(SwitchBase, {\n Item: SwitchItem,\n Group: SwitchGroup,\n});\n\nSwitch.displayName = \"Switch\";\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"text-KJmGkwnf.js","names":[],"sources":["../src/components/text/text.tsx"],"sourcesContent":["import {\n type CSSProperties,\n type ComponentPropsWithoutRef,\n type ElementRef,\n type ForwardedRef,\n forwardRef,\n useMemo,\n type ElementType,\n} from \"react\";\n\nimport { cn } from \"../../utils/cn\";\n\n/** Text variant and size definitions mapping names to their Tailwind classes. */\nexport const SF_TEXT_VARIANTS = {\n variant: {\n heading1: {\n classes: \"text-3xl font-semibold\",\n description: \"Large heading for page titles\",\n },\n heading2: {\n classes: \"text-2xl font-semibold\",\n description: \"Medium heading for section titles\",\n },\n heading3: {\n classes: \"text-lg font-semibold\",\n description: \"Small heading for subsections\",\n },\n body: {\n classes: \"text-sf-default\",\n description: \"Default body text\",\n },\n secondary: {\n classes: \"text-sf-subtle\",\n description: \"Muted text for secondary information\",\n },\n success: {\n classes: \"text-sf-link\",\n description: \"Success state text\",\n },\n error: {\n classes: \"text-sf-danger\",\n description: \"Error state text\",\n },\n mono: {\n classes: \"font-mono\",\n description: \"Monospace text for code\",\n },\n \"mono-secondary\": {\n classes: \"font-mono text-sf-subtle\",\n description: \"Muted monospace text\",\n },\n },\n size: {\n xs: {\n classes: \"text-xs\",\n description: \"Extra small text\",\n },\n sm: {\n classes: \"text-sm\",\n description: \"Small text\",\n },\n base: {\n classes: \"text-base\",\n description: \"Default text size\",\n },\n lg: {\n classes: \"text-lg\",\n description: \"Large text\",\n },\n },\n} as const;\n\nexport const SF_TEXT_DEFAULT_VARIANTS = {\n variant: \"body\",\n size: \"base\",\n} as const;\n\n/**\n * SF_TEXT_STYLING - Typography metadata for Figma generator\n *\n * This export provides structured styling information extracted from text.tsx\n * for use by the Figma plugin generator. It documents font sizes, weights,\n * colors, and font families used across all Text variants.\n *\n * Source of truth chain:\n * text.tsx (this file) → component-registry.json → text.ts (Figma generator)\n */\nexport const SF_TEXT_STYLING = {\n fontSizes: {\n xs: 12,\n sm: 14,\n base: 16,\n lg: 18,\n xl: 20,\n \"2xl\": 24,\n \"3xl\": 30,\n },\n fontWeights: {\n normal: 400,\n medium: 500,\n semibold: 600,\n },\n baseColor: \"text-sf-default\",\n variantColors: {\n body: \"text-sf-default\",\n secondary: \"text-sf-subtle\",\n success: \"text-sf-link\",\n error: \"text-sf-danger\",\n mono: \"text-sf-default\",\n \"mono-secondary\": \"text-sf-subtle\",\n },\n fontFamilies: {\n default: \"sans-serif\",\n mono: \"monospace\",\n },\n} as const;\n\n// Derived types from SF_TEXT_VARIANTS\nexport type SFTextVariant = keyof typeof SF_TEXT_VARIANTS.variant;\nexport type SFTextSize = keyof typeof SF_TEXT_VARIANTS.size;\n\nexport interface SFTextVariantsProps {\n variant?: SFTextVariant;\n size?: SFTextSize;\n}\n\nexport function textVariants({\n variant = SF_TEXT_DEFAULT_VARIANTS.variant,\n size = SF_TEXT_DEFAULT_VARIANTS.size,\n}: SFTextVariantsProps = {}) {\n return cn(\n SF_TEXT_VARIANTS.variant[variant].classes,\n SF_TEXT_VARIANTS.size[size].classes\n );\n}\n\n// Legacy types for backwards compatibility\ntype Heading = \"heading1\" | \"heading2\" | \"heading3\";\ntype Copy = \"body\" | \"secondary\" | \"success\" | \"error\";\ntype Monospace = \"mono\" | \"mono-secondary\";\ntype TextSize = SFTextSize;\ntype TextVariant = SFTextVariant;\n\ntype BaseTextProps = Omit<\n ComponentPropsWithoutRef<\"span\">,\n \"className\" | \"style\"\n> & {\n DANGEROUS_className?: string;\n DANGEROUS_style?: CSSProperties;\n as?: ElementType;\n};\n\ntype TextPropsInternal<Variant extends TextVariant = \"body\"> = BaseTextProps &\n (Variant extends Copy\n ? {\n variant?: Variant;\n bold?: boolean;\n size?: TextSize;\n }\n : Variant extends Monospace\n ? {\n variant?: Variant;\n bold?: never;\n size?: \"lg\";\n }\n : Variant extends Heading\n ? {\n variant?: Variant;\n bold?: never;\n size?: never;\n }\n : never);\n\n/**\n * Text component props.\n *\n * @example\n * ```tsx\n * <Text variant=\"heading1\">Page Title</Text>\n * <Text variant=\"body\">Default paragraph text.</Text>\n * <Text variant=\"secondary\" size=\"sm\">Muted helper text</Text>\n * <Text variant=\"error\">Something went wrong</Text>\n * <Text variant=\"mono\">console.log(\"code\")</Text>\n * ```\n */\nexport interface TextProps {\n /**\n * Text style variant. Determines color, font, and weight.\n * - `\"heading1\"` — Large page title (30px, semibold)\n * - `\"heading2\"` — Section title (24px, semibold)\n * - `\"heading3\"` — Subsection title (18px, semibold)\n * - `\"body\"` — Default body text\n * - `\"secondary\"` — Muted text for secondary information\n * - `\"success\"` — Success state text\n * - `\"error\"` — Error state text\n * - `\"mono\"` — Monospace text for code\n * - `\"mono-secondary\"` — Muted monospace text\n * @default \"body\"\n */\n variant?: SFTextVariant;\n /**\n * Text size (only applies to body/secondary/success/error variants).\n * - `\"xs\"` — 12px\n * - `\"sm\"` — 14px\n * - `\"base\"` — 16px\n * - `\"lg\"` — 18px\n * @default \"base\"\n */\n size?: SFTextSize;\n /** Whether to use bold font weight (only applies to body variants). */\n bold?: boolean;\n /** The HTML element type to render as (e.g. `\"span\"`, `\"p\"`, `\"h1\"`). Auto-selected based on variant if omitted. */\n as?: ElementType;\n /** Text content. */\n children?: React.ReactNode;\n}\n\n/**\n * Typography component for rendering text with consistent styling.\n * Automatically selects the appropriate HTML element based on variant\n * (`h1`/`h2`/`h3` for headings, `p` for body, `span` for mono).\n *\n * @example\n * ```tsx\n * <Text variant=\"heading1\">Dashboard</Text>\n * <Text>Default body text</Text>\n * ```\n */\nfunction _Text<Variant extends TextVariant = \"body\">(\n {\n variant = \"body\" as Variant,\n bold = false,\n size = \"base\",\n children,\n DANGEROUS_className,\n DANGEROUS_style,\n as,\n ...props\n }: TextPropsInternal<Variant>,\n ref: ForwardedRef<HTMLHeadingElement>\n) {\n const isCopy = [\"body\", \"secondary\", \"success\", \"error\"].includes(variant);\n const isMono = [\"mono\", \"mono-secondary\"].includes(variant);\n\n const Component = useMemo(() => {\n if (as) return as;\n if (variant === \"heading1\") return \"h1\";\n if (variant === \"heading2\") return \"h2\";\n if (variant === \"heading3\") return \"h3\";\n if ([\"mono\", \"mono-secondary\"].includes(variant)) return \"span\";\n return \"p\";\n }, [variant, as]);\n\n return (\n <Component\n ref={ref}\n className={cn(\n \"text-sf-default\",\n SF_TEXT_VARIANTS.variant[variant].classes,\n isCopy ? SF_TEXT_VARIANTS.size[size].classes : \"\",\n isCopy && bold ? \"font-medium\" : \"\",\n // Monospace fonts need to be 1pt smaller than body text to optically match\n isMono &&\n (size === \"lg\"\n ? SF_TEXT_VARIANTS.size.base.classes\n : SF_TEXT_VARIANTS.size.sm.classes),\n DANGEROUS_className\n )}\n style={DANGEROUS_style}\n {...props}\n >\n {children}\n </Component>\n );\n}\n\nexport const Text = forwardRef(_Text) as <Variant extends TextVariant = \"body\">(\n props: TextPropsInternal<Variant> & {\n ref?: ForwardedRef<ElementRef<\"span\">>;\n }\n) => React.ReactElement;\n"],"mappings":";;;;;;AAaA,IAAa,mBAAmB;CAC9B,SAAS;EACP,UAAU;GACR,SAAS;GACT,aAAa;GACd;EACD,UAAU;GACR,SAAS;GACT,aAAa;GACd;EACD,UAAU;GACR,SAAS;GACT,aAAa;GACd;EACD,MAAM;GACJ,SAAS;GACT,aAAa;GACd;EACD,WAAW;GACT,SAAS;GACT,aAAa;GACd;EACD,SAAS;GACP,SAAS;GACT,aAAa;GACd;EACD,OAAO;GACL,SAAS;GACT,aAAa;GACd;EACD,MAAM;GACJ,SAAS;GACT,aAAa;GACd;EACD,kBAAkB;GAChB,SAAS;GACT,aAAa;GACd;EACF;CACD,MAAM;EACJ,IAAI;GACF,SAAS;GACT,aAAa;GACd;EACD,IAAI;GACF,SAAS;GACT,aAAa;GACd;EACD,MAAM;GACJ,SAAS;GACT,aAAa;GACd;EACD,IAAI;GACF,SAAS;GACT,aAAa;GACd;EACF;CACF;;;;;;;;;;;;AA8JD,SAAS,MACP,EACE,UAAU,QACV,OAAO,OACP,OAAO,QACP,UACA,qBACA,iBACA,IACA,GAAG,SAEL,KACA;CACA,MAAM,SAAS;EAAC;EAAQ;EAAa;EAAW;EAAQ,CAAC,SAAS,QAAQ;CAC1E,MAAM,SAAS,CAAC,QAAQ,iBAAiB,CAAC,SAAS,QAAQ;AAW3D,QACE,oBAVgB,cAAc;AAC9B,MAAI,GAAI,QAAO;AACf,MAAI,YAAY,WAAY,QAAO;AACnC,MAAI,YAAY,WAAY,QAAO;AACnC,MAAI,YAAY,WAAY,QAAO;AACnC,MAAI,CAAC,QAAQ,iBAAiB,CAAC,SAAS,QAAQ,CAAE,QAAO;AACzD,SAAO;IACN,CAAC,SAAS,GAAG,CAAC,EAGf;EACO;EACL,WAAW,GACT,mBACA,iBAAiB,QAAQ,SAAS,SAClC,SAAS,iBAAiB,KAAK,MAAM,UAAU,IAC/C,UAAU,OAAO,gBAAgB,IAEjC,WACG,SAAS,OACN,iBAAiB,KAAK,KAAK,UAC3B,iBAAiB,KAAK,GAAG,UAC/B,oBACD;EACD,OAAO;EACP,GAAI;EAEH;EACS,CAAA;;AAIhB,IAAa,OAAO,WAAW,MAAM"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"text-roll-BZ3I1umc.js","names":[],"sources":["../src/components/text-roll/text-roll.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n motion,\n type Target,\n type TargetAndTransition,\n type Transition,\n type VariantLabels,\n} from \"motion/react\";\n\nexport type TextRollVariants = {\n enter: {\n initial: Target | VariantLabels | boolean;\n animate: TargetAndTransition | VariantLabels;\n };\n exit: {\n initial: Target | VariantLabels | boolean;\n animate: TargetAndTransition | VariantLabels;\n };\n};\n\nexport type TextRollProps = {\n /** Text to animate. Each character rolls in / out independently. */\n children: string;\n /** Duration (seconds) of each letter's enter and exit tween. */\n duration?: number;\n /** Per-letter delay for the enter animation. */\n getEnterDelay?: (index: number) => number;\n /** Per-letter delay for the exit animation. */\n getExitDelay?: (index: number) => number;\n /** Additional CSS classes merged via `cn()`. Use sf semantic tokens only. */\n className?: string;\n /** Shared transition for both enter and exit tweens. */\n transition?: Transition;\n /** Override the default rotate-X roll with custom enter/exit variants. */\n variants?: TextRollVariants;\n /** Fires once the last letter's exit animation finishes. */\n onAnimationComplete?: () => void;\n};\n\nconst DEFAULT_VARIANTS: TextRollVariants = {\n enter: {\n initial: { rotateX: 0 },\n animate: { rotateX: 90 },\n },\n exit: {\n initial: { rotateX: 90 },\n animate: { rotateX: 0 },\n },\n};\n\n/**\n * Letter-by-letter roll animation. Each character flips on the X axis: the\n * current letter rolls up and out, the new letter rolls in from below.\n * Good for title changes (e.g. a streaming activity group swapping its\n * current-step label) where the text content is short and the change should\n * register visually.\n *\n * Wraps the string in an `aria-hidden` visual stack with a screen-reader-only\n * copy of the full text so a11y tools always read the real content.\n *\n * @example\n * ```tsx\n * <TextRoll key={title}>{title}</TextRoll>\n * ```\n */\nexport function TextRoll({\n children,\n duration = 0.5,\n getEnterDelay = (i) => i * 0.1,\n getExitDelay = (i) => i * 0.1 + 0.2,\n className,\n transition = { ease: \"easeIn\" },\n variants,\n onAnimationComplete,\n}: TextRollProps) {\n const letters = children.split(\"\");\n\n return (\n <span className={className}>\n {letters.map((letter, i) => {\n const display = letter === \" \" ? \"\\u00A0\" : letter;\n return (\n <span\n aria-hidden=\"true\"\n className=\"relative inline-block [perspective:10000px] [transform-style:preserve-3d] [width:auto]\"\n // Using index is intentional — letters are positional.\n // biome-ignore lint/suspicious/noArrayIndexKey: positional char animation\n key={i}\n >\n <motion.span\n animate={\n variants?.enter?.animate ?? DEFAULT_VARIANTS.enter.animate\n }\n className=\"absolute inline-block [backface-visibility:hidden] [transform-origin:50%_25%]\"\n initial={\n variants?.enter?.initial ?? DEFAULT_VARIANTS.enter.initial\n }\n transition={{\n ...transition,\n duration,\n delay: getEnterDelay(i),\n }}\n >\n {display}\n </motion.span>\n <motion.span\n animate={variants?.exit?.animate ?? DEFAULT_VARIANTS.exit.animate}\n className=\"absolute inline-block [backface-visibility:hidden] [transform-origin:50%_100%]\"\n initial={variants?.exit?.initial ?? DEFAULT_VARIANTS.exit.initial}\n onAnimationComplete={\n letters.length === i + 1 ? onAnimationComplete : undefined\n }\n transition={{\n ...transition,\n duration,\n delay: getExitDelay(i),\n }}\n >\n {display}\n </motion.span>\n <span className=\"invisible\">{display}</span>\n </span>\n );\n })}\n <span className=\"sr-only\">{children}</span>\n </span>\n );\n}\n\nTextRoll.displayName = \"TextRoll\";\n"],"mappings":";;;;AAwCA,IAAM,mBAAqC;CACzC,OAAO;EACL,SAAS,EAAE,SAAS,GAAG;EACvB,SAAS,EAAE,SAAS,IAAI;EACzB;CACD,MAAM;EACJ,SAAS,EAAE,SAAS,IAAI;EACxB,SAAS,EAAE,SAAS,GAAG;EACxB;CACF;;;;;;;;;;;;;;;;AAiBD,SAAgB,SAAS,EACvB,UACA,WAAW,IACX,iBAAiB,MAAM,IAAI,IAC3B,gBAAgB,MAAM,IAAI,KAAM,IAChC,WACA,aAAa,EAAE,MAAM,UAAU,EAC/B,UACA,uBACgB;CAChB,MAAM,UAAU,SAAS,MAAM,GAAG;AAElC,QACE,qBAAC,QAAD;EAAiB;YAAjB,CACG,QAAQ,KAAK,QAAQ,MAAM;GAC1B,MAAM,UAAU,WAAW,MAAM,SAAW;AAC5C,UACE,qBAAC,QAAD;IACE,eAAY;IACZ,WAAU;cAFZ;KAOE,oBAAC,OAAO,MAAR;MACE,SACE,UAAU,OAAO,WAAW,iBAAiB,MAAM;MAErD,WAAU;MACV,SACE,UAAU,OAAO,WAAW,iBAAiB,MAAM;MAErD,YAAY;OACV,GAAG;OACH;OACA,OAAO,cAAc,EAAE;OACxB;gBAEA;MACW,CAAA;KACd,oBAAC,OAAO,MAAR;MACE,SAAS,UAAU,MAAM,WAAW,iBAAiB,KAAK;MAC1D,WAAU;MACV,SAAS,UAAU,MAAM,WAAW,iBAAiB,KAAK;MAC1D,qBACE,QAAQ,WAAW,IAAI,IAAI,sBAAsB,KAAA;MAEnD,YAAY;OACV,GAAG;OACH;OACA,OAAO,aAAa,EAAE;OACvB;gBAEA;MACW,CAAA;KACd,oBAAC,QAAD;MAAM,WAAU;gBAAa;MAAe,CAAA;KACvC;MAlCA,EAkCA;IAET,EACF,oBAAC,QAAD;GAAM,WAAU;GAAW;GAAgB,CAAA,CACtC;;;AAIX,SAAS,cAAc"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"theme-toggle-Bhu681D7.js","names":[],"sources":["../src/components/theme-toggle/theme-toggle.tsx"],"sourcesContent":["\"use client\";\n\nimport { MoonIcon, SunIcon } from \"@phosphor-icons/react\";\nimport { useEffect, useState } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\nimport { Button } from \"../button\";\nimport { Tooltip } from \"../tooltip\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport type SFThemeMode = \"light\" | \"dark\" | \"system\";\n\nexport const SF_THEME_TOGGLE_VARIANTS = {\n mode: {\n light: { classes: \"\", description: \"Light mode\" },\n dark: { classes: \"\", description: \"Dark mode\" },\n system: { classes: \"\", description: \"Follow system preference\" },\n },\n} as const;\n\nexport const SF_THEME_TOGGLE_DEFAULT_VARIANTS = {\n mode: \"system\",\n} as const;\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nconst STORAGE_KEY = \"theme\";\n\nfunction getSystemTheme(): \"light\" | \"dark\" {\n if (typeof window === \"undefined\") return \"light\";\n return window.matchMedia(\"(prefers-color-scheme: dark)\").matches\n ? \"dark\"\n : \"light\";\n}\n\nfunction resolveMode(mode: SFThemeMode): \"light\" | \"dark\" {\n return mode === \"system\" ? getSystemTheme() : mode;\n}\n\nfunction applyTheme(mode: SFThemeMode) {\n const resolved = resolveMode(mode);\n document.documentElement.dataset.mode = resolved;\n if (mode === \"system\") {\n localStorage.removeItem(STORAGE_KEY);\n } else {\n localStorage.setItem(STORAGE_KEY, mode);\n }\n}\n\n/**\n * Read the current persisted mode preference from localStorage.\n * Returns \"system\" if nothing is stored.\n */\nexport function getStoredThemeMode(): SFThemeMode {\n if (typeof window === \"undefined\") return \"system\";\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored === \"light\" || stored === \"dark\") return stored;\n return \"system\";\n}\n\n// ─── Component ────────────────────────────────────────────────────────────────\n\nexport interface ThemeToggleProps {\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /**\n * Controlled mode. When provided the component acts as a controlled input —\n * pair with `onModeChange`.\n */\n mode?: SFThemeMode;\n /**\n * Called when the user cycles to a new mode.\n * Receives the new mode value.\n */\n onModeChange?: (mode: SFThemeMode) => void;\n /**\n * Cycle order for clicking. Defaults to `[\"light\", \"dark\", \"system\"]`.\n * Remove `\"system\"` to limit to a simple light/dark toggle.\n */\n cycle?: SFThemeMode[];\n /** Show a tooltip labelling the current action. Defaults to true. */\n tooltip?: boolean;\n}\n\n/**\n * Theme toggle button. Cycles through light → dark → system (follows OS) modes.\n *\n * Reads from and writes to `localStorage` under the key `\"theme\"`. When set to\n * `\"system\"` the key is removed so the OS preference takes over automatically.\n * Applies the resolved mode to `document.documentElement.dataset.mode`.\n *\n * @example\n * ```tsx\n * // Simple uncontrolled — manages localStorage automatically\n * <ThemeToggle />\n *\n * // Controlled\n * const [mode, setMode] = useState<SFThemeMode>(\"system\");\n * <ThemeToggle mode={mode} onModeChange={setMode} />\n *\n * // Light/dark only (no system option)\n * <ThemeToggle cycle={[\"light\", \"dark\"]} />\n * ```\n */\nexport function ThemeToggle({\n className,\n mode: controlledMode,\n onModeChange,\n cycle = [\"light\", \"dark\", \"system\"],\n tooltip = true,\n}: ThemeToggleProps) {\n const isControlled = controlledMode !== undefined;\n\n const [internalMode, setInternalMode] = useState<SFThemeMode>(\"system\");\n const [mounted, setMounted] = useState(false);\n\n // Hydrate from localStorage on mount\n useEffect(() => {\n setMounted(true);\n if (!isControlled) {\n setInternalMode(getStoredThemeMode());\n }\n }, [isControlled]);\n\n // Keep in sync if system preference changes while in \"system\" mode\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const mq = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const activeMode = isControlled ? controlledMode : internalMode;\n if (activeMode !== \"system\") return;\n\n const handler = () => applyTheme(\"system\");\n mq.addEventListener(\"change\", handler);\n return () => mq.removeEventListener(\"change\", handler);\n }, [isControlled, controlledMode, internalMode]);\n\n const activeMode = isControlled ? (controlledMode ?? \"system\") : internalMode;\n const resolvedActive = resolveMode(activeMode);\n\n const handleClick = () => {\n const idx = cycle.indexOf(activeMode);\n const next = cycle[(idx + 1) % cycle.length] ?? cycle[0] ?? \"system\";\n applyTheme(next);\n if (!isControlled) setInternalMode(next);\n onModeChange?.(next);\n };\n\n const tooltipLabel =\n activeMode === \"light\"\n ? \"Switch to dark mode\"\n : activeMode === \"dark\"\n ? \"Use system theme\"\n : \"Switch to light mode\";\n\n // SSR / pre-mount: render a stable placeholder to avoid hydration mismatch\n if (!mounted) {\n return (\n <Button\n aria-label=\"Toggle theme\"\n className={cn(\"text-sf-subtle\", className)}\n shape=\"square\"\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n >\n <SunIcon className=\"size-4\" />\n </Button>\n );\n }\n\n const button = (\n <Button\n aria-label={tooltipLabel}\n className={cn(\"text-sf-subtle hover:text-sf-default\", className)}\n onClick={handleClick}\n shape=\"square\"\n size=\"sm\"\n type=\"button\"\n variant=\"ghost\"\n >\n {resolvedActive === \"dark\" ? (\n <MoonIcon className=\"size-4\" />\n ) : (\n <SunIcon className=\"size-4\" />\n )}\n </Button>\n );\n\n if (!tooltip) return button;\n\n return <Tooltip content={tooltipLabel}>{button}</Tooltip>;\n}\n"],"mappings":";;;;;;;;AAaA,IAAa,2BAA2B,EACtC,MAAM;CACJ,OAAO;EAAE,SAAS;EAAI,aAAa;EAAc;CACjD,MAAM;EAAE,SAAS;EAAI,aAAa;EAAa;CAC/C,QAAQ;EAAE,SAAS;EAAI,aAAa;EAA4B;CACjE,EACF;AAED,IAAa,mCAAmC,EAC9C,MAAM,UACP;AAID,IAAM,cAAc;AAEpB,SAAS,iBAAmC;AAC1C,KAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,QAAO,OAAO,WAAW,+BAA+B,CAAC,UACrD,SACA;;AAGN,SAAS,YAAY,MAAqC;AACxD,QAAO,SAAS,WAAW,gBAAgB,GAAG;;AAGhD,SAAS,WAAW,MAAmB;CACrC,MAAM,WAAW,YAAY,KAAK;AAClC,UAAS,gBAAgB,QAAQ,OAAO;AACxC,KAAI,SAAS,SACX,cAAa,WAAW,YAAY;KAEpC,cAAa,QAAQ,aAAa,KAAK;;;;;;AAQ3C,SAAgB,qBAAkC;AAChD,KAAI,OAAO,WAAW,YAAa,QAAO;CAC1C,MAAM,SAAS,aAAa,QAAQ,YAAY;AAChD,KAAI,WAAW,WAAW,WAAW,OAAQ,QAAO;AACpD,QAAO;;;;;;;;;;;;;;;;;;;;;;AA+CT,SAAgB,YAAY,EAC1B,WACA,MAAM,gBACN,cACA,QAAQ;CAAC;CAAS;CAAQ;CAAS,EACnC,UAAU,QACS;CACnB,MAAM,eAAe,mBAAmB,KAAA;CAExC,MAAM,CAAC,cAAc,mBAAmB,SAAsB,SAAS;CACvE,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;AAG7C,iBAAgB;AACd,aAAW,KAAK;AAChB,MAAI,CAAC,aACH,iBAAgB,oBAAoB,CAAC;IAEtC,CAAC,aAAa,CAAC;AAGlB,iBAAgB;AACd,MAAI,OAAO,WAAW,YAAa;EACnC,MAAM,KAAK,OAAO,WAAW,+BAA+B;AAE5D,OADmB,eAAe,iBAAiB,kBAChC,SAAU;EAE7B,MAAM,gBAAgB,WAAW,SAAS;AAC1C,KAAG,iBAAiB,UAAU,QAAQ;AACtC,eAAa,GAAG,oBAAoB,UAAU,QAAQ;IACrD;EAAC;EAAc;EAAgB;EAAa,CAAC;CAEhD,MAAM,aAAa,eAAgB,kBAAkB,WAAY;CACjE,MAAM,iBAAiB,YAAY,WAAW;CAE9C,MAAM,oBAAoB;EAExB,MAAM,OAAO,OADD,MAAM,QAAQ,WAAW,GACX,KAAK,MAAM,WAAW,MAAM,MAAM;AAC5D,aAAW,KAAK;AAChB,MAAI,CAAC,aAAc,iBAAgB,KAAK;AACxC,iBAAe,KAAK;;CAGtB,MAAM,eACJ,eAAe,UACX,wBACA,eAAe,SACb,qBACA;AAGR,KAAI,CAAC,QACH,QACE,oBAAC,QAAD;EACE,cAAW;EACX,WAAW,GAAG,kBAAkB,UAAU;EAC1C,OAAM;EACN,MAAK;EACL,MAAK;EACL,SAAQ;YAER,oBAAC,SAAD,EAAS,WAAU,UAAW,CAAA;EACvB,CAAA;CAIb,MAAM,SACJ,oBAAC,QAAD;EACE,cAAY;EACZ,WAAW,GAAG,wCAAwC,UAAU;EAChE,SAAS;EACT,OAAM;EACN,MAAK;EACL,MAAK;EACL,SAAQ;YAEP,mBAAmB,SAClB,oBAAC,UAAD,EAAU,WAAU,UAAW,CAAA,GAE/B,oBAAC,SAAD,EAAS,WAAU,UAAW,CAAA;EAEzB,CAAA;AAGX,KAAI,CAAC,QAAS,QAAO;AAErB,QAAO,oBAAC,SAAD;EAAS,SAAS;YAAe;EAAiB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tooltip-Cb7QW-7H.js","names":[],"sources":["../src/components/tooltip/tooltip.tsx"],"sourcesContent":["import { Tooltip as TooltipBase } from \"@base-ui/react/tooltip\";\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\n\n/** Tooltip side variant definitions mapping positions to their Tailwind classes. */\nexport const SF_TOOLTIP_VARIANTS = {\n side: {\n top: {\n classes: \"\",\n description: \"Tooltip appears above the trigger\",\n },\n bottom: {\n classes: \"\",\n description: \"Tooltip appears below the trigger\",\n },\n left: {\n classes: \"\",\n description: \"Tooltip appears to the left of the trigger\",\n },\n right: {\n classes: \"\",\n description: \"Tooltip appears to the right of the trigger\",\n },\n },\n} as const;\n\nexport const SF_TOOLTIP_DEFAULT_VARIANTS = {\n side: \"top\",\n} as const;\n\n// Derived types from SF_TOOLTIP_VARIANTS\nexport type SFTooltipSide = keyof typeof SF_TOOLTIP_VARIANTS.side;\n\nexport interface SFTooltipVariantsProps {\n /**\n * Preferred side of the trigger to render the tooltip.\n * - `\"top\"` — Tooltip appears above the trigger\n * - `\"bottom\"` — Tooltip appears below the trigger\n * - `\"left\"` — Tooltip appears to the left of the trigger\n * - `\"right\"` — Tooltip appears to the right of the trigger\n * @default \"top\"\n */\n side?: SFTooltipSide;\n}\n\nexport function tooltipVariants({\n side = SF_TOOLTIP_DEFAULT_VARIANTS.side,\n}: SFTooltipVariantsProps = {}) {\n return cn(\n // Base styles\n \"flex origin-[var(--transform-origin)] flex-col rounded-md bg-sf-elevated px-2.5 py-1.5 text-sm text-sf-default\",\n \"shadow-lg shadow-sf-tip-shadow outline outline-1 outline-sf-fill\",\n \"transition-[transform,opacity] duration-150\",\n \"data-[starting-style]:scale-90 data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-90 data-[ending-style]:opacity-0\",\n \"data-[instant]:duration-0\",\n // Apply side-specific styles (currently none, but extensible)\n SF_TOOLTIP_VARIANTS.side[side].classes\n );\n}\n\nexport const TooltipProvider = TooltipBase.Provider;\n\ntype BaseTooltipProps = ComponentPropsWithoutRef<typeof TooltipBase.Root>;\n\ntype TriggerProps = ComponentPropsWithoutRef<typeof TooltipBase.Trigger>;\n\n/** Alignment options for tooltip positioning. Source: PositionerProps[\"align\"] */\ntype TooltipAlign = \"start\" | \"center\" | \"end\";\n\n/**\n * Tooltip component props.\n *\n * @example\n * ```tsx\n * <TooltipProvider>\n * <Tooltip content=\"Add new item\">\n * <Button shape=\"square\" icon={PlusIcon} />\n * </Tooltip>\n * </TooltipProvider>\n * ```\n */\nexport type TooltipProps = BaseTooltipProps &\n SFTooltipVariantsProps & {\n /**\n * Alignment on the axis perpendicular to `side`.\n * - `\"start\"` — Align to the start edge\n * - `\"center\"` — Center-aligned\n * - `\"end\"` — Align to the end edge\n */\n align?: TooltipAlign;\n /** Additional CSS classes merged via `cn()`. */\n className?: string;\n /** Content to display inside the tooltip popup. */\n content: ReactNode;\n };\n\n/**\n * Accessible popup that shows additional information on hover/focus.\n * Wrap your app or section with `<TooltipProvider>` to enable delay grouping.\n *\n * @example\n * ```tsx\n * <Tooltip content=\"Save changes\">\n * <Button variant=\"primary\">Save</Button>\n * </Tooltip>\n * ```\n */\nexport function Tooltip({\n content,\n children,\n align,\n side,\n className,\n ...props\n}: TooltipProps) {\n return (\n <TooltipBase.Root {...props}>\n <TooltipBase.Trigger\n className={className}\n render={children as TriggerProps[\"render\"]}\n />\n <TooltipBase.Portal>\n <TooltipBase.Positioner align={align} side={side} sideOffset={10}>\n <TooltipBase.Popup\n className={cn(\n \"flex origin-[var(--transform-origin)] flex-col rounded-md bg-sf-elevated px-2.5 py-1.5 text-sm text-sf-default\",\n \"shadow-lg shadow-sf-tip-shadow outline outline-sf-fill\",\n \"transition-[transform,opacity] duration-150\",\n \"data-[starting-style]:scale-90 data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-90 data-[ending-style]:opacity-0\",\n \"data-[instant]:duration-0\",\n \"sf-tooltip-popup\"\n )}\n >\n <TooltipBase.Arrow\n className={cn(\n \"flex\",\n \"data-[side=bottom]:top-[-8px]\",\n \"data-[side=left]:right-[-13px] data-[side=left]:rotate-90\",\n \"data-[side=right]:left-[-13px] data-[side=right]:-rotate-90\",\n \"data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180\"\n )}\n >\n <ArrowSvg />\n </TooltipBase.Arrow>\n {content}\n </TooltipBase.Popup>\n </TooltipBase.Positioner>\n </TooltipBase.Portal>\n </TooltipBase.Root>\n );\n}\n\n/**\n * Arrow SVG with three paths for proper border rendering in both light and dark modes.\n * This approach matches Base UI's tooltip implementation.\n *\n * The three paths are:\n * 1. ArrowFill - The main arrow body, matches tooltip background\n * 2. ArrowOuterStroke - Border visible in light mode only (transparent in dark)\n * 3. ArrowInnerStroke - Border visible in dark mode only (transparent in light)\n *\n * This is necessary because the outer and inner stroke paths have different geometries,\n * and using both ensures the arrow border aligns perfectly with the tooltip's outline\n * in both color modes.\n *\n * @see https://base-ui.com/react/components/tooltip\n */\nfunction ArrowSvg(props: React.ComponentProps<\"svg\">) {\n return (\n <svg width=\"20\" height=\"10\" viewBox=\"0 0 20 10\" fill=\"none\" {...props}>\n <path\n d=\"M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z\"\n className=\"fill-sf-elevated\"\n />\n <path\n d=\"M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z\"\n className=\"fill-sf-tip-shadow\"\n />\n <path\n d=\"M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z\"\n className=\"fill-sf-tip-stroke\"\n />\n </svg>\n );\n}\n"],"mappings":";;;;;AA8DA,IAAa,kBAAkB,QAAY;;;;;;;;;;;;AA+C3C,SAAgB,UAAQ,EACtB,SACA,UACA,OACA,MACA,WACA,GAAG,SACY;AACf,QACE,qBAAC,QAAY,MAAb;EAAkB,GAAI;YAAtB,CACE,oBAAC,QAAY,SAAb;GACa;GACX,QAAQ;GACR,CAAA,EACF,oBAAC,QAAY,QAAb,EAAA,UACE,oBAAC,QAAY,YAAb;GAA+B;GAAa;GAAM,YAAY;aAC5D,qBAAC,QAAY,OAAb;IACE,WAAW,GACT,kHACA,0DACA,+CACA,kEACA,8DACA,6BACA,mBACD;cATH,CAWE,oBAAC,QAAY,OAAb;KACE,WAAW,GACT,QACA,iCACA,6DACA,+DACA,2DACD;eAED,oBAAC,UAAD,EAAY,CAAA;KACM,CAAA,EACnB,QACiB;;GACG,CAAA,EACN,CAAA,CACJ;;;;;;;;;;;;;;;;;;AAmBvB,SAAS,SAAS,OAAoC;AACpD,QACE,qBAAC,OAAD;EAAK,OAAM;EAAK,QAAO;EAAK,SAAQ;EAAY,MAAK;EAAO,GAAI;YAAhE;GACE,oBAAC,QAAD;IACE,GAAE;IACF,WAAU;IACV,CAAA;GACF,oBAAC,QAAD;IACE,GAAE;IACF,WAAU;IACV,CAAA;GACF,oBAAC,QAAD;IACE,GAAE;IACF,WAAU;IACV,CAAA;GACE"}