@signalflare-ai/ui 1.0.0 → 1.2.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 (300) hide show
  1. package/CHANGELOG.md +37 -4
  2. package/README.md +1 -1
  3. package/ai/component-registry.json +1047 -183
  4. package/ai/component-registry.md +4241 -50
  5. package/ai/schemas.ts +99 -502
  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-BdUZI3Gk.js} +3 -3
  10. package/dist/{ai-actions-DSVeQn4e.js.map → ai-actions-BdUZI3Gk.js.map} +1 -1
  11. package/dist/{ai-agent-card-BXHwhWAU.js → ai-agent-card-BR2NIYhi.js} +1 -1
  12. package/dist/{ai-agent-card-BXHwhWAU.js.map → ai-agent-card-BR2NIYhi.js.map} +1 -1
  13. package/dist/{ai-approval-aa0qvjFN.js → ai-approval-Ba7mrKba.js} +2 -2
  14. package/dist/{ai-approval-aa0qvjFN.js.map → ai-approval-Ba7mrKba.js.map} +1 -1
  15. package/dist/{ai-code-block-BgtIxtZZ.js → ai-code-block-CZtoL73R.js} +3 -3
  16. package/dist/{ai-code-block-BgtIxtZZ.js.map → ai-code-block-CZtoL73R.js.map} +1 -1
  17. package/dist/ai-conversation-Cc7WlaBg.js +242 -0
  18. package/dist/ai-conversation-Cc7WlaBg.js.map +1 -0
  19. package/dist/{ai-info-banner-uFxHHwBA.js → ai-info-banner-C7EWPBj7.js} +7 -3
  20. package/dist/ai-info-banner-C7EWPBj7.js.map +1 -0
  21. package/dist/{ai-message-BjnFznXy.js → ai-message-Bp7L68U_.js} +27 -8
  22. package/dist/ai-message-Bp7L68U_.js.map +1 -0
  23. package/dist/{ai-mission-header-08__gULL.js → ai-mission-header-TiCJfTNt.js} +1 -1
  24. package/dist/{ai-mission-header-08__gULL.js.map → ai-mission-header-TiCJfTNt.js.map} +1 -1
  25. package/dist/{ai-part-group-DBtgTgAn.js → ai-part-group-DNb9I446.js} +3 -3
  26. package/dist/{ai-part-group-DBtgTgAn.js.map → ai-part-group-DNb9I446.js.map} +1 -1
  27. package/dist/{ai-prompt-input-Dy1LfxPk.js → ai-prompt-input-BVvov_KF.js} +467 -25
  28. package/dist/ai-prompt-input-BVvov_KF.js.map +1 -0
  29. package/dist/{ai-question-CHHoDJMg.js → ai-question-GPPMk7YM.js} +2 -2
  30. package/dist/{ai-question-CHHoDJMg.js.map → ai-question-GPPMk7YM.js.map} +1 -1
  31. package/dist/{ai-reasoning-CnL6ZSr5.js → ai-reasoning-_feFjk56.js} +2 -2
  32. package/dist/{ai-reasoning-CnL6ZSr5.js.map → ai-reasoning-_feFjk56.js.map} +1 -1
  33. package/dist/{ai-response-BEUg3xvd.js → ai-response-CvjV3WhV.js} +8 -3
  34. package/dist/ai-response-CvjV3WhV.js.map +1 -0
  35. package/dist/{ai-shimmer-By5_L05p.js → ai-shimmer-j6lKIrjj.js} +1 -1
  36. package/dist/{ai-shimmer-By5_L05p.js.map → ai-shimmer-j6lKIrjj.js.map} +1 -1
  37. package/dist/{ai-status-badge-BGYGWYF6.js → ai-status-badge-CSU_QOdz.js} +1 -1
  38. package/dist/{ai-status-badge-BGYGWYF6.js.map → ai-status-badge-CSU_QOdz.js.map} +1 -1
  39. package/dist/{ai-streaming-text-CMfoThV0.js → ai-streaming-text-IWW1BhvZ.js} +44 -16
  40. package/dist/ai-streaming-text-IWW1BhvZ.js.map +1 -0
  41. package/dist/{ai-subagent-DcPRqkAA.js → ai-subagent-JA4iIMW3.js} +13 -5
  42. package/dist/ai-subagent-JA4iIMW3.js.map +1 -0
  43. package/dist/{ai-suggestion-MgeCg5Ar.js → ai-suggestion-BdO6MBuH.js} +2 -2
  44. package/dist/{ai-suggestion-MgeCg5Ar.js.map → ai-suggestion-BdO6MBuH.js.map} +1 -1
  45. package/dist/{ai-task-list-Da9zIm00.js → ai-task-list-DYw4R1FA.js} +12 -5
  46. package/dist/ai-task-list-DYw4R1FA.js.map +1 -0
  47. package/dist/{ai-timeline-Cwu045IR.js → ai-timeline-C42tOUT8.js} +1 -1
  48. package/dist/{ai-timeline-Cwu045IR.js.map → ai-timeline-C42tOUT8.js.map} +1 -1
  49. package/dist/{ai-tool-Cn1O4xjP.js → ai-tool-03jOTwUI.js} +23 -10
  50. package/dist/ai-tool-03jOTwUI.js.map +1 -0
  51. package/dist/{ai-usage-bar-DjS12DMp.js → ai-usage-bar-BRf5LC_b.js} +1 -1
  52. package/dist/{ai-usage-bar-DjS12DMp.js.map → ai-usage-bar-BRf5LC_b.js.map} +1 -1
  53. package/dist/{badge-D_eaA6wv.js → badge-BheXjMc8.js} +2 -2
  54. package/dist/{badge-D_eaA6wv.js.map → badge-BheXjMc8.js.map} +1 -1
  55. package/dist/{banner-B_6oBrsu.js → banner-CcsjunJg.js} +7 -2
  56. package/dist/banner-CcsjunJg.js.map +1 -0
  57. package/dist/{breadcrumbs-BlmeYfgq.js → breadcrumbs-CouSyy3H.js} +3 -3
  58. package/dist/{breadcrumbs-BlmeYfgq.js.map → breadcrumbs-CouSyy3H.js.map} +1 -1
  59. package/dist/{button-De0267YU.js → button-CO6-qPax.js} +1 -1
  60. package/dist/{button-De0267YU.js.map → button-CO6-qPax.js.map} +1 -1
  61. package/dist/catalog.js +1 -1
  62. package/dist/{chart-BK3sVPnD.js → chart-Dg0qUeSc.js} +2 -2
  63. package/dist/{chart-BK3sVPnD.js.map → chart-Dg0qUeSc.js.map} +1 -1
  64. package/dist/{checkbox-DYhUmZNw.js → checkbox-D7p4QKsC.js} +2 -2
  65. package/dist/{checkbox-DYhUmZNw.js.map → checkbox-D7p4QKsC.js.map} +1 -1
  66. package/dist/{clipboard-text-ssybngLw.js → clipboard-text-kLaMogs3.js} +3 -3
  67. package/dist/{clipboard-text-ssybngLw.js.map → clipboard-text-kLaMogs3.js.map} +1 -1
  68. package/dist/{code-Cx-QSoOT.js → code-BN8InC0G.js} +2 -2
  69. package/dist/{code-Cx-QSoOT.js.map → code-BN8InC0G.js.map} +1 -1
  70. package/dist/{collapsible-DWsXeXmS.js → collapsible-D_ueZ0jz.js} +1 -1
  71. package/dist/{collapsible-DWsXeXmS.js.map → collapsible-D_ueZ0jz.js.map} +1 -1
  72. package/dist/{combobox-C0iW6a0r.js → combobox-B7TOK0U2.js} +3 -3
  73. package/dist/{combobox-C0iW6a0r.js.map → combobox-B7TOK0U2.js.map} +1 -1
  74. package/dist/{command-palette-DGzioeki.js → command-palette-CuNUyJca.js} +2 -2
  75. package/dist/{command-palette-DGzioeki.js.map → command-palette-CuNUyJca.js.map} +1 -1
  76. package/dist/components/ai-actions.js +1 -1
  77. package/dist/components/ai-agent-card.js +1 -1
  78. package/dist/components/ai-approval.js +1 -1
  79. package/dist/components/ai-code-block.js +1 -1
  80. package/dist/components/ai-conversation.js +2 -2
  81. package/dist/components/ai-info-banner.js +1 -1
  82. package/dist/components/ai-message.js +1 -1
  83. package/dist/components/ai-mission-header.js +1 -1
  84. package/dist/components/ai-part-group.js +1 -1
  85. package/dist/components/ai-prompt-input.js +2 -2
  86. package/dist/components/ai-question.js +1 -1
  87. package/dist/components/ai-reasoning.js +1 -1
  88. package/dist/components/ai-response.js +1 -1
  89. package/dist/components/ai-shimmer.js +1 -1
  90. package/dist/components/ai-status-badge.js +1 -1
  91. package/dist/components/ai-streaming-text.js +2 -2
  92. package/dist/components/ai-subagent.js +1 -1
  93. package/dist/components/ai-suggestion.js +1 -1
  94. package/dist/components/ai-task-list.js +1 -1
  95. package/dist/components/ai-timeline.js +1 -1
  96. package/dist/components/ai-tool.js +1 -1
  97. package/dist/components/ai-usage-bar.js +1 -1
  98. package/dist/components/badge.js +1 -1
  99. package/dist/components/banner.js +1 -1
  100. package/dist/components/breadcrumbs.js +1 -1
  101. package/dist/components/button.js +1 -1
  102. package/dist/components/chart.js +2 -2
  103. package/dist/components/checkbox.js +1 -1
  104. package/dist/components/clipboard-text.js +1 -1
  105. package/dist/components/code.js +1 -1
  106. package/dist/components/collapsible.js +1 -1
  107. package/dist/components/combobox.js +1 -1
  108. package/dist/components/command-palette.js +1 -1
  109. package/dist/components/data-grid.js +1 -1
  110. package/dist/components/date-picker.js +1 -1
  111. package/dist/components/date-range-picker.js +1 -1
  112. package/dist/components/dialog.js +1 -1
  113. package/dist/components/dropdown.js +1 -1
  114. package/dist/components/empty.js +1 -1
  115. package/dist/components/field.js +1 -1
  116. package/dist/components/filters.js +1 -1
  117. package/dist/components/flow.js +1 -1
  118. package/dist/components/grid.js +1 -1
  119. package/dist/components/input.js +2 -2
  120. package/dist/components/label.js +1 -1
  121. package/dist/components/layer-card.js +1 -1
  122. package/dist/components/loader.js +1 -1
  123. package/dist/components/menubar.js +1 -1
  124. package/dist/components/meter.js +1 -1
  125. package/dist/components/pagination.js +1 -1
  126. package/dist/components/popover.js +1 -1
  127. package/dist/components/radio.js +1 -1
  128. package/dist/components/select.js +1 -1
  129. package/dist/components/sensitive-input.js +1 -1
  130. package/dist/components/sidebar.js +1 -1
  131. package/dist/components/signalflare-ai-logo.js +1 -1
  132. package/dist/components/sparkline.js +1 -1
  133. package/dist/components/stat-card.js +1 -1
  134. package/dist/components/surface.js +1 -1
  135. package/dist/components/switch.js +1 -1
  136. package/dist/components/table.js +1 -1
  137. package/dist/components/tabs.js +1 -1
  138. package/dist/components/text-roll.js +1 -1
  139. package/dist/components/text.js +1 -1
  140. package/dist/components/theme-toggle.js +1 -1
  141. package/dist/components/toast.js +1 -1
  142. package/dist/components/tooltip.js +1 -1
  143. package/dist/components/use-agent-harness.js +1 -1
  144. package/dist/{data-grid-CG76N_hK.js → data-grid-DGHmU0w3.js} +8 -8
  145. package/dist/{data-grid-CG76N_hK.js.map → data-grid-DGHmU0w3.js.map} +1 -1
  146. package/dist/{date-picker-Dqg9L4xu.js → date-picker--ox89RBy.js} +1 -1
  147. package/dist/{date-picker-Dqg9L4xu.js.map → date-picker--ox89RBy.js.map} +1 -1
  148. package/dist/{date-range-picker-D75LLINc.js → date-range-picker-DVa7QBqE.js} +1 -1
  149. package/dist/{date-range-picker-D75LLINc.js.map → date-range-picker-DVa7QBqE.js.map} +1 -1
  150. package/dist/{dialog-CyHEQXEY.js → dialog-Bv1oSFOd.js} +2 -2
  151. package/dist/{dialog-CyHEQXEY.js.map → dialog-Bv1oSFOd.js.map} +1 -1
  152. package/dist/{dist-1-gcEL2L.js → dist-B6iWiWwp.js} +25 -25
  153. package/dist/{dist-1-gcEL2L.js.map → dist-B6iWiWwp.js.map} +1 -1
  154. package/dist/{dropdown-qnEYRFXZ.js → dropdown-B_nrGXjV.js} +2 -2
  155. package/dist/{dropdown-qnEYRFXZ.js.map → dropdown-B_nrGXjV.js.map} +1 -1
  156. package/dist/{echart-DURZEyai.js → echart-CdOUaT-r.js} +1 -1
  157. package/dist/{echart-DURZEyai.js.map → echart-CdOUaT-r.js.map} +1 -1
  158. package/dist/{empty-D2TypIId.js → empty-DZnN0zKX.js} +11 -6
  159. package/dist/empty-DZnN0zKX.js.map +1 -0
  160. package/dist/{field-Y_UK1_Cg.js → field-B_yVof52.js} +2 -2
  161. package/dist/{field-Y_UK1_Cg.js.map → field-B_yVof52.js.map} +1 -1
  162. package/dist/{filters-Bw_U6ZTx.js → filters-cpJCY21R.js} +7 -7
  163. package/dist/{filters-Bw_U6ZTx.js.map → filters-cpJCY21R.js.map} +1 -1
  164. package/dist/{flow-BRsYUCJa.js → flow-B4v198ot.js} +1 -1
  165. package/dist/{flow-BRsYUCJa.js.map → flow-B4v198ot.js.map} +1 -1
  166. package/dist/genui.js +1 -1
  167. package/dist/{grid-qUAN9hFx.js → grid-CEd64Lnh.js} +1 -1
  168. package/dist/{grid-qUAN9hFx.js.map → grid-CEd64Lnh.js.map} +1 -1
  169. package/dist/{highlight-to-react-ClEfL81q.js → highlight-to-react-D0Yav4jk.js} +1 -1
  170. package/dist/{highlight-to-react-ClEfL81q.js.map → highlight-to-react-D0Yav4jk.js.map} +1 -1
  171. package/dist/index.js +69 -69
  172. package/dist/{input-DXYUjGgD.js → input-B2bbijRh.js} +2 -2
  173. package/dist/{input-DXYUjGgD.js.map → input-B2bbijRh.js.map} +1 -1
  174. package/dist/{input-DddtBN-g.js → input-ClB_E4Lb.js} +4 -4
  175. package/dist/{input-DddtBN-g.js.map → input-ClB_E4Lb.js.map} +1 -1
  176. package/dist/{label-QtJxtJ4u.js → label-DUv_urO1.js} +2 -2
  177. package/dist/{label-QtJxtJ4u.js.map → label-DUv_urO1.js.map} +1 -1
  178. package/dist/{layer-card-BME0eljh.js → layer-card-BK7eYfwn.js} +1 -1
  179. package/dist/{layer-card-BME0eljh.js.map → layer-card-BK7eYfwn.js.map} +1 -1
  180. package/dist/layout-DJHMMap2.js +6103 -0
  181. package/dist/layout-DJHMMap2.js.map +1 -0
  182. package/dist/measured-text-BI3dTJmH.js +290 -0
  183. package/dist/measured-text-BI3dTJmH.js.map +1 -0
  184. package/dist/{menubar-C8NzAjfd.js → menubar-Cxf3xeAt.js} +2 -2
  185. package/dist/{menubar-C8NzAjfd.js.map → menubar-Cxf3xeAt.js.map} +1 -1
  186. package/dist/{meter-CpmTenEr.js → meter-BFFe9l5b.js} +1 -1
  187. package/dist/{meter-CpmTenEr.js.map → meter-BFFe9l5b.js.map} +1 -1
  188. package/dist/{pagination-BVqdlONY.js → pagination-yS372Tr4.js} +2 -2
  189. package/dist/{pagination-BVqdlONY.js.map → pagination-yS372Tr4.js.map} +1 -1
  190. package/dist/{popover-BRQZ2b6z.js → popover-SRoJaCZr.js} +1 -1
  191. package/dist/{popover-BRQZ2b6z.js.map → popover-SRoJaCZr.js.map} +1 -1
  192. package/dist/{radio-BNSwOt3B.js → radio-BcwhwYNB.js} +1 -1
  193. package/dist/{radio-BNSwOt3B.js.map → radio-BcwhwYNB.js.map} +1 -1
  194. package/dist/{select-1w2aebGQ.js → select-DMhdoHMa.js} +4 -4
  195. package/dist/{select-1w2aebGQ.js.map → select-DMhdoHMa.js.map} +1 -1
  196. package/dist/{sensitive-input-82Cez3vj.js → sensitive-input-CJUpIRal.js} +3 -3
  197. package/dist/{sensitive-input-82Cez3vj.js.map → sensitive-input-CJUpIRal.js.map} +1 -1
  198. package/dist/{sidebar-CAsCmSpM.js → sidebar-D4zrlYpn.js} +2 -2
  199. package/dist/{sidebar-CAsCmSpM.js.map → sidebar-D4zrlYpn.js.map} +1 -1
  200. package/dist/{signalflare-ai-logo-DDhxMJD6.js → signalflare-ai-logo-Bipogceq.js} +1 -1
  201. package/dist/{signalflare-ai-logo-DDhxMJD6.js.map → signalflare-ai-logo-Bipogceq.js.map} +1 -1
  202. package/dist/{skeleton-line-Do3UmGk9.js → skeleton-line-CH1-h6e2.js} +1 -1
  203. package/dist/{skeleton-line-Do3UmGk9.js.map → skeleton-line-CH1-h6e2.js.map} +1 -1
  204. package/dist/{sparkline-DdbeM4Ai.js → sparkline-DHmgj1d0.js} +2 -2
  205. package/dist/{sparkline-DdbeM4Ai.js.map → sparkline-DHmgj1d0.js.map} +1 -1
  206. package/dist/src/blocks/agent-harness/agent-harness.d.ts.map +1 -1
  207. package/dist/src/blocks/agent-harness/agent-harness.tsx +29 -5
  208. package/dist/src/components/ai-conversation/ai-conversation.d.ts +69 -37
  209. package/dist/src/components/ai-conversation/ai-conversation.d.ts.map +1 -1
  210. package/dist/src/components/ai-conversation/index.d.ts +2 -1
  211. package/dist/src/components/ai-conversation/index.d.ts.map +1 -1
  212. package/dist/src/components/ai-conversation/measurement-constants.d.ts +30 -0
  213. package/dist/src/components/ai-conversation/measurement-constants.d.ts.map +1 -0
  214. package/dist/src/components/ai-info-banner/ai-info-banner.d.ts.map +1 -1
  215. package/dist/src/components/ai-message/ai-message.d.ts +3 -0
  216. package/dist/src/components/ai-message/ai-message.d.ts.map +1 -1
  217. package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts +58 -4
  218. package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts.map +1 -1
  219. package/dist/src/components/ai-prompt-input/controller.d.ts +10 -2
  220. package/dist/src/components/ai-prompt-input/controller.d.ts.map +1 -1
  221. package/dist/src/components/ai-prompt-input/index.d.ts +2 -2
  222. package/dist/src/components/ai-prompt-input/index.d.ts.map +1 -1
  223. package/dist/src/components/ai-prompt-input/types.d.ts +16 -0
  224. package/dist/src/components/ai-prompt-input/types.d.ts.map +1 -1
  225. package/dist/src/components/ai-response/ai-response.d.ts +12 -1
  226. package/dist/src/components/ai-response/ai-response.d.ts.map +1 -1
  227. package/dist/src/components/ai-streaming-text/ai-streaming-text.d.ts +27 -0
  228. package/dist/src/components/ai-streaming-text/ai-streaming-text.d.ts.map +1 -1
  229. package/dist/src/components/ai-streaming-text/index.d.ts +1 -1
  230. package/dist/src/components/ai-streaming-text/index.d.ts.map +1 -1
  231. package/dist/src/components/ai-subagent/ai-subagent.d.ts.map +1 -1
  232. package/dist/src/components/ai-task-list/ai-task-list.d.ts.map +1 -1
  233. package/dist/src/components/ai-tool/ai-tool.d.ts.map +1 -1
  234. package/dist/src/components/banner/banner.d.ts.map +1 -1
  235. package/dist/src/components/empty/empty.d.ts.map +1 -1
  236. package/dist/src/components/stat-card/stat-card.d.ts +5 -0
  237. package/dist/src/components/stat-card/stat-card.d.ts.map +1 -1
  238. package/dist/src/components/text/text.d.ts +35 -1
  239. package/dist/src/components/text/text.d.ts.map +1 -1
  240. package/dist/src/components/tooltip/tooltip.d.ts.map +1 -1
  241. package/dist/src/index.d.ts +3 -3
  242. package/dist/src/index.d.ts.map +1 -1
  243. package/dist/src/utils/index.d.ts +2 -0
  244. package/dist/src/utils/index.d.ts.map +1 -1
  245. package/dist/src/utils/measured-text.d.ts +40 -0
  246. package/dist/src/utils/measured-text.d.ts.map +1 -0
  247. package/dist/src/utils/use-measured-text.d.ts +59 -0
  248. package/dist/src/utils/use-measured-text.d.ts.map +1 -0
  249. package/dist/{stat-card-CEZscNh8.js → stat-card-Ew-ofzEm.js} +28 -10
  250. package/dist/stat-card-Ew-ofzEm.js.map +1 -0
  251. package/dist/styles/sf-binding.css +9 -1
  252. package/dist/styles/sf-standalone.css +2 -2
  253. package/dist/styles/shadcn.css +1 -1
  254. package/dist/styles/theme-fedramp.css +12 -3
  255. package/dist/styles/theme-minimal.css +104 -26
  256. package/dist/styles/theme-sf.css +138 -39
  257. package/dist/styles/theme-vesper.css +91 -0
  258. package/dist/{surface-BduI7Ehl.js → surface-DGwRlC0o.js} +1 -1
  259. package/dist/{surface-BduI7Ehl.js.map → surface-DGwRlC0o.js.map} +1 -1
  260. package/dist/{switch-CzZBRBL7.js → switch-BxAMfHdt.js} +2 -2
  261. package/dist/{switch-CzZBRBL7.js.map → switch-BxAMfHdt.js.map} +1 -1
  262. package/dist/{table-Rv4JMy0B.js → table-BBeAtYVZ.js} +2 -2
  263. package/dist/{table-Rv4JMy0B.js.map → table-BBeAtYVZ.js.map} +1 -1
  264. package/dist/{tabs-1cHrYoel.js → tabs-CeHu7Scn.js} +1 -1
  265. package/dist/{tabs-1cHrYoel.js.map → tabs-CeHu7Scn.js.map} +1 -1
  266. package/dist/{text-KJmGkwnf.js → text-Cqryz7rk.js} +27 -5
  267. package/dist/text-Cqryz7rk.js.map +1 -0
  268. package/dist/{text-roll-BZ3I1umc.js → text-roll-Ch52hcQj.js} +1 -1
  269. package/dist/{text-roll-BZ3I1umc.js.map → text-roll-Ch52hcQj.js.map} +1 -1
  270. package/dist/{theme-toggle-Bhu681D7.js → theme-toggle-LDfIKEqx.js} +3 -3
  271. package/dist/{theme-toggle-Bhu681D7.js.map → theme-toggle-LDfIKEqx.js.map} +1 -1
  272. package/dist/{toast-Nw28a5Cx.js → toast-CaFQNYng.js} +2 -2
  273. package/dist/{toast-Nw28a5Cx.js.map → toast-CaFQNYng.js.map} +1 -1
  274. package/dist/{tooltip-Cb7QW-7H.js → tooltip-g9lFsvcT.js} +8 -2
  275. package/dist/tooltip-g9lFsvcT.js.map +1 -0
  276. package/dist/{use-agent-harness-BMyF8pTq.js → use-agent-harness-BTcNJdw4.js} +1 -1
  277. package/dist/{use-agent-harness-BMyF8pTq.js.map → use-agent-harness-BTcNJdw4.js.map} +1 -1
  278. package/dist/utils.js +2 -1
  279. package/package.json +2 -1
  280. package/scripts/component-registry/index.ts +2 -2
  281. package/scripts/css-build.ts +1 -1
  282. package/scripts/theme-generator/config.ts +27 -141
  283. package/scripts/theme-generator/generate-css.ts +0 -1
  284. package/scripts/theme-generator/index.ts +0 -1
  285. package/dist/ai-conversation-CArP7C8K.js +0 -184
  286. package/dist/ai-conversation-CArP7C8K.js.map +0 -1
  287. package/dist/ai-info-banner-uFxHHwBA.js.map +0 -1
  288. package/dist/ai-message-BjnFznXy.js.map +0 -1
  289. package/dist/ai-prompt-input-Dy1LfxPk.js.map +0 -1
  290. package/dist/ai-response-BEUg3xvd.js.map +0 -1
  291. package/dist/ai-streaming-text-CMfoThV0.js.map +0 -1
  292. package/dist/ai-subagent-DcPRqkAA.js.map +0 -1
  293. package/dist/ai-task-list-Da9zIm00.js.map +0 -1
  294. package/dist/ai-tool-Cn1O4xjP.js.map +0 -1
  295. package/dist/banner-B_6oBrsu.js.map +0 -1
  296. package/dist/empty-D2TypIId.js.map +0 -1
  297. package/dist/stat-card-CEZscNh8.js.map +0 -1
  298. package/dist/styles/theme-blue-tint.css +0 -98
  299. package/dist/text-KJmGkwnf.js.map +0 -1
  300. package/dist/tooltip-Cb7QW-7H.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"table-Rv4JMy0B.js","names":[],"sources":["../src/components/table/table.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\n\nimport { cn } from \"../../utils\";\nimport { Checkbox } from \"../checkbox\";\n\n/** Table layout and row variant definitions mapping names to their Tailwind classes. */\nexport const SF_TABLE_VARIANTS = {\n layout: {\n auto: {\n classes: \"\",\n description: \"Auto table layout - columns resize based on content\",\n },\n fixed: {\n classes: \"table-fixed\",\n description:\n \"Fixed table layout - columns have equal width, controlled via colgroup\",\n },\n },\n variant: {\n default: {\n classes: \"\",\n description: \"Default row variant\",\n },\n selected: {\n classes: \"bg-sf-tint\",\n description: \"Selected row variant\",\n },\n },\n} as const;\n\nexport const SF_TABLE_DEFAULT_VARIANTS = {\n layout: \"auto\",\n variant: \"default\",\n} as const;\n\nexport type SFTableRowVariant = keyof typeof SF_TABLE_VARIANTS.variant;\nexport type SFTableLayout = keyof typeof SF_TABLE_VARIANTS.layout;\n\n/**\n * Table root — applies layout, borders, padding, and header styles.\n *\n * @example\n * ```tsx\n * <Table layout=\"fixed\">\n * <Table.Header>\n * <Table.Row>\n * <Table.Head>Name</Table.Head>\n * <Table.Head>Status</Table.Head>\n * </Table.Row>\n * </Table.Header>\n * <Table.Body>\n * <Table.Row>\n * <Table.Cell>Worker A</Table.Cell>\n * <Table.Cell>Active</Table.Cell>\n * </Table.Row>\n * </Table.Body>\n * </Table>\n * ```\n */\nconst TableRoot = forwardRef<\n HTMLTableElement,\n React.HTMLAttributes<HTMLTableElement> & {\n /**\n * Table layout algorithm.\n * - `\"auto\"` — columns resize based on content\n * - `\"fixed\"` — equal-width columns, controlled via `<colgroup>`\n * @default \"auto\"\n */\n layout?: SFTableLayout;\n }\n>(({ layout = \"auto\", ...props }, ref) => {\n const className = cn(\n \"w-full\",\n SF_TABLE_VARIANTS.layout[layout].classes,\n \"[&_tr_td]:border-b [&_tr_td]:border-sf-fill [&_tr:last-child_td]:border-b-0\", // Row border\n \"[&_tr_td]:p-3\", // Cell padding\n \"[&_tr_th]:border-b [&_tr_th]:border-sf-fill [&_tr_th]:p-3 [&_tr_th]:font-semibold\", // Header styles\n \"[&_tr_th]:bg-sf-base\", // Header background color\n \"text-left text-sf-default\",\n props.className\n );\n\n return <table ref={ref} {...props} className={className} />;\n});\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <thead ref={ref} {...props} />;\n});\n\nconst TableHead = forwardRef<\n HTMLTableCellElement,\n React.HTMLAttributes<HTMLTableCellElement>\n>((props, ref) => {\n const className = cn(\"group relative\", props.className);\n return <th ref={ref} {...props} className={className} />;\n});\n\nconst TableRow = forwardRef<\n HTMLTableRowElement,\n React.HTMLAttributes<HTMLTableRowElement> & {\n variant?: SFTableRowVariant;\n }\n>(({ variant = SF_TABLE_DEFAULT_VARIANTS.variant, ...props }, ref) => {\n const className = cn(\n SF_TABLE_VARIANTS.variant[variant].classes,\n props.className\n );\n\n return <tr ref={ref} {...props} className={className} />;\n});\n\nconst TableBody = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <tbody ref={ref} {...props} />;\n});\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement>\n>((props, ref) => {\n return <td ref={ref} {...props} />;\n});\n\nconst TableFooter = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <tfoot ref={ref} {...props} />;\n});\n\nconst TableResizeHandle = forwardRef<\n HTMLButtonElement,\n React.HTMLAttributes<HTMLButtonElement>\n>((props, ref) => {\n return (\n <button\n ref={ref}\n {...props}\n type=\"button\"\n aria-label=\"Resize column\"\n className={cn(\n \"invisible h-full group-hover:visible\", // Make the handle invisible by default\n \"w-[10px]\", // Hitting area\n \"flex items-center justify-center\", // Center the handle\n \"cursor-col-resize touch-none select-none\", // Prevent selection and touch events\n \"absolute top-0 right-0\", // Position the handle\n \"m-0 bg-sf-base p-0\" // Override the stratus button styles\n )}\n >\n <span className=\"h-5 w-[2px] rounded bg-sf-ring\" />\n </button>\n );\n});\n\n/**\n * Special cell that makes the entire cell area a hit target for the checkbox.\n */\n\nconst TableCheckCell = forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement> & {\n checked?: boolean;\n indeterminate?: boolean;\n onValueChange?: (checked: boolean) => void;\n label?: string;\n disabled?: boolean;\n }\n>(\n (\n { checked, indeterminate, onValueChange, label, disabled, ...props },\n ref\n ) => {\n return (\n <TableCell\n ref={ref}\n {...props}\n className={cn(\"w-10 leading-none\", props.className)}\n >\n <Checkbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckedChange={(newChecked) => {\n onValueChange?.(newChecked);\n }}\n aria-label={label ?? \"Select row\"}\n disabled={disabled}\n className=\"relative before:absolute before:-inset-3 before:content-['']\"\n />\n </TableCell>\n );\n }\n);\n\nconst TableCheckHead = forwardRef<\n HTMLTableCellElement,\n React.ThHTMLAttributes<HTMLTableCellElement> & {\n checked?: boolean;\n indeterminate?: boolean;\n onValueChange?: (checked: boolean) => void;\n label?: string;\n disabled?: boolean;\n }\n>(\n (\n { checked, indeterminate, onValueChange, label, disabled, ...props },\n ref\n ) => {\n return (\n <TableHead\n ref={ref}\n {...props}\n className={cn(\"w-10 leading-none\", props.className)}\n >\n <Checkbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckedChange={(newChecked) => {\n onValueChange?.(newChecked);\n }}\n aria-label={label ?? \"Select all rows\"}\n disabled={disabled}\n className=\"relative before:absolute before:-inset-3 before:content-['']\"\n />\n </TableHead>\n );\n }\n);\n\nTableRoot.displayName = \"Table\";\nTableBody.displayName = \"Table.Body\";\nTableHead.displayName = \"Table.Head\";\nTableRow.displayName = \"Table.Row\";\nTableCell.displayName = \"Table.Cell\";\nTableFooter.displayName = \"Table.Footer\";\nTableHeader.displayName = \"Table.Header\";\nTableResizeHandle.displayName = \"Table.ResizeHandle\";\nTableCheckCell.displayName = \"Table.CheckCell\";\nTableCheckHead.displayName = \"Table.CheckHead\";\n\n/**\n * Table — semantic HTML table with styled rows, cells, and selection support.\n *\n * Compound component: `Table` (Root), `.Header`, `.Head`, `.Body`, `.Row`,\n * `.Cell`, `.Footer`, `.CheckCell`, `.CheckHead`, `.ResizeHandle`.\n *\n * @example\n * ```tsx\n * <Table>\n * <Table.Header>\n * <Table.Row>\n * <Table.CheckHead checked={allSelected} onValueChange={toggleAll} />\n * <Table.Head>Name</Table.Head>\n * </Table.Row>\n * </Table.Header>\n * <Table.Body>\n * {rows.map((row) => (\n * <Table.Row key={row.id} variant={selected.has(row.id) ? \"selected\" : \"default\"}>\n * <Table.CheckCell checked={selected.has(row.id)} onValueChange={() => toggle(row.id)} />\n * <Table.Cell>{row.name}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * </Table>\n * ```\n */\nexport const Table = Object.assign(TableRoot, {\n Header: TableHeader,\n Head: TableHead,\n Row: TableRow,\n Body: TableBody,\n Cell: TableCell,\n CheckCell: TableCheckCell,\n CheckHead: TableCheckHead,\n Footer: TableFooter,\n ResizeHandle: TableResizeHandle,\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"table-BBeAtYVZ.js","names":[],"sources":["../src/components/table/table.tsx"],"sourcesContent":["import { forwardRef } from \"react\";\n\nimport { cn } from \"../../utils\";\nimport { Checkbox } from \"../checkbox\";\n\n/** Table layout and row variant definitions mapping names to their Tailwind classes. */\nexport const SF_TABLE_VARIANTS = {\n layout: {\n auto: {\n classes: \"\",\n description: \"Auto table layout - columns resize based on content\",\n },\n fixed: {\n classes: \"table-fixed\",\n description:\n \"Fixed table layout - columns have equal width, controlled via colgroup\",\n },\n },\n variant: {\n default: {\n classes: \"\",\n description: \"Default row variant\",\n },\n selected: {\n classes: \"bg-sf-tint\",\n description: \"Selected row variant\",\n },\n },\n} as const;\n\nexport const SF_TABLE_DEFAULT_VARIANTS = {\n layout: \"auto\",\n variant: \"default\",\n} as const;\n\nexport type SFTableRowVariant = keyof typeof SF_TABLE_VARIANTS.variant;\nexport type SFTableLayout = keyof typeof SF_TABLE_VARIANTS.layout;\n\n/**\n * Table root — applies layout, borders, padding, and header styles.\n *\n * @example\n * ```tsx\n * <Table layout=\"fixed\">\n * <Table.Header>\n * <Table.Row>\n * <Table.Head>Name</Table.Head>\n * <Table.Head>Status</Table.Head>\n * </Table.Row>\n * </Table.Header>\n * <Table.Body>\n * <Table.Row>\n * <Table.Cell>Worker A</Table.Cell>\n * <Table.Cell>Active</Table.Cell>\n * </Table.Row>\n * </Table.Body>\n * </Table>\n * ```\n */\nconst TableRoot = forwardRef<\n HTMLTableElement,\n React.HTMLAttributes<HTMLTableElement> & {\n /**\n * Table layout algorithm.\n * - `\"auto\"` — columns resize based on content\n * - `\"fixed\"` — equal-width columns, controlled via `<colgroup>`\n * @default \"auto\"\n */\n layout?: SFTableLayout;\n }\n>(({ layout = \"auto\", ...props }, ref) => {\n const className = cn(\n \"w-full\",\n SF_TABLE_VARIANTS.layout[layout].classes,\n \"[&_tr_td]:border-b [&_tr_td]:border-sf-fill [&_tr:last-child_td]:border-b-0\", // Row border\n \"[&_tr_td]:p-3\", // Cell padding\n \"[&_tr_th]:border-b [&_tr_th]:border-sf-fill [&_tr_th]:p-3 [&_tr_th]:font-semibold\", // Header styles\n \"[&_tr_th]:bg-sf-base\", // Header background color\n \"text-left text-sf-default\",\n props.className\n );\n\n return <table ref={ref} {...props} className={className} />;\n});\n\nconst TableHeader = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <thead ref={ref} {...props} />;\n});\n\nconst TableHead = forwardRef<\n HTMLTableCellElement,\n React.HTMLAttributes<HTMLTableCellElement>\n>((props, ref) => {\n const className = cn(\"group relative\", props.className);\n return <th ref={ref} {...props} className={className} />;\n});\n\nconst TableRow = forwardRef<\n HTMLTableRowElement,\n React.HTMLAttributes<HTMLTableRowElement> & {\n variant?: SFTableRowVariant;\n }\n>(({ variant = SF_TABLE_DEFAULT_VARIANTS.variant, ...props }, ref) => {\n const className = cn(\n SF_TABLE_VARIANTS.variant[variant].classes,\n props.className\n );\n\n return <tr ref={ref} {...props} className={className} />;\n});\n\nconst TableBody = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <tbody ref={ref} {...props} />;\n});\n\nconst TableCell = forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement>\n>((props, ref) => {\n return <td ref={ref} {...props} />;\n});\n\nconst TableFooter = forwardRef<\n HTMLTableSectionElement,\n React.HTMLAttributes<HTMLTableSectionElement>\n>((props, ref) => {\n return <tfoot ref={ref} {...props} />;\n});\n\nconst TableResizeHandle = forwardRef<\n HTMLButtonElement,\n React.HTMLAttributes<HTMLButtonElement>\n>((props, ref) => {\n return (\n <button\n ref={ref}\n {...props}\n type=\"button\"\n aria-label=\"Resize column\"\n className={cn(\n \"invisible h-full group-hover:visible\", // Make the handle invisible by default\n \"w-[10px]\", // Hitting area\n \"flex items-center justify-center\", // Center the handle\n \"cursor-col-resize touch-none select-none\", // Prevent selection and touch events\n \"absolute top-0 right-0\", // Position the handle\n \"m-0 bg-sf-base p-0\" // Override the stratus button styles\n )}\n >\n <span className=\"h-5 w-[2px] rounded bg-sf-ring\" />\n </button>\n );\n});\n\n/**\n * Special cell that makes the entire cell area a hit target for the checkbox.\n */\n\nconst TableCheckCell = forwardRef<\n HTMLTableCellElement,\n React.TdHTMLAttributes<HTMLTableCellElement> & {\n checked?: boolean;\n indeterminate?: boolean;\n onValueChange?: (checked: boolean) => void;\n label?: string;\n disabled?: boolean;\n }\n>(\n (\n { checked, indeterminate, onValueChange, label, disabled, ...props },\n ref\n ) => {\n return (\n <TableCell\n ref={ref}\n {...props}\n className={cn(\"w-10 leading-none\", props.className)}\n >\n <Checkbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckedChange={(newChecked) => {\n onValueChange?.(newChecked);\n }}\n aria-label={label ?? \"Select row\"}\n disabled={disabled}\n className=\"relative before:absolute before:-inset-3 before:content-['']\"\n />\n </TableCell>\n );\n }\n);\n\nconst TableCheckHead = forwardRef<\n HTMLTableCellElement,\n React.ThHTMLAttributes<HTMLTableCellElement> & {\n checked?: boolean;\n indeterminate?: boolean;\n onValueChange?: (checked: boolean) => void;\n label?: string;\n disabled?: boolean;\n }\n>(\n (\n { checked, indeterminate, onValueChange, label, disabled, ...props },\n ref\n ) => {\n return (\n <TableHead\n ref={ref}\n {...props}\n className={cn(\"w-10 leading-none\", props.className)}\n >\n <Checkbox\n checked={checked}\n indeterminate={indeterminate}\n onCheckedChange={(newChecked) => {\n onValueChange?.(newChecked);\n }}\n aria-label={label ?? \"Select all rows\"}\n disabled={disabled}\n className=\"relative before:absolute before:-inset-3 before:content-['']\"\n />\n </TableHead>\n );\n }\n);\n\nTableRoot.displayName = \"Table\";\nTableBody.displayName = \"Table.Body\";\nTableHead.displayName = \"Table.Head\";\nTableRow.displayName = \"Table.Row\";\nTableCell.displayName = \"Table.Cell\";\nTableFooter.displayName = \"Table.Footer\";\nTableHeader.displayName = \"Table.Header\";\nTableResizeHandle.displayName = \"Table.ResizeHandle\";\nTableCheckCell.displayName = \"Table.CheckCell\";\nTableCheckHead.displayName = \"Table.CheckHead\";\n\n/**\n * Table — semantic HTML table with styled rows, cells, and selection support.\n *\n * Compound component: `Table` (Root), `.Header`, `.Head`, `.Body`, `.Row`,\n * `.Cell`, `.Footer`, `.CheckCell`, `.CheckHead`, `.ResizeHandle`.\n *\n * @example\n * ```tsx\n * <Table>\n * <Table.Header>\n * <Table.Row>\n * <Table.CheckHead checked={allSelected} onValueChange={toggleAll} />\n * <Table.Head>Name</Table.Head>\n * </Table.Row>\n * </Table.Header>\n * <Table.Body>\n * {rows.map((row) => (\n * <Table.Row key={row.id} variant={selected.has(row.id) ? \"selected\" : \"default\"}>\n * <Table.CheckCell checked={selected.has(row.id)} onValueChange={() => toggle(row.id)} />\n * <Table.Cell>{row.name}</Table.Cell>\n * </Table.Row>\n * ))}\n * </Table.Body>\n * </Table>\n * ```\n */\nexport const Table = Object.assign(TableRoot, {\n Header: TableHeader,\n Head: TableHead,\n Row: TableRow,\n Body: TableBody,\n Cell: TableCell,\n CheckCell: TableCheckCell,\n CheckHead: TableCheckHead,\n Footer: TableFooter,\n ResizeHandle: TableResizeHandle,\n});\n"],"mappings":"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"}
@@ -51,4 +51,4 @@ function Tabs$1({ tabs, value, selectedValue, onValueChange, activateOnFocus, cl
51
51
  //#endregion
52
52
  export { Tabs$1 as t };
53
53
 
54
- //# sourceMappingURL=tabs-1cHrYoel.js.map
54
+ //# sourceMappingURL=tabs-CeHu7Scn.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabs-1cHrYoel.js","names":[],"sources":["../src/components/tabs/tabs.tsx"],"sourcesContent":["import { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\n\n/** Tabs variant definitions. */\nexport const SF_TABS_VARIANTS = {\n variant: [\"segmented\", \"underline\", \"pill\"],\n} as const;\n\nexport const SF_TABS_DEFAULT_VARIANTS = {\n variant: \"segmented\",\n} as const;\n\nexport const SF_TABS_STYLING = {\n container: {\n height: 34,\n borderRadius: 8,\n background: \"color-accent\",\n padding: 1,\n },\n tab: {\n paddingX: 10,\n verticalMargin: 1,\n fontSize: 16,\n fontWeight: 500,\n borderRadius: 8,\n activeColor: \"text-color-surface\",\n inactiveColor: \"text-color-label\",\n },\n indicator: {\n background: \"color-surface-secondary\",\n ring: \"color-color-2\",\n borderRadius: 6,\n shadow: \"shadow-sm\",\n },\n} as const;\n\n// Derived types from SF_TABS_VARIANTS\nexport interface SFTabsVariantsProps {\n /**\n * Tab style.\n * - `\"segmented\"` — Pill-shaped indicator on a filled track\n * - `\"underline\"` — Underline indicator below tab text\n * - `\"pill\"` — Fully rounded tabs, only selected has background\n * @default \"segmented\"\n */\n variant?: (typeof SF_TABS_VARIANTS.variant)[number];\n}\n\n/** Configuration for a single tab within the Tabs component. */\nexport type TabsItem = {\n /** Unique identifier for the tab, used as the controlled value. */\n value: string;\n /** Display content for the tab trigger. */\n label: ReactNode;\n /** Additional CSS classes for this tab trigger. */\n className?: string;\n /** Custom render function to replace the tab element (e.g. for link-based tabs). */\n render?: (props: Record<string, unknown>) => React.ReactElement;\n};\n\n/**\n * Tabs component props.\n *\n * @example\n * ```tsx\n * <Tabs\n * tabs={[\n * { value: \"overview\", label: \"Overview\" },\n * { value: \"settings\", label: \"Settings\" },\n * ]}\n * value={activeTab}\n * onValueChange={setActiveTab}\n * />\n * ```\n */\nexport type TabsProps = SFTabsVariantsProps & {\n /** Array of tab items to render. */\n tabs?: TabsItem[];\n /** Controlled value. When set, component becomes controlled. */\n value?: string;\n /** Default selected value for uncontrolled mode. Ignored when `value` is set. */\n selectedValue?: string;\n /** Callback fired when the active tab changes. */\n onValueChange?: (value: string) => void;\n /**\n * When `true`, tabs are activated immediately upon receiving focus via arrow keys.\n * When `false` (default), tabs receive focus but require Enter/Space to activate.\n */\n activateOnFocus?: boolean;\n /** Additional CSS classes for the root element. */\n className?: string;\n /** Additional CSS classes for the tab list element. */\n listClassName?: string;\n /** Additional CSS classes for the indicator element. */\n indicatorClassName?: string;\n};\n\n/**\n * Tab navigation component with segmented, underline, or pill style.\n * Built on Base UI Tabs with animated active indicator.\n *\n * @example\n * ```tsx\n * <Tabs\n * variant=\"segmented\"\n * tabs={[{ value: \"tab1\", label: \"Tab 1\" }, { value: \"tab2\", label: \"Tab 2\" }]}\n * value={active}\n * onValueChange={setActive}\n * />\n * <Tabs variant=\"pill\" tabs={[...]} value={active} />\n * ```\n */\nexport function Tabs({\n tabs,\n value,\n selectedValue,\n onValueChange,\n activateOnFocus,\n className,\n listClassName,\n indicatorClassName,\n variant = SF_TABS_DEFAULT_VARIANTS.variant,\n}: TabsProps) {\n const items: TabsItem[] = tabs ?? [];\n\n if (items.length === 0) {\n return null;\n }\n\n const fallbackValue = items[0]?.value;\n const isControlled = value !== undefined;\n const rootProps = {\n value: isControlled ? value : undefined,\n defaultValue: isControlled ? undefined : (selectedValue ?? fallbackValue),\n };\n\n const isSegmented = variant === \"segmented\";\n const isUnderline = variant === \"underline\";\n const isPill = variant === \"pill\";\n\n return (\n <TabsPrimitive.Root\n {...rootProps}\n className={cn(\"relative min-w-0 font-medium\", className)}\n onValueChange={(nextValue) => {\n const stringValue = String(nextValue);\n onValueChange?.(stringValue);\n }}\n >\n {/* Background element for segmented variant only */}\n {(isSegmented || isPill) && (\n <div\n className={cn(\n \"absolute inset-x-0 top-1/2 -z-10 h-8.5 -translate-y-1/2 rounded-lg\",\n isSegmented && \"bg-sf-tint\",\n isPill && \"hidden\"\n )}\n />\n )}\n <TabsPrimitive.List\n activateOnFocus={activateOnFocus}\n className={cn(\n \"scrollbar-hide relative flex min-w-0 shrink items-stretch\",\n isSegmented && \"h-8.5 rounded-lg bg-sf-tint px-px\",\n isUnderline && \"h-7 gap-4 border-b border-sf-line pb-2\",\n isPill && \"h-9 gap-1\",\n listClassName\n )}\n >\n {items.map((tab) => (\n <TabsPrimitive.Tab\n key={tab.value}\n value={tab.value}\n className={cn(\n \"relative z-10 flex cursor-pointer items-center whitespace-nowrap hover:border-sf-tint focus-visible:rounded-none focus-visible:ring-sf-ring focus-visible:outline-offset-3\",\n isSegmented &&\n \"my-px rounded-lg bg-transparent px-2.5 text-base text-sf-strong aria-selected:text-sf-default\",\n isUnderline &&\n \"mb-2 text-base text-sf-strong hover:text-sf-subtle aria-selected:font-medium aria-selected:text-sf-default\",\n isPill &&\n \"rounded-full px-3 text-sm text-sf-strong transition-colors hover:bg-sf-tint/50 hover:text-sf-subtle aria-selected:bg-sf-tint aria-selected:font-medium aria-selected:text-sf-default\",\n tab.className\n )}\n >\n {tab.label}\n </TabsPrimitive.Tab>\n ))}\n <TabsPrimitive.Indicator\n className={cn(\n \"absolute z-0 transition-[left,width,transform] duration-200 ease-out\",\n \"data-[rendered=false]:scale-90 data-[rendered=false]:opacity-0\",\n \"left-(--active-tab-left) w-(--active-tab-width)\",\n isSegmented &&\n \"top-(--active-tab-top) h-(--active-tab-height) rounded-lg bg-sf-overlay shadow-sm ring ring-sf-fill-hover\",\n isUnderline && \"bottom-0 h-0.5 bg-sf-brand\",\n isPill && \"hidden\",\n indicatorClassName\n )}\n />\n </TabsPrimitive.List>\n </TabsPrimitive.Root>\n );\n}\n"],"mappings":";;;;;AAUA,IAAa,2BAA2B,EACtC,SAAS,aACV;;;;;;;;;;;;;;;;AAsGD,SAAgB,OAAK,EACnB,MACA,OACA,eACA,eACA,iBACA,WACA,eACA,oBACA,UAAU,yBAAyB,WACvB;CACZ,MAAM,QAAoB,QAAQ,EAAE;AAEpC,KAAI,MAAM,WAAW,EACnB,QAAO;CAGT,MAAM,gBAAgB,MAAM,IAAI;CAChC,MAAM,eAAe,UAAU,KAAA;CAC/B,MAAM,YAAY;EAChB,OAAO,eAAe,QAAQ,KAAA;EAC9B,cAAc,eAAe,KAAA,IAAa,iBAAiB;EAC5D;CAED,MAAM,cAAc,YAAY;CAChC,MAAM,cAAc,YAAY;CAChC,MAAM,SAAS,YAAY;AAE3B,QACE,qBAAC,KAAc,MAAf;EACE,GAAI;EACJ,WAAW,GAAG,gCAAgC,UAAU;EACxD,gBAAgB,cAAc;AAE5B,mBADoB,OAAO,UAAU,CACT;;YALhC,EASI,eAAe,WACf,oBAAC,OAAD,EACE,WAAW,GACT,sEACA,eAAe,cACf,UAAU,SACX,EACD,CAAA,EAEJ,qBAAC,KAAc,MAAf;GACmB;GACjB,WAAW,GACT,6DACA,eAAe,qCACf,eAAe,0CACf,UAAU,aACV,cACD;aARH,CAUG,MAAM,KAAK,QACV,oBAAC,KAAc,KAAf;IAEE,OAAO,IAAI;IACX,WAAW,GACT,8KACA,eACE,iGACF,eACE,8GACF,UACE,wLACF,IAAI,UACL;cAEA,IAAI;IACa,EAdb,IAAI,MAcS,CACpB,EACF,oBAAC,KAAc,WAAf,EACE,WAAW,GACT,wEACA,kEACA,mDACA,eACE,6GACF,eAAe,8BACf,UAAU,UACV,mBACD,EACD,CAAA,CACiB;KACF"}
1
+ {"version":3,"file":"tabs-CeHu7Scn.js","names":[],"sources":["../src/components/tabs/tabs.tsx"],"sourcesContent":["import { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\";\nimport type { ReactNode } from \"react\";\n\nimport { cn } from \"../../utils/cn\";\n\n/** Tabs variant definitions. */\nexport const SF_TABS_VARIANTS = {\n variant: [\"segmented\", \"underline\", \"pill\"],\n} as const;\n\nexport const SF_TABS_DEFAULT_VARIANTS = {\n variant: \"segmented\",\n} as const;\n\nexport const SF_TABS_STYLING = {\n container: {\n height: 34,\n borderRadius: 8,\n background: \"color-accent\",\n padding: 1,\n },\n tab: {\n paddingX: 10,\n verticalMargin: 1,\n fontSize: 16,\n fontWeight: 500,\n borderRadius: 8,\n activeColor: \"text-color-surface\",\n inactiveColor: \"text-color-label\",\n },\n indicator: {\n background: \"color-surface-secondary\",\n ring: \"color-color-2\",\n borderRadius: 6,\n shadow: \"shadow-sm\",\n },\n} as const;\n\n// Derived types from SF_TABS_VARIANTS\nexport interface SFTabsVariantsProps {\n /**\n * Tab style.\n * - `\"segmented\"` — Pill-shaped indicator on a filled track\n * - `\"underline\"` — Underline indicator below tab text\n * - `\"pill\"` — Fully rounded tabs, only selected has background\n * @default \"segmented\"\n */\n variant?: (typeof SF_TABS_VARIANTS.variant)[number];\n}\n\n/** Configuration for a single tab within the Tabs component. */\nexport type TabsItem = {\n /** Unique identifier for the tab, used as the controlled value. */\n value: string;\n /** Display content for the tab trigger. */\n label: ReactNode;\n /** Additional CSS classes for this tab trigger. */\n className?: string;\n /** Custom render function to replace the tab element (e.g. for link-based tabs). */\n render?: (props: Record<string, unknown>) => React.ReactElement;\n};\n\n/**\n * Tabs component props.\n *\n * @example\n * ```tsx\n * <Tabs\n * tabs={[\n * { value: \"overview\", label: \"Overview\" },\n * { value: \"settings\", label: \"Settings\" },\n * ]}\n * value={activeTab}\n * onValueChange={setActiveTab}\n * />\n * ```\n */\nexport type TabsProps = SFTabsVariantsProps & {\n /** Array of tab items to render. */\n tabs?: TabsItem[];\n /** Controlled value. When set, component becomes controlled. */\n value?: string;\n /** Default selected value for uncontrolled mode. Ignored when `value` is set. */\n selectedValue?: string;\n /** Callback fired when the active tab changes. */\n onValueChange?: (value: string) => void;\n /**\n * When `true`, tabs are activated immediately upon receiving focus via arrow keys.\n * When `false` (default), tabs receive focus but require Enter/Space to activate.\n */\n activateOnFocus?: boolean;\n /** Additional CSS classes for the root element. */\n className?: string;\n /** Additional CSS classes for the tab list element. */\n listClassName?: string;\n /** Additional CSS classes for the indicator element. */\n indicatorClassName?: string;\n};\n\n/**\n * Tab navigation component with segmented, underline, or pill style.\n * Built on Base UI Tabs with animated active indicator.\n *\n * @example\n * ```tsx\n * <Tabs\n * variant=\"segmented\"\n * tabs={[{ value: \"tab1\", label: \"Tab 1\" }, { value: \"tab2\", label: \"Tab 2\" }]}\n * value={active}\n * onValueChange={setActive}\n * />\n * <Tabs variant=\"pill\" tabs={[...]} value={active} />\n * ```\n */\nexport function Tabs({\n tabs,\n value,\n selectedValue,\n onValueChange,\n activateOnFocus,\n className,\n listClassName,\n indicatorClassName,\n variant = SF_TABS_DEFAULT_VARIANTS.variant,\n}: TabsProps) {\n const items: TabsItem[] = tabs ?? [];\n\n if (items.length === 0) {\n return null;\n }\n\n const fallbackValue = items[0]?.value;\n const isControlled = value !== undefined;\n const rootProps = {\n value: isControlled ? value : undefined,\n defaultValue: isControlled ? undefined : (selectedValue ?? fallbackValue),\n };\n\n const isSegmented = variant === \"segmented\";\n const isUnderline = variant === \"underline\";\n const isPill = variant === \"pill\";\n\n return (\n <TabsPrimitive.Root\n {...rootProps}\n className={cn(\"relative min-w-0 font-medium\", className)}\n onValueChange={(nextValue) => {\n const stringValue = String(nextValue);\n onValueChange?.(stringValue);\n }}\n >\n {/* Background element for segmented variant only */}\n {(isSegmented || isPill) && (\n <div\n className={cn(\n \"absolute inset-x-0 top-1/2 -z-10 h-8.5 -translate-y-1/2 rounded-lg\",\n isSegmented && \"bg-sf-tint\",\n isPill && \"hidden\"\n )}\n />\n )}\n <TabsPrimitive.List\n activateOnFocus={activateOnFocus}\n className={cn(\n \"scrollbar-hide relative flex min-w-0 shrink items-stretch\",\n isSegmented && \"h-8.5 rounded-lg bg-sf-tint px-px\",\n isUnderline && \"h-7 gap-4 border-b border-sf-line pb-2\",\n isPill && \"h-9 gap-1\",\n listClassName\n )}\n >\n {items.map((tab) => (\n <TabsPrimitive.Tab\n key={tab.value}\n value={tab.value}\n className={cn(\n \"relative z-10 flex cursor-pointer items-center whitespace-nowrap hover:border-sf-tint focus-visible:rounded-none focus-visible:ring-sf-ring focus-visible:outline-offset-3\",\n isSegmented &&\n \"my-px rounded-lg bg-transparent px-2.5 text-base text-sf-strong aria-selected:text-sf-default\",\n isUnderline &&\n \"mb-2 text-base text-sf-strong hover:text-sf-subtle aria-selected:font-medium aria-selected:text-sf-default\",\n isPill &&\n \"rounded-full px-3 text-sm text-sf-strong transition-colors hover:bg-sf-tint/50 hover:text-sf-subtle aria-selected:bg-sf-tint aria-selected:font-medium aria-selected:text-sf-default\",\n tab.className\n )}\n >\n {tab.label}\n </TabsPrimitive.Tab>\n ))}\n <TabsPrimitive.Indicator\n className={cn(\n \"absolute z-0 transition-[left,width,transform] duration-200 ease-out\",\n \"data-[rendered=false]:scale-90 data-[rendered=false]:opacity-0\",\n \"left-(--active-tab-left) w-(--active-tab-width)\",\n isSegmented &&\n \"top-(--active-tab-top) h-(--active-tab-height) rounded-lg bg-sf-overlay shadow-sm ring ring-sf-fill-hover\",\n isUnderline && \"bottom-0 h-0.5 bg-sf-brand\",\n isPill && \"hidden\",\n indicatorClassName\n )}\n />\n </TabsPrimitive.List>\n </TabsPrimitive.Root>\n );\n}\n"],"mappings":";;;;;AAUA,IAAa,2BAA2B,EACtC,SAAS,aACV;;;;;;;;;;;;;;;;AAsGD,SAAgB,OAAK,EACnB,MACA,OACA,eACA,eACA,iBACA,WACA,eACA,oBACA,UAAU,yBAAyB,WACvB;CACZ,MAAM,QAAoB,QAAQ,EAAE;AAEpC,KAAI,MAAM,WAAW,EACnB,QAAO;CAGT,MAAM,gBAAgB,MAAM,IAAI;CAChC,MAAM,eAAe,UAAU,KAAA;CAC/B,MAAM,YAAY;EAChB,OAAO,eAAe,QAAQ,KAAA;EAC9B,cAAc,eAAe,KAAA,IAAa,iBAAiB;EAC5D;CAED,MAAM,cAAc,YAAY;CAChC,MAAM,cAAc,YAAY;CAChC,MAAM,SAAS,YAAY;AAE3B,QACE,qBAAC,KAAc,MAAf;EACE,GAAI;EACJ,WAAW,GAAG,gCAAgC,UAAU;EACxD,gBAAgB,cAAc;AAE5B,mBADoB,OAAO,UAAU,CACT;;YALhC,EASI,eAAe,WACf,oBAAC,OAAD,EACE,WAAW,GACT,sEACA,eAAe,cACf,UAAU,SACX,EACD,CAAA,EAEJ,qBAAC,KAAc,MAAf;GACmB;GACjB,WAAW,GACT,6DACA,eAAe,qCACf,eAAe,0CACf,UAAU,aACV,cACD;aARH,CAUG,MAAM,KAAK,QACV,oBAAC,KAAc,KAAf;IAEE,OAAO,IAAI;IACX,WAAW,GACT,8KACA,eACE,iGACF,eACE,8GACF,UACE,wLACF,IAAI,UACL;cAEA,IAAI;IACa,EAdb,IAAI,MAcS,CACpB,EACF,oBAAC,KAAc,WAAf,EACE,WAAW,GACT,wEACA,kEACA,mDACA,eACE,6GACF,eAAe,8BACf,UAAU,UACV,mBACD,EACD,CAAA,CACiB;KACF"}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { t as cn } from "./cn-YROP2_ox.js";
3
+ import { t as MeasuredText } from "./measured-text-BI3dTJmH.js";
3
4
  import { forwardRef, useMemo } from "react";
4
5
  import { jsx } from "react/jsx-runtime";
5
6
  //#region src/components/text/text.tsx
@@ -62,18 +63,25 @@ var SF_TEXT_VARIANTS = {
62
63
  }
63
64
  }
64
65
  };
66
+ function getDefaultWrap(variant) {
67
+ if (variant === "heading1" || variant === "heading2" || variant === "heading3") return "balance";
68
+ return "natural";
69
+ }
65
70
  /**
66
71
  * Typography component for rendering text with consistent styling.
67
72
  * Automatically selects the appropriate HTML element based on variant
68
73
  * (`h1`/`h2`/`h3` for headings, `p` for body, `span` for mono).
69
74
  *
75
+ * Now includes pretext-driven layout for precise wrapping and spacing.
76
+ *
70
77
  * @example
71
78
  * ```tsx
72
79
  * <Text variant="heading1">Dashboard</Text>
73
80
  * <Text>Default body text</Text>
81
+ * <Text wrap="shrink">Compact bubble</Text>
74
82
  * ```
75
83
  */
76
- function _Text({ variant = "body", bold = false, size = "base", children, DANGEROUS_className, DANGEROUS_style, as, ...props }, ref) {
84
+ function _Text({ variant = "body", bold = false, size = "base", children, DANGEROUS_className, DANGEROUS_style, as, wrap, reserveLines, ...props }, ref) {
77
85
  const isCopy = [
78
86
  "body",
79
87
  "secondary",
@@ -81,23 +89,37 @@ function _Text({ variant = "body", bold = false, size = "base", children, DANGER
81
89
  "error"
82
90
  ].includes(variant);
83
91
  const isMono = ["mono", "mono-secondary"].includes(variant);
84
- return /* @__PURE__ */ jsx(useMemo(() => {
92
+ const Component = useMemo(() => {
85
93
  if (as) return as;
86
94
  if (variant === "heading1") return "h1";
87
95
  if (variant === "heading2") return "h2";
88
96
  if (variant === "heading3") return "h3";
89
97
  if (["mono", "mono-secondary"].includes(variant)) return "span";
90
98
  return "p";
91
- }, [variant, as]), {
99
+ }, [variant, as]);
100
+ const effectiveWrap = wrap ?? getDefaultWrap(variant);
101
+ const className = cn("text-sf-default", SF_TEXT_VARIANTS.variant[variant].classes, isCopy ? SF_TEXT_VARIANTS.size[size].classes : "", isCopy && bold ? "font-medium" : "", isMono && (size === "lg" ? SF_TEXT_VARIANTS.size.base.classes : SF_TEXT_VARIANTS.size.sm.classes), DANGEROUS_className);
102
+ if (effectiveWrap !== "natural" && effectiveWrap !== false) return /* @__PURE__ */ jsx(MeasuredText, {
103
+ ref,
104
+ as: Component,
105
+ wrap: effectiveWrap,
106
+ reserveLines,
107
+ className,
108
+ style: DANGEROUS_style,
109
+ ...props,
110
+ children
111
+ });
112
+ return /* @__PURE__ */ jsx(Component, {
92
113
  ref,
93
- className: cn("text-sf-default", SF_TEXT_VARIANTS.variant[variant].classes, isCopy ? SF_TEXT_VARIANTS.size[size].classes : "", isCopy && bold ? "font-medium" : "", isMono && (size === "lg" ? SF_TEXT_VARIANTS.size.base.classes : SF_TEXT_VARIANTS.size.sm.classes), DANGEROUS_className),
114
+ className,
94
115
  style: DANGEROUS_style,
95
116
  ...props,
96
117
  children
97
118
  });
98
119
  }
99
120
  var Text = forwardRef(_Text);
121
+ Text.displayName = "Text";
100
122
  //#endregion
101
123
  export { Text as t };
102
124
 
103
- //# sourceMappingURL=text-KJmGkwnf.js.map
125
+ //# sourceMappingURL=text-Cqryz7rk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-Cqryz7rk.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\";\nimport { MeasuredText, type MeasuredTextMode } from \"../../utils/measured-text\";\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 * 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.\n * - `false` — Same as `\"natural\"`, explicit opt-out.\n * @default \"balance\" for headings, \"natural\" for body/mono/secondary.\n */\n wrap?: MeasuredTextMode | false;\n /**\n * For `wrap=\"reserve\"`: reserve this many lines of height.\n * If omitted, measures current content to determine line count.\n */\n reserveLines?: number;\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 * <Text wrap=\"shrink\">Hug content width</Text>\n * <Text wrap=\"reserve\" reserveLines={3}>Streaming content...</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 * 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.\n * @default \"balance\" for headings, \"natural\" for body/mono.\n */\n wrap?: MeasuredTextMode | false;\n /**\n * For `wrap=\"reserve\"`: reserve this many lines of height.\n * If omitted, measures current content to determine line count.\n */\n reserveLines?: number;\n}\n\nfunction getDefaultWrap(variant: TextVariant): MeasuredTextMode | false {\n if (variant === \"heading1\" || variant === \"heading2\" || variant === \"heading3\") {\n return \"balance\";\n }\n return \"natural\";\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 * Now includes pretext-driven layout for precise wrapping and spacing.\n *\n * @example\n * ```tsx\n * <Text variant=\"heading1\">Dashboard</Text>\n * <Text>Default body text</Text>\n * <Text wrap=\"shrink\">Compact bubble</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 wrap,\n reserveLines,\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 const effectiveWrap = wrap ?? getDefaultWrap(variant);\n const 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\n // Use MeasuredText for non-natural modes, or when reserveLines is set\n if (effectiveWrap !== \"natural\" && effectiveWrap !== false) {\n return (\n <MeasuredText\n ref={ref as React.RefObject<HTMLElement>}\n as={Component}\n wrap={effectiveWrap}\n reserveLines={reserveLines}\n className={className}\n style={DANGEROUS_style}\n {...props}\n >\n {children}\n </MeasuredText>\n );\n }\n\n // Natural mode: render directly without measurement overhead\n return (\n <Component\n ref={ref}\n className={className}\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 & { displayName?: string };\n\n// Cast needed because of the complex forwardRef type signature\n(Text as { displayName?: string }).displayName = \"Text\";\n"],"mappings":";;;;;;;AAcA,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;AAkLD,SAAS,eAAe,SAAgD;AACtE,KAAI,YAAY,cAAc,YAAY,cAAc,YAAY,WAClE,QAAO;AAET,QAAO;;;;;;;;;;;;;;;;AAiBT,SAAS,MACP,EACE,UAAU,QACV,OAAO,OACP,OAAO,QACP,UACA,qBACA,iBACA,IACA,MACA,cACA,GAAG,SAEL,KACA;CACA,MAAM,SAAS;EAAC;EAAQ;EAAa;EAAW;EAAQ,CAAC,SAAS,QAAQ;CAC1E,MAAM,SAAS,CAAC,QAAQ,iBAAiB,CAAC,SAAS,QAAQ;CAE3D,MAAM,YAAY,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;CAEjB,MAAM,gBAAgB,QAAQ,eAAe,QAAQ;CACrD,MAAM,YAAY,GAChB,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;AAGD,KAAI,kBAAkB,aAAa,kBAAkB,MACnD,QACE,oBAAC,cAAD;EACO;EACL,IAAI;EACJ,MAAM;EACQ;EACH;EACX,OAAO;EACP,GAAI;EAEH;EACY,CAAA;AAKnB,QACE,oBAAC,WAAD;EACO;EACM;EACX,OAAO;EACP,GAAI;EAEH;EACS,CAAA;;AAIhB,IAAa,OAAO,WAAW,MAAM;AAOrC,KAAmC,cAAc"}
@@ -76,4 +76,4 @@ TextRoll.displayName = "TextRoll";
76
76
  //#endregion
77
77
  export { TextRoll as t };
78
78
 
79
- //# sourceMappingURL=text-roll-BZ3I1umc.js.map
79
+ //# sourceMappingURL=text-roll-Ch52hcQj.js.map
@@ -1 +1 @@
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
+ {"version":3,"file":"text-roll-Ch52hcQj.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,7 +1,7 @@
1
1
  "use client";
2
2
  import { t as cn } from "./cn-YROP2_ox.js";
3
- import { t as Tooltip } from "./tooltip-Cb7QW-7H.js";
4
- import { t as Button } from "./button-De0267YU.js";
3
+ import { t as Tooltip } from "./tooltip-g9lFsvcT.js";
4
+ import { t as Button } from "./button-CO6-qPax.js";
5
5
  import { useEffect, useState } from "react";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  import { MoonIcon, SunIcon } from "@phosphor-icons/react";
@@ -126,4 +126,4 @@ function ThemeToggle({ className, mode: controlledMode, onModeChange, cycle = [
126
126
  //#endregion
127
127
  export { getStoredThemeMode as i, SF_THEME_TOGGLE_VARIANTS as n, ThemeToggle as r, SF_THEME_TOGGLE_DEFAULT_VARIANTS as t };
128
128
 
129
- //# sourceMappingURL=theme-toggle-Bhu681D7.js.map
129
+ //# sourceMappingURL=theme-toggle-LDfIKEqx.js.map
@@ -1 +1 @@
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
+ {"version":3,"file":"theme-toggle-LDfIKEqx.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,6 +1,6 @@
1
1
  "use client";
2
2
  import { t as cn } from "./cn-YROP2_ox.js";
3
- import { t as Button } from "./button-De0267YU.js";
3
+ import { t as Button } from "./button-CO6-qPax.js";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { Toast, Toast as Toast$1 } from "@base-ui/react/toast";
6
6
  import { WarningIcon, WarningOctagonIcon } from "@phosphor-icons/react/dist/ssr";
@@ -158,4 +158,4 @@ function XIcon(props) {
158
158
  //#endregion
159
159
  export { useSFToastManager as a, createSFToastManager as i, ToastProvider as n, Toasty as r, Toast$1 as t };
160
160
 
161
- //# sourceMappingURL=toast-Nw28a5Cx.js.map
161
+ //# sourceMappingURL=toast-CaFQNYng.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toast-Nw28a5Cx.js","names":[],"sources":["../src/components/toast/toast.tsx"],"sourcesContent":["import {\n Toast,\n ToastManagerAddOptions,\n ToastObject,\n} from \"@base-ui/react/toast\";\nimport {\n WarningIcon,\n WarningOctagonIcon,\n} from \"@phosphor-icons/react/dist/ssr\";\nimport type React from \"react\";\n\nimport { Button, ButtonProps } from \"../../components/button\";\nimport { cn } from \"../../utils/cn\";\n\n/**\n * Toast styling configuration for Figma plugin consumption.\n * Toast has no user-facing variants but documents the styling structure.\n */\nexport const SF_TOAST_VARIANTS = {\n root: {\n classes:\n \"rounded-lg border border-sf-fill bg-sf-control p-4 shadow-lg text-sf-default\",\n description: \"Toast container with background, border, and shadow\",\n },\n title: {\n classes: \"text-[0.975rem] leading-5 font-medium text-sf-default\",\n description: \"Toast title with primary text color\",\n },\n description: {\n classes: \"text-[0.925rem] leading-5 text-sf-subtle\",\n description: \"Toast description with muted text color\",\n },\n close: {\n classes:\n \"absolute top-2 right-2 flex h-5 w-5 items-center justify-center rounded border-none bg-transparent text-sf-subtle hover:bg-sf-fill-hover hover:text-sf-strong\",\n description: \"Close button with X icon\",\n },\n variant: {\n default: {\n classes: \"border-sf-fill bg-sf-control\",\n description: \"Default toast style\",\n },\n error: {\n classes:\n \"border-sf-fill bg-sf-control [&_[data-toast-icon]]:text-[light-dark(var(--color-red-600),var(--color-red-400))] [&_[data-toast-title]]:text-[light-dark(var(--color-red-600),var(--color-red-400))]\",\n description: \"Error toast for critical issues\",\n icon: WarningOctagonIcon,\n },\n warning: {\n classes:\n \"border-sf-fill bg-sf-control [&_[data-toast-icon]]:text-[light-dark(var(--color-amber-700),var(--color-amber-500))] [&_[data-toast-title]]:text-[light-dark(var(--color-amber-700),var(--color-amber-500))]\",\n description: \"Warning toast for cautionary messages\",\n icon: WarningIcon,\n },\n },\n} as const;\n\nexport const SF_TOAST_DEFAULT_VARIANTS = {\n variant: \"default\",\n} as const;\n\n/**\n * Toast styling configuration for Figma plugin consumption.\n * Provides structured metadata for generating Toast components in Figma.\n */\nexport const SF_TOAST_STYLING = {\n container: {\n width: 300,\n padding: 16,\n borderRadius: 8,\n background: \"color-secondary\",\n border: \"color-color\",\n shadow: \"shadow-lg\",\n gap: 4,\n },\n title: {\n fontSize: 16,\n fontWeight: 500,\n color: \"text-color-surface\",\n },\n description: {\n fontSize: 15,\n fontWeight: 400,\n color: \"text-color-muted\",\n },\n closeButton: {\n size: 20,\n iconSize: 16,\n iconName: \"ph-x\",\n iconColor: \"text-color-muted\",\n hoverBackground: \"color-color-2\",\n hoverColor: \"text-color-label\",\n borderRadius: 4,\n },\n} as const;\n\n// Derived types from SF_TOAST_VARIANTS\nexport type SFToastVariant = keyof typeof SF_TOAST_VARIANTS.variant;\n\nexport interface SFToastVariantsProps {\n variant?: SFToastVariant;\n}\n\nexport function toastVariants({\n variant = SF_TOAST_DEFAULT_VARIANTS.variant,\n}: SFToastVariantsProps = {}) {\n return cn(\n // Base styles for toast root\n \"rounded-xl border bg-clip-padding p-4 shadow-lg\",\n // Apply variant styles from SF_TOAST_VARIANTS\n SF_TOAST_VARIANTS.variant[variant].classes\n );\n}\n\n/**\n * Toasty component props.\n *\n * Wrap your app with `<Toasty>` to enable toast notifications.\n * Use `Toast.useToastManager().notify(…)` to create toasts.\n *\n * @example\n * ```tsx\n * // 1. Wrap your app\n * <Toasty>\n * <App />\n * </Toasty>\n *\n * // 2. Show a toast from any child component\n * const toasts = Toast.useToastManager();\n * toasts.notify({ title: \"Saved\", description: \"Changes saved successfully.\" });\n * ```\n */\nexport interface ToastyProps extends SFToastVariantsProps {\n /** Application content. Toasts render via a portal above this. */\n children: React.ReactNode;\n}\n\ntype SFToastOptionsBase = {\n variant?: SFToastVariant;\n content?: React.ReactNode;\n actions?: Array<ButtonProps>;\n};\n\nexport type SFToastOptions<Data extends object> = ToastObject<Data> &\n SFToastOptionsBase;\n\nexport type SFToastManagerAddOptions<Data extends object> =\n ToastManagerAddOptions<Data> & SFToastOptionsBase;\n\nfunction wrapManagerMethods<\n T extends { add: Function; update: Function; promise: Function },\n>(manager: T) {\n return {\n ...manager,\n\n add: (options: SFToastManagerAddOptions<any>) => {\n return manager.add({\n ...options,\n });\n },\n\n update: (id: string, options: Partial<SFToastManagerAddOptions<any>>) => {\n return manager.update(id, {\n ...options,\n });\n },\n\n promise: <T,>(\n promise: Promise<T>,\n options: {\n loading: SFToastManagerAddOptions<any>;\n success:\n | SFToastManagerAddOptions<any>\n | ((data: T) => SFToastManagerAddOptions<any>);\n error:\n | SFToastManagerAddOptions<any>\n | ((error: Error) => SFToastManagerAddOptions<any>);\n }\n ) => {\n return manager.promise(promise, {\n loading: { ...options.loading },\n success:\n typeof options.success === \"function\"\n ? (data: T) => ({\n ...(\n options.success as (data: T) => SFToastManagerAddOptions<any>\n )(data),\n })\n : { ...options.success },\n error:\n typeof options.error === \"function\"\n ? (error: Error) => ({\n ...(\n options.error as (\n error: Error\n ) => SFToastManagerAddOptions<any>\n )(error),\n })\n : { ...options.error },\n });\n },\n };\n}\n\nexport const useSFToastManager = () => {\n const manager = Toast.useToastManager();\n return {\n ...wrapManagerMethods(manager),\n toasts: manager.toasts as Array<SFToastOptions<any>>,\n };\n};\n\nexport const createSFToastManager = () => {\n return wrapManagerMethods(Toast.createToastManager());\n};\n\n/**\n * Toasty — toast notification provider and viewport.\n *\n * Renders a `Toast.Provider` with a fixed-position viewport in the bottom-right corner.\n * Toasts stack with smooth enter/exit animations, swipe-to-dismiss, and expand-on-hover.\n *\n * Built on `@base-ui/react/toast`.\n *\n * @example\n * ```tsx\n * <Toasty>\n * <App />\n * </Toasty>\n * ```\n */\nexport function Toasty({ children }: ToastyProps) {\n return (\n <Toast.Provider>\n {children}\n <Toast.Portal>\n <Toast.Viewport className=\"fixed top-auto right-4 bottom-4 z-10 mx-auto flex w-[calc(100%-2rem)] sm:right-8 sm:bottom-8 sm:w-[340px]\">\n <ToastList />\n </Toast.Viewport>\n </Toast.Portal>\n </Toast.Provider>\n );\n}\n\n/** Alias for Toasty — provided for discoverability when migrating from other libraries */\nexport const ToastProvider = Toasty;\n\nfunction ToastList() {\n const { toasts } = useSFToastManager();\n return toasts.map((toast) => (\n <Toast.Root\n key={toast.id}\n toast={toast}\n className={cn(\n \"absolute right-0 bottom-0 left-auto z-[calc(1000-var(--toast-index))] mr-0 h-[var(--height)] w-full origin-bottom select-none\",\n toastVariants({ variant: toast.variant }),\n \"[--gap:0.75rem] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))]\",\n \"[transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))] [transition:transform_0.5s_cubic-bezier(0.22,1,0.36,1),opacity_0.5s,height_0.15s]\",\n \"after:absolute after:top-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']\",\n \"data-[ending-style]:opacity-0 data-[expanded]:h-[var(--toast-height)] data-[expanded]:[transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--offset-y)))] data-[limited]:opacity-0 data-[starting-style]:[transform:translateY(150%)]\",\n \"data-[ending-style]:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))] data-[expanded]:data-[ending-style]:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n \"data-[ending-style]:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))] data-[expanded]:data-[ending-style]:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n \"data-[ending-style]:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))] data-[expanded]:data-[ending-style]:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n \"data-[ending-style]:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))] data-[expanded]:data-[ending-style]:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n \"[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(150%)]\"\n )}\n >\n <div className=\"absolute inset-0 rounded-[11px] bg-sf-control/90\"></div>\n <Toast.Content className=\"isolate flex flex-col gap-1 transition-opacity [transition-duration:250ms] data-[behind]:pointer-events-none data-[behind]:opacity-0 data-[expanded]:pointer-events-auto data-[expanded]:opacity-100\">\n {toast.content ?? (\n <>\n <div className=\"flex items-start gap-2\">\n <ToastIcon variant={toast.variant} />\n <div className=\"flex flex-col gap-1 overflow-hidden\">\n <Toast.Title\n data-toast-title\n className=\"text-[0.975rem] leading-5 font-medium text-sf-default\"\n />\n <Toast.Description className=\"text-[0.925rem] leading-5 text-sf-subtle\" />\n\n {!!toast.actions && (\n <div className=\"mt-2 flex min-w-0 flex-nowrap gap-2 overflow-x-auto p-px\">\n {toast.actions.map((actionProps, idx) => (\n <Button key={idx} {...actionProps} />\n ))}\n </div>\n )}\n </div>\n </div>\n </>\n )}\n <Toast.Close\n className=\"absolute top-2 right-2 flex h-4 w-4 items-center justify-center rounded border-none bg-transparent text-current/50 hover:bg-sf-contrast/10 hover:text-current\"\n aria-label=\"Close\"\n >\n <XIcon className=\"h-3 w-3\" />\n </Toast.Close>\n </Toast.Content>\n </Toast.Root>\n ));\n}\n\nfunction ToastIcon({ variant }: { variant?: SFToastVariant }) {\n if (!variant || variant === \"default\") return null;\n const variantConfig = SF_TOAST_VARIANTS.variant[variant];\n if (!(\"icon\" in variantConfig)) return null;\n const Icon = variantConfig.icon;\n return (\n <Icon data-toast-icon className=\"mt-0.5 h-4 w-4 shrink-0\" weight=\"fill\" />\n );\n}\n\nfunction XIcon(props: React.ComponentProps<\"svg\">) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"toast-CaFQNYng.js","names":[],"sources":["../src/components/toast/toast.tsx"],"sourcesContent":["import {\n Toast,\n ToastManagerAddOptions,\n ToastObject,\n} from \"@base-ui/react/toast\";\nimport {\n WarningIcon,\n WarningOctagonIcon,\n} from \"@phosphor-icons/react/dist/ssr\";\nimport type React from \"react\";\n\nimport { Button, ButtonProps } from \"../../components/button\";\nimport { cn } from \"../../utils/cn\";\n\n/**\n * Toast styling configuration for Figma plugin consumption.\n * Toast has no user-facing variants but documents the styling structure.\n */\nexport const SF_TOAST_VARIANTS = {\n root: {\n classes:\n \"rounded-lg border border-sf-fill bg-sf-control p-4 shadow-lg text-sf-default\",\n description: \"Toast container with background, border, and shadow\",\n },\n title: {\n classes: \"text-[0.975rem] leading-5 font-medium text-sf-default\",\n description: \"Toast title with primary text color\",\n },\n description: {\n classes: \"text-[0.925rem] leading-5 text-sf-subtle\",\n description: \"Toast description with muted text color\",\n },\n close: {\n classes:\n \"absolute top-2 right-2 flex h-5 w-5 items-center justify-center rounded border-none bg-transparent text-sf-subtle hover:bg-sf-fill-hover hover:text-sf-strong\",\n description: \"Close button with X icon\",\n },\n variant: {\n default: {\n classes: \"border-sf-fill bg-sf-control\",\n description: \"Default toast style\",\n },\n error: {\n classes:\n \"border-sf-fill bg-sf-control [&_[data-toast-icon]]:text-[light-dark(var(--color-red-600),var(--color-red-400))] [&_[data-toast-title]]:text-[light-dark(var(--color-red-600),var(--color-red-400))]\",\n description: \"Error toast for critical issues\",\n icon: WarningOctagonIcon,\n },\n warning: {\n classes:\n \"border-sf-fill bg-sf-control [&_[data-toast-icon]]:text-[light-dark(var(--color-amber-700),var(--color-amber-500))] [&_[data-toast-title]]:text-[light-dark(var(--color-amber-700),var(--color-amber-500))]\",\n description: \"Warning toast for cautionary messages\",\n icon: WarningIcon,\n },\n },\n} as const;\n\nexport const SF_TOAST_DEFAULT_VARIANTS = {\n variant: \"default\",\n} as const;\n\n/**\n * Toast styling configuration for Figma plugin consumption.\n * Provides structured metadata for generating Toast components in Figma.\n */\nexport const SF_TOAST_STYLING = {\n container: {\n width: 300,\n padding: 16,\n borderRadius: 8,\n background: \"color-secondary\",\n border: \"color-color\",\n shadow: \"shadow-lg\",\n gap: 4,\n },\n title: {\n fontSize: 16,\n fontWeight: 500,\n color: \"text-color-surface\",\n },\n description: {\n fontSize: 15,\n fontWeight: 400,\n color: \"text-color-muted\",\n },\n closeButton: {\n size: 20,\n iconSize: 16,\n iconName: \"ph-x\",\n iconColor: \"text-color-muted\",\n hoverBackground: \"color-color-2\",\n hoverColor: \"text-color-label\",\n borderRadius: 4,\n },\n} as const;\n\n// Derived types from SF_TOAST_VARIANTS\nexport type SFToastVariant = keyof typeof SF_TOAST_VARIANTS.variant;\n\nexport interface SFToastVariantsProps {\n variant?: SFToastVariant;\n}\n\nexport function toastVariants({\n variant = SF_TOAST_DEFAULT_VARIANTS.variant,\n}: SFToastVariantsProps = {}) {\n return cn(\n // Base styles for toast root\n \"rounded-xl border bg-clip-padding p-4 shadow-lg\",\n // Apply variant styles from SF_TOAST_VARIANTS\n SF_TOAST_VARIANTS.variant[variant].classes\n );\n}\n\n/**\n * Toasty component props.\n *\n * Wrap your app with `<Toasty>` to enable toast notifications.\n * Use `Toast.useToastManager().notify(…)` to create toasts.\n *\n * @example\n * ```tsx\n * // 1. Wrap your app\n * <Toasty>\n * <App />\n * </Toasty>\n *\n * // 2. Show a toast from any child component\n * const toasts = Toast.useToastManager();\n * toasts.notify({ title: \"Saved\", description: \"Changes saved successfully.\" });\n * ```\n */\nexport interface ToastyProps extends SFToastVariantsProps {\n /** Application content. Toasts render via a portal above this. */\n children: React.ReactNode;\n}\n\ntype SFToastOptionsBase = {\n variant?: SFToastVariant;\n content?: React.ReactNode;\n actions?: Array<ButtonProps>;\n};\n\nexport type SFToastOptions<Data extends object> = ToastObject<Data> &\n SFToastOptionsBase;\n\nexport type SFToastManagerAddOptions<Data extends object> =\n ToastManagerAddOptions<Data> & SFToastOptionsBase;\n\nfunction wrapManagerMethods<\n T extends { add: Function; update: Function; promise: Function },\n>(manager: T) {\n return {\n ...manager,\n\n add: (options: SFToastManagerAddOptions<any>) => {\n return manager.add({\n ...options,\n });\n },\n\n update: (id: string, options: Partial<SFToastManagerAddOptions<any>>) => {\n return manager.update(id, {\n ...options,\n });\n },\n\n promise: <T,>(\n promise: Promise<T>,\n options: {\n loading: SFToastManagerAddOptions<any>;\n success:\n | SFToastManagerAddOptions<any>\n | ((data: T) => SFToastManagerAddOptions<any>);\n error:\n | SFToastManagerAddOptions<any>\n | ((error: Error) => SFToastManagerAddOptions<any>);\n }\n ) => {\n return manager.promise(promise, {\n loading: { ...options.loading },\n success:\n typeof options.success === \"function\"\n ? (data: T) => ({\n ...(\n options.success as (data: T) => SFToastManagerAddOptions<any>\n )(data),\n })\n : { ...options.success },\n error:\n typeof options.error === \"function\"\n ? (error: Error) => ({\n ...(\n options.error as (\n error: Error\n ) => SFToastManagerAddOptions<any>\n )(error),\n })\n : { ...options.error },\n });\n },\n };\n}\n\nexport const useSFToastManager = () => {\n const manager = Toast.useToastManager();\n return {\n ...wrapManagerMethods(manager),\n toasts: manager.toasts as Array<SFToastOptions<any>>,\n };\n};\n\nexport const createSFToastManager = () => {\n return wrapManagerMethods(Toast.createToastManager());\n};\n\n/**\n * Toasty — toast notification provider and viewport.\n *\n * Renders a `Toast.Provider` with a fixed-position viewport in the bottom-right corner.\n * Toasts stack with smooth enter/exit animations, swipe-to-dismiss, and expand-on-hover.\n *\n * Built on `@base-ui/react/toast`.\n *\n * @example\n * ```tsx\n * <Toasty>\n * <App />\n * </Toasty>\n * ```\n */\nexport function Toasty({ children }: ToastyProps) {\n return (\n <Toast.Provider>\n {children}\n <Toast.Portal>\n <Toast.Viewport className=\"fixed top-auto right-4 bottom-4 z-10 mx-auto flex w-[calc(100%-2rem)] sm:right-8 sm:bottom-8 sm:w-[340px]\">\n <ToastList />\n </Toast.Viewport>\n </Toast.Portal>\n </Toast.Provider>\n );\n}\n\n/** Alias for Toasty — provided for discoverability when migrating from other libraries */\nexport const ToastProvider = Toasty;\n\nfunction ToastList() {\n const { toasts } = useSFToastManager();\n return toasts.map((toast) => (\n <Toast.Root\n key={toast.id}\n toast={toast}\n className={cn(\n \"absolute right-0 bottom-0 left-auto z-[calc(1000-var(--toast-index))] mr-0 h-[var(--height)] w-full origin-bottom select-none\",\n toastVariants({ variant: toast.variant }),\n \"[--gap:0.75rem] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))]\",\n \"[transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))] [transition:transform_0.5s_cubic-bezier(0.22,1,0.36,1),opacity_0.5s,height_0.15s]\",\n \"after:absolute after:top-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']\",\n \"data-[ending-style]:opacity-0 data-[expanded]:h-[var(--toast-height)] data-[expanded]:[transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--offset-y)))] data-[limited]:opacity-0 data-[starting-style]:[transform:translateY(150%)]\",\n \"data-[ending-style]:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))] data-[expanded]:data-[ending-style]:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]\",\n \"data-[ending-style]:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))] data-[expanded]:data-[ending-style]:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]\",\n \"data-[ending-style]:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))] data-[expanded]:data-[ending-style]:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]\",\n \"data-[ending-style]:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))] data-[expanded]:data-[ending-style]:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]\",\n \"[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(150%)]\"\n )}\n >\n <div className=\"absolute inset-0 rounded-[11px] bg-sf-control/90\"></div>\n <Toast.Content className=\"isolate flex flex-col gap-1 transition-opacity [transition-duration:250ms] data-[behind]:pointer-events-none data-[behind]:opacity-0 data-[expanded]:pointer-events-auto data-[expanded]:opacity-100\">\n {toast.content ?? (\n <>\n <div className=\"flex items-start gap-2\">\n <ToastIcon variant={toast.variant} />\n <div className=\"flex flex-col gap-1 overflow-hidden\">\n <Toast.Title\n data-toast-title\n className=\"text-[0.975rem] leading-5 font-medium text-sf-default\"\n />\n <Toast.Description className=\"text-[0.925rem] leading-5 text-sf-subtle\" />\n\n {!!toast.actions && (\n <div className=\"mt-2 flex min-w-0 flex-nowrap gap-2 overflow-x-auto p-px\">\n {toast.actions.map((actionProps, idx) => (\n <Button key={idx} {...actionProps} />\n ))}\n </div>\n )}\n </div>\n </div>\n </>\n )}\n <Toast.Close\n className=\"absolute top-2 right-2 flex h-4 w-4 items-center justify-center rounded border-none bg-transparent text-current/50 hover:bg-sf-contrast/10 hover:text-current\"\n aria-label=\"Close\"\n >\n <XIcon className=\"h-3 w-3\" />\n </Toast.Close>\n </Toast.Content>\n </Toast.Root>\n ));\n}\n\nfunction ToastIcon({ variant }: { variant?: SFToastVariant }) {\n if (!variant || variant === \"default\") return null;\n const variantConfig = SF_TOAST_VARIANTS.variant[variant];\n if (!(\"icon\" in variantConfig)) return null;\n const Icon = variantConfig.icon;\n return (\n <Icon data-toast-icon className=\"mt-0.5 h-4 w-4 shrink-0\" weight=\"fill\" />\n );\n}\n\nfunction XIcon(props: React.ComponentProps<\"svg\">) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n {...props}\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { t as cn } from "./cn-YROP2_ox.js";
3
+ import { t as Text } from "./text-Cqryz7rk.js";
3
4
  import { jsx, jsxs } from "react/jsx-runtime";
4
5
  import { Tooltip } from "@base-ui/react/tooltip";
5
6
  //#region src/components/tooltip/tooltip.tsx
@@ -30,7 +31,12 @@ function Tooltip$1({ content, children, align, side, className, ...props }) {
30
31
  children: [/* @__PURE__ */ jsx(Tooltip.Arrow, {
31
32
  className: cn("flex", "data-[side=bottom]:top-[-8px]", "data-[side=left]:right-[-13px] data-[side=left]:rotate-90", "data-[side=right]:left-[-13px] data-[side=right]:-rotate-90", "data-[side=top]:bottom-[-8px] data-[side=top]:rotate-180"),
32
33
  children: /* @__PURE__ */ jsx(ArrowSvg, {})
33
- }), content]
34
+ }), typeof content === "string" ? /* @__PURE__ */ jsx(Text, {
35
+ size: "sm",
36
+ wrap: "shrink",
37
+ as: "span",
38
+ children: content
39
+ }) : content]
34
40
  })
35
41
  }) })]
36
42
  });
@@ -76,4 +82,4 @@ function ArrowSvg(props) {
76
82
  //#endregion
77
83
  export { TooltipProvider as n, Tooltip$1 as t };
78
84
 
79
- //# sourceMappingURL=tooltip-Cb7QW-7H.js.map
85
+ //# sourceMappingURL=tooltip-g9lFsvcT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tooltip-g9lFsvcT.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\";\nimport { Text } from \"../text\";\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 {typeof content === \"string\" ? (\n <Text size=\"sm\" wrap=\"shrink\" as=\"span\">\n {content}\n </Text>\n ) : (\n content\n )}\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":";;;;;;AA+DA,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,OAAO,YAAY,WAClB,oBAAC,MAAD;KAAM,MAAK;KAAK,MAAK;KAAS,IAAG;eAC9B;KACI,CAAA,GAEP,QAEgB;;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"}
@@ -926,4 +926,4 @@ function useAgentHarness({ adapter }) {
926
926
  //#endregion
927
927
  export { useAgentHarness as a, fromMastraHarness as i, SF_USE_AGENT_HARNESS_VARIANTS as n, createAgentHarnessState as r, SF_USE_AGENT_HARNESS_DEFAULT_VARIANTS as t };
928
928
 
929
- //# sourceMappingURL=use-agent-harness-BMyF8pTq.js.map
929
+ //# sourceMappingURL=use-agent-harness-BTcNJdw4.js.map