@keboola/design 15.0.0 → 16.0.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 (358) hide show
  1. package/AGENTS.md +6 -5
  2. package/CHANGELOG.md +94 -0
  3. package/COMPONENT-API.md +62 -61
  4. package/dist/{AIKit-CaAW4GLx.js → AIKit-Cf5plya2.js} +381 -224
  5. package/dist/AIKit-Cf5plya2.js.map +1 -0
  6. package/dist/{Alert-Chz6KZ7e.js → Alert-DziS8n1H.js} +12 -19
  7. package/dist/{Alert-Chz6KZ7e.js.map → Alert-DziS8n1H.js.map} +1 -1
  8. package/dist/{AlertModal-D4AtpvLS.js → AlertModal-De04fFoy.js} +16 -26
  9. package/dist/AlertModal-De04fFoy.js.map +1 -0
  10. package/dist/{AppShell-C8V1KRr_.js → AppShell-BUa3U7-e.js} +6 -9
  11. package/dist/{AppShell-C8V1KRr_.js.map → AppShell-BUa3U7-e.js.map} +1 -1
  12. package/dist/{AutoSaveTextarea-BbMhC5Aq.js → AutoSaveTextarea-CXHOQSun.js} +4 -5
  13. package/dist/{AutoSaveTextarea-BbMhC5Aq.js.map → AutoSaveTextarea-CXHOQSun.js.map} +1 -1
  14. package/dist/{Badge-5GHIsgRS.js → Badge-CFRhducL.js} +18 -23
  15. package/dist/Badge-CFRhducL.js.map +1 -0
  16. package/dist/{BrandEditor-CTGtQUFZ.js → BrandEditor-hiLBX7az.js} +16 -23
  17. package/dist/{BrandEditor-CTGtQUFZ.js.map → BrandEditor-hiLBX7az.js.map} +1 -1
  18. package/dist/{BrandLogo-DkESE19K.js → BrandLogo-Dn7hhp2c.js} +4 -5
  19. package/dist/{BrandLogo-DkESE19K.js.map → BrandLogo-Dn7hhp2c.js.map} +1 -1
  20. package/dist/{Breadcrumb-B2YSNON4.js → Breadcrumb-uGFEIjFF.js} +17 -28
  21. package/dist/{Breadcrumb-B2YSNON4.js.map → Breadcrumb-uGFEIjFF.js.map} +1 -1
  22. package/dist/{Button-BNkyYU8u.js → Button-DbvGzEDb.js} +24 -20
  23. package/dist/Button-DbvGzEDb.js.map +1 -0
  24. package/dist/{Calendar-BnKi1kPu.js → Calendar-lJBTETbk.js} +752 -905
  25. package/dist/Calendar-lJBTETbk.js.map +1 -0
  26. package/dist/{Card-DxjGiqH8.js → Card-VIPfOVW5.js} +8 -14
  27. package/dist/{Card-DxjGiqH8.js.map → Card-VIPfOVW5.js.map} +1 -1
  28. package/dist/{Checkbox-CHDDJyAA.js → Checkbox-B2jLlyaO.js} +6 -8
  29. package/dist/{Checkbox-CHDDJyAA.js.map → Checkbox-B2jLlyaO.js.map} +1 -1
  30. package/dist/{Clipboard-DlwVZS1P.js → Clipboard-fAkDdpEu.js} +4 -5
  31. package/dist/{Clipboard-DlwVZS1P.js.map → Clipboard-fAkDdpEu.js.map} +1 -1
  32. package/dist/{ClipboardButton-B1Hr_n_Z.js → ClipboardButton-71Ugbl8c.js} +6 -8
  33. package/dist/{ClipboardButton-B1Hr_n_Z.js.map → ClipboardButton-71Ugbl8c.js.map} +1 -1
  34. package/dist/{CodeEditor-DVSPdfdo.js → CodeEditor-D_b-ZCng.js} +19 -31
  35. package/dist/{CodeEditor-DVSPdfdo.js.map → CodeEditor-D_b-ZCng.js.map} +1 -1
  36. package/dist/{Collapsible-DD4xTL75.js → Collapsible-zsXk4Vpp.js} +5 -8
  37. package/dist/{Collapsible-DD4xTL75.js.map → Collapsible-zsXk4Vpp.js.map} +1 -1
  38. package/dist/{ColorInput-B_eZIu39.js → ColorInput-Cjr1jkvy.js} +9 -12
  39. package/dist/{ColorInput-B_eZIu39.js.map → ColorInput-Cjr1jkvy.js.map} +1 -1
  40. package/dist/{ColorModeSwitch-B6UEzG0H.js → ColorModeSwitch-CuPYnJ2V.js} +5 -6
  41. package/dist/{ColorModeSwitch-B6UEzG0H.js.map → ColorModeSwitch-CuPYnJ2V.js.map} +1 -1
  42. package/dist/{Combobox-CaKqgstG.js → Combobox-DYjvYgl3.js} +38 -67
  43. package/dist/Combobox-DYjvYgl3.js.map +1 -0
  44. package/dist/{Command-DhXmqFLT.js → Command-BcTb6GsR.js} +14 -24
  45. package/dist/{Command-DhXmqFLT.js.map → Command-BcTb6GsR.js.map} +1 -1
  46. package/dist/{CopyField-D0Pg4Z0R.js → CopyField-CnwAvQz9.js} +16 -28
  47. package/dist/{CopyField-D0Pg4Z0R.js.map → CopyField-CnwAvQz9.js.map} +1 -1
  48. package/dist/{DateInput-BgbMDJkm.js → DateInput-DJNX7Vdx.js} +8 -10
  49. package/dist/{DateInput-BgbMDJkm.js.map → DateInput-DJNX7Vdx.js.map} +1 -1
  50. package/dist/{DatePicker-BXpDRo-R.js → DatePicker-CI59gF3S.js} +4 -5
  51. package/dist/{DatePicker-BXpDRo-R.js.map → DatePicker-CI59gF3S.js.map} +1 -1
  52. package/dist/{DateRangeInput-BW0-_jV0.js → DateRangeInput-B3g8cyS0.js} +8 -10
  53. package/dist/{DateRangeInput-BW0-_jV0.js.map → DateRangeInput-B3g8cyS0.js.map} +1 -1
  54. package/dist/{DateRangePicker-C4-DoWac.js → DateRangePicker-48yOB2qV.js} +9 -10
  55. package/dist/{DateRangePicker-C4-DoWac.js.map → DateRangePicker-48yOB2qV.js.map} +1 -1
  56. package/dist/{DiffView-Dy4z-n-1.js → DiffView-DITZdVbh.js} +7 -12
  57. package/dist/{DiffView-Dy4z-n-1.js.map → DiffView-DITZdVbh.js.map} +1 -1
  58. package/dist/{DropdownMenu-CcVbZ_5u.js → DropdownMenu-Ba9atqDa.js} +21 -37
  59. package/dist/DropdownMenu-Ba9atqDa.js.map +1 -0
  60. package/dist/{FieldBox-BrxLkY9C.js → FieldBox-DdSdJ3ZN.js} +6 -10
  61. package/dist/{FieldBox-BrxLkY9C.js.map → FieldBox-DdSdJ3ZN.js.map} +1 -1
  62. package/dist/{FieldItem-BHUqgSO1.js → FieldItem-D7eCMfMB.js} +6 -8
  63. package/dist/{FieldItem-BHUqgSO1.js.map → FieldItem-D7eCMfMB.js.map} +1 -1
  64. package/dist/{FieldItem-CPN1xjN5.d.ts → FieldItem-fqm3CNR8.d.ts} +7 -6
  65. package/dist/{FileUpload-BYFONpEl.js → FileUpload-DskvxhAr.js} +25 -45
  66. package/dist/{FileUpload-BYFONpEl.js.map → FileUpload-DskvxhAr.js.map} +1 -1
  67. package/dist/{Form-CAofWyMI.js → Form-BUNW7nlt.js} +24 -38
  68. package/dist/{Form-CAofWyMI.js.map → Form-BUNW7nlt.js.map} +1 -1
  69. package/dist/{FormGroup-V5kIgQRN.js → FormGroup-QJB21LKp.js} +12 -20
  70. package/dist/{FormGroup-V5kIgQRN.js.map → FormGroup-QJB21LKp.js.map} +1 -1
  71. package/dist/{FullScreenModal-DAvvlGOz.js → FullScreenModal-RzY5XxiG.js} +8 -12
  72. package/dist/{FullScreenModal-DAvvlGOz.js.map → FullScreenModal-RzY5XxiG.js.map} +1 -1
  73. package/dist/HoverCard-OGWKRXJ7.js +24 -0
  74. package/dist/HoverCard-OGWKRXJ7.js.map +1 -0
  75. package/dist/{InlineEdit-D4P0SvCB.js → InlineEdit-CXL0ZslO.js} +7 -8
  76. package/dist/{InlineEdit-D4P0SvCB.js.map → InlineEdit-CXL0ZslO.js.map} +1 -1
  77. package/dist/{InputGroup-CZv_7QlM.js → InputGroup-BWeanEo7.js} +9 -15
  78. package/dist/{InputGroup-CZv_7QlM.js.map → InputGroup-BWeanEo7.js.map} +1 -1
  79. package/dist/{Kbd-CflKthfu.js → Kbd-BprYCICe.js} +8 -13
  80. package/dist/{Kbd-CflKthfu.js.map → Kbd-BprYCICe.js.map} +1 -1
  81. package/dist/{MarkedText-DlmlJO0u.js → MarkedText-BrganZ_V.js} +4 -6
  82. package/dist/{MarkedText-DlmlJO0u.js.map → MarkedText-BrganZ_V.js.map} +1 -1
  83. package/dist/{MermaidDiagram-Te-5gOCU.js → MermaidDiagram-E3azndPk.js} +9 -11
  84. package/dist/{MermaidDiagram-Te-5gOCU.js.map → MermaidDiagram-E3azndPk.js.map} +1 -1
  85. package/dist/{Modal-CbUz-5YH.js → Modal-Cf_kPEBW.js} +14 -22
  86. package/dist/Modal-Cf_kPEBW.js.map +1 -0
  87. package/dist/{ModalTitle-cy0Ht9VY.js → ModalTitle-7vgpfc6B.js} +6 -9
  88. package/dist/ModalTitle-7vgpfc6B.js.map +1 -0
  89. package/dist/{MultiActionButtonGroup-Dzig87s1.js → MultiActionButtonGroup-8WQwL4UQ.js} +6 -8
  90. package/dist/{MultiActionButtonGroup-Dzig87s1.js.map → MultiActionButtonGroup-8WQwL4UQ.js.map} +1 -1
  91. package/dist/{Navbar-DHUS7XiU.js → Navbar-CRjxVboE.js} +13 -22
  92. package/dist/{Navbar-DHUS7XiU.js.map → Navbar-CRjxVboE.js.map} +1 -1
  93. package/dist/{OtpInput-CY8yCaJk.js → OtpInput-C5plPzGU.js} +7 -11
  94. package/dist/{OtpInput-CY8yCaJk.js.map → OtpInput-C5plPzGU.js.map} +1 -1
  95. package/dist/{PageHeader-CL1A6jFM.js → PageHeader-DosMyar2.js} +6 -10
  96. package/dist/{PageHeader-CL1A6jFM.js.map → PageHeader-DosMyar2.js.map} +1 -1
  97. package/dist/{PageLayout-C9aXTpqV.js → PageLayout-LcvJccOW.js} +5 -8
  98. package/dist/{PageLayout-C9aXTpqV.js.map → PageLayout-LcvJccOW.js.map} +1 -1
  99. package/dist/{PageToolbar-DJ5tdYla.js → PageToolbar-By2HznxO.js} +8 -10
  100. package/dist/{PageToolbar-DJ5tdYla.js.map → PageToolbar-By2HznxO.js.map} +1 -1
  101. package/dist/{Pagination-D27x5KmH.js → Pagination-DrXTrvfD.js} +11 -18
  102. package/dist/{Pagination-D27x5KmH.js.map → Pagination-DrXTrvfD.js.map} +1 -1
  103. package/dist/{Popconfirm-DwLCYNaF.js → Popconfirm-BJuDOHdv.js} +46 -25
  104. package/dist/Popconfirm-BJuDOHdv.js.map +1 -0
  105. package/dist/{Popover-DtUDwUVO.js → Popover-DhOPlWgF.js} +5 -7
  106. package/dist/Popover-DhOPlWgF.js.map +1 -0
  107. package/dist/{RadioGroup-B0TwHjBb.js → RadioGroup-B9oC8P15.js} +12 -18
  108. package/dist/{RadioGroup-B0TwHjBb.js.map → RadioGroup-B9oC8P15.js.map} +1 -1
  109. package/dist/{Resizable-D8zs0kcq.js → Resizable-Co-L3qg7.js} +4 -6
  110. package/dist/{Resizable-D8zs0kcq.js.map → Resizable-Co-L3qg7.js.map} +1 -1
  111. package/dist/{Search-vyZwGKMU.js → Search-OgaNjqQM.js} +26 -21
  112. package/dist/Search-OgaNjqQM.js.map +1 -0
  113. package/dist/{SearchInput-DyYXyw3u.js → SearchInput-eLS-uvOn.js} +18 -29
  114. package/dist/SearchInput-eLS-uvOn.js.map +1 -0
  115. package/dist/{SectionNav-tLK3iF6c.js → SectionNav-L81iJBo3.js} +11 -14
  116. package/dist/{SectionNav-tLK3iF6c.js.map → SectionNav-L81iJBo3.js.map} +1 -1
  117. package/dist/{Select-B22hB_-w.js → Select-DRdkdzBp.js} +29 -26
  118. package/dist/Select-DRdkdzBp.js.map +1 -0
  119. package/dist/{Sheet-0TWKTqid.js → Sheet-DVb4XoJ5.js} +13 -20
  120. package/dist/Sheet-DVb4XoJ5.js.map +1 -0
  121. package/dist/{Sidebar-C5hdANBU.js → Sidebar-DYvodJWN.js} +43 -75
  122. package/dist/{Sidebar-C5hdANBU.js.map → Sidebar-DYvodJWN.js.map} +1 -1
  123. package/dist/{Slider-DrcsM8_G.js → Slider-B9IskDxf.js} +8 -12
  124. package/dist/{Slider-DrcsM8_G.js.map → Slider-B9IskDxf.js.map} +1 -1
  125. package/dist/{Stepper-CQrUPVFL.js → Stepper-D7VspVEt.js} +11 -19
  126. package/dist/{Stepper-CQrUPVFL.js.map → Stepper-D7VspVEt.js.map} +1 -1
  127. package/dist/{Switch-DccpSpzC.js → Switch-DONWW7ju.js} +4 -6
  128. package/dist/{Switch-DccpSpzC.js.map → Switch-DONWW7ju.js.map} +1 -1
  129. package/dist/{Table-CilEvpMq.js → Table-BwgBm3hJ.js} +12 -21
  130. package/dist/{Table-CilEvpMq.js.map → Table-BwgBm3hJ.js.map} +1 -1
  131. package/dist/{Tabs-Ck4uWf8U.js → Tabs-DmJB4l_N.js} +9 -14
  132. package/dist/{Tabs-Ck4uWf8U.js.map → Tabs-DmJB4l_N.js.map} +1 -1
  133. package/dist/{TextInput-CR0_USaY.js → TextInput--1CfZybC.js} +8 -10
  134. package/dist/TextInput--1CfZybC.js.map +1 -0
  135. package/dist/{ThemeProvider-BTK7AL-T.js → ThemeProvider-BCHllN7d.js} +8 -13
  136. package/dist/{ThemeProvider-BTK7AL-T.js.map → ThemeProvider-BCHllN7d.js.map} +1 -1
  137. package/dist/{TimePicker-CoRpiEM3.js → TimePicker-CCV3SOw5.js} +4 -6
  138. package/dist/{TimePicker-CoRpiEM3.js.map → TimePicker-CCV3SOw5.js.map} +1 -1
  139. package/dist/{Timeline-DUXgByUE.js → Timeline-EMOpTLAT.js} +8 -13
  140. package/dist/{Timeline-DUXgByUE.js.map → Timeline-EMOpTLAT.js.map} +1 -1
  141. package/dist/{Toast-937n7n8i.js → Toast-BOTINeTX.js} +4 -6
  142. package/dist/{Toast-937n7n8i.js.map → Toast-BOTINeTX.js.map} +1 -1
  143. package/dist/{ToggleAllTooltip-DEjbWFoj.js → ToggleAllTooltip-BFmA6TXf.js} +4 -6
  144. package/dist/{ToggleAllTooltip-DEjbWFoj.js.map → ToggleAllTooltip-BFmA6TXf.js.map} +1 -1
  145. package/dist/{ToggleGroup-BOz1yyz6.js → ToggleGroup-DsDS7k70.js} +3 -4
  146. package/dist/{ToggleGroup-BOz1yyz6.js.map → ToggleGroup-DsDS7k70.js.map} +1 -1
  147. package/dist/{Workbench-CxgNCs3I.js → Workbench-4s0xP6XU.js} +18 -32
  148. package/dist/{Workbench-CxgNCs3I.js.map → Workbench-4s0xP6XU.js.map} +1 -1
  149. package/dist/{ZoomableSvg-DnFXo2L4.js → ZoomableSvg-BRPGgaWJ.js} +9 -11
  150. package/dist/{ZoomableSvg-DnFXo2L4.js.map → ZoomableSvg-BRPGgaWJ.js.map} +1 -1
  151. package/dist/charts.d.ts +0 -16
  152. package/dist/charts.js +10 -19
  153. package/dist/charts.js.map +1 -1
  154. package/dist/{classNames-DcGnTh2N.js → classNames-DkX30VJU.js} +2 -3
  155. package/dist/{classNames-DcGnTh2N.js.map → classNames-DkX30VJU.js.map} +1 -1
  156. package/dist/editors.d.ts +2 -16
  157. package/dist/editors.js +16 -26
  158. package/dist/editors.js.map +1 -1
  159. package/dist/{findLiteralMatches-DgGLzyG0.js → findLiteralMatches-BaLZTPtx.js} +2 -3
  160. package/dist/{findLiteralMatches-DgGLzyG0.js.map → findLiteralMatches-BaLZTPtx.js.map} +1 -1
  161. package/dist/flint.d.ts +0 -2
  162. package/dist/flint.js +10 -14
  163. package/dist/flint.js.map +1 -1
  164. package/dist/{highlightCode-D354tCXO.js → highlightCode-2spZP7ZA.js} +2 -3
  165. package/dist/{highlightCode-D354tCXO.js.map → highlightCode-2spZP7ZA.js.map} +1 -1
  166. package/dist/{icons-ZIeZXXS7.js → icons-DDR9dFSr.js} +21 -40
  167. package/dist/{icons-ZIeZXXS7.js.map → icons-DDR9dFSr.js.map} +1 -1
  168. package/dist/icons.d.ts +1 -1
  169. package/dist/icons.js +1 -2
  170. package/dist/{index-D-itZ3VP.d.ts → index-BljYaTWL.d.ts} +1 -39
  171. package/dist/index.d.ts +452 -1296
  172. package/dist/index.js +76 -74
  173. package/dist/internal/blocks/AIKit.js +1 -2
  174. package/dist/internal/blocks/AppShell.js +1 -2
  175. package/dist/internal/blocks/AuthLayout.js +3 -4
  176. package/dist/internal/blocks/AutoSaveTextarea.js +1 -2
  177. package/dist/internal/blocks/BrandEditor.js +1 -2
  178. package/dist/internal/blocks/ChartPanel.js +3 -4
  179. package/dist/internal/blocks/ChipEditor.js +6 -7
  180. package/dist/internal/blocks/ClipboardButton.js +1 -2
  181. package/dist/internal/blocks/ColorInput.js +1 -2
  182. package/dist/internal/blocks/ColorModeSwitch.js +1 -2
  183. package/dist/internal/blocks/Command.js +1 -2
  184. package/dist/internal/blocks/CopyField.js +1 -2
  185. package/dist/internal/blocks/DashboardHero.js +2 -3
  186. package/dist/internal/blocks/DateInput.js +1 -2
  187. package/dist/internal/blocks/DateRangeInput.js +1 -2
  188. package/dist/internal/blocks/DiagramShared/DiagramSkeleton.js +1 -2
  189. package/dist/internal/blocks/EmptyConfigurationActionCard.js +2 -3
  190. package/dist/internal/blocks/EmptyState.js +1 -2
  191. package/dist/internal/blocks/ErrorState.js +1 -2
  192. package/dist/internal/blocks/ExportMenu.js +5 -6
  193. package/dist/internal/blocks/FacebookButton.js +3 -4
  194. package/dist/internal/blocks/Form/connectors/ComboboxField.js +3 -4
  195. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +2 -3
  196. package/dist/internal/blocks/Form.js +3 -2
  197. package/dist/internal/blocks/FormGroup.js +1 -2
  198. package/dist/internal/blocks/GoogleButton.js +3 -4
  199. package/dist/internal/blocks/InlineEdit.js +1 -2
  200. package/dist/internal/blocks/MicrosoftButton.js +3 -4
  201. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -2
  202. package/dist/internal/blocks/MultiCombobox.js +7 -8
  203. package/dist/internal/blocks/NumberInput.js +2 -3
  204. package/dist/internal/blocks/OtpInput.js +1 -2
  205. package/dist/internal/blocks/PageHeader.js +1 -2
  206. package/dist/internal/blocks/PageLayout.js +1 -2
  207. package/dist/internal/blocks/PageToolbar.js +1 -2
  208. package/dist/internal/blocks/PasswordInput.js +5 -6
  209. package/dist/internal/blocks/SearchInput.js +1 -2
  210. package/dist/internal/blocks/SearchInputWithNavigation.js +6 -7
  211. package/dist/internal/blocks/SectionNav.js +1 -2
  212. package/dist/internal/blocks/SplitButton.js +4 -5
  213. package/dist/internal/blocks/StatCard.js +4 -6
  214. package/dist/internal/blocks/StatCard.js.map +1 -1
  215. package/dist/internal/blocks/TextInput.js +1 -2
  216. package/dist/internal/blocks/Textarea.js +3 -4
  217. package/dist/internal/blocks/TimeInput.js +6 -7
  218. package/dist/internal/components/Alert.js +1 -2
  219. package/dist/internal/components/AlertModal.js +1 -2
  220. package/dist/internal/components/Avatar.js +3 -4
  221. package/dist/internal/components/Badge.js +1 -2
  222. package/dist/internal/components/BrandLogo.js +1 -2
  223. package/dist/internal/components/Breadcrumb.js +1 -2
  224. package/dist/internal/components/Button.js +1 -2
  225. package/dist/internal/components/ButtonGroup.js +2 -3
  226. package/dist/internal/components/Calendar.js +1 -2
  227. package/dist/internal/components/Card.js +1 -2
  228. package/dist/internal/components/Checkbox.js +1 -2
  229. package/dist/internal/components/Clipboard.js +1 -2
  230. package/dist/internal/components/Collapsible.js +1 -2
  231. package/dist/internal/components/CollapsiblePanel.js +5 -6
  232. package/dist/internal/components/Combobox.js +1 -2
  233. package/dist/internal/components/DatePicker.js +1 -2
  234. package/dist/internal/components/DateRangePicker.js +1 -2
  235. package/dist/internal/components/DiffView.js +1 -2
  236. package/dist/internal/components/DotsLoader.js +2 -3
  237. package/dist/internal/components/DropdownMenu.js +1 -2
  238. package/dist/internal/components/EmptySearchContent.js +1 -2
  239. package/dist/internal/components/FileUpload.js +1 -2
  240. package/dist/internal/components/FullScreenModal.js +1 -2
  241. package/dist/internal/components/HelpBlock.js +1 -2
  242. package/dist/internal/components/HoverCard.js +1 -2
  243. package/dist/internal/components/InputGroup.js +1 -2
  244. package/dist/internal/components/Kbd.js +1 -2
  245. package/dist/internal/components/Label.js +2 -3
  246. package/dist/internal/components/Link.js +2 -3
  247. package/dist/internal/components/MarkedText.js +1 -2
  248. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +3 -4
  249. package/dist/internal/components/MergeEditor/PaneHeader.js +1 -2
  250. package/dist/internal/components/MergeEditor/constants.js +1 -2
  251. package/dist/internal/components/MergeEditor/useMergeDiff.js +1 -2
  252. package/dist/internal/components/Modal.js +1 -2
  253. package/dist/internal/components/Navbar.js +1 -2
  254. package/dist/internal/components/Pagination.js +1 -2
  255. package/dist/internal/components/PanelWithDetails.js +4 -5
  256. package/dist/internal/components/Popconfirm.js +1 -2
  257. package/dist/internal/components/Popover.js +1 -2
  258. package/dist/internal/components/Progress.js +2 -3
  259. package/dist/internal/components/RadioGroup.js +1 -2
  260. package/dist/internal/components/Resizable.js +1 -2
  261. package/dist/internal/components/ScrollArea.js +3 -5
  262. package/dist/internal/components/ScrollArea.js.map +1 -1
  263. package/dist/internal/components/Search.js +1 -2
  264. package/dist/internal/components/Select.js +1 -2
  265. package/dist/internal/components/Separator.js +2 -3
  266. package/dist/internal/components/Sheet.js +1 -2
  267. package/dist/internal/components/Sidebar.js +1 -2
  268. package/dist/internal/components/Skeleton/Skeleton.js +2 -3
  269. package/dist/internal/components/Skeleton/SkeletonList.js +2 -3
  270. package/dist/internal/components/Slider.js +1 -2
  271. package/dist/internal/components/SpotlightBackdrop.js +3 -5
  272. package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
  273. package/dist/internal/components/Stepper.js +1 -2
  274. package/dist/internal/components/Switch.js +1 -2
  275. package/dist/internal/components/Table.js +1 -2
  276. package/dist/internal/components/Tabs.js +1 -2
  277. package/dist/internal/components/ThemeProvider.js +2 -2
  278. package/dist/internal/components/TimePicker.js +1 -2
  279. package/dist/internal/components/Timeline.js +1 -2
  280. package/dist/internal/components/Toast.js +2 -2
  281. package/dist/internal/components/Toggle.js +2 -3
  282. package/dist/internal/components/ToggleGroup.js +1 -2
  283. package/dist/internal/components/Tooltip.js +1 -2
  284. package/dist/internal/components/Truncated.js +3 -4
  285. package/dist/internal/components/Workbench.js +1 -2
  286. package/dist/internal/components/ZoomableSvg.js +1 -2
  287. package/dist/internal/hooks/useAltDigitHotkey.js +1 -2
  288. package/dist/internal/hooks/useAutosizeInput.js +1 -2
  289. package/dist/internal/hooks/useScrollbarPosition.js +2 -3
  290. package/dist/internal/hooks/useStableCallback.js +1 -2
  291. package/dist/internal/hooks/useTimeout.js +18 -0
  292. package/dist/internal/hooks/useTimeout.js.map +1 -0
  293. package/dist/internal/utils/accessibleName.js +1 -2
  294. package/dist/internal/utils/mergeRefs.js +1 -2
  295. package/dist/internal/utils.js +3 -3
  296. package/dist/markdown-editor.d.ts +0 -4
  297. package/dist/markdown-editor.js +30 -49
  298. package/dist/markdown-editor.js.map +1 -1
  299. package/dist/mermaid.d.ts +0 -2
  300. package/dist/mermaid.js +1 -2
  301. package/dist/rjsf.d.ts +0 -8
  302. package/dist/rjsf.js +47 -78
  303. package/dist/rjsf.js.map +1 -1
  304. package/dist/{rolldown-runtime-Bdc48AWt.js → rolldown-runtime-BrwM56v-.js} +2 -3
  305. package/dist/{styles-T8xwr0sR.js → styles-BXXXosW_.js} +2 -3
  306. package/dist/{styles-T8xwr0sR.js.map → styles-BXXXosW_.js.map} +1 -1
  307. package/dist/{styles-DxazJ8Mz.js → styles-nwtCRF7y.js} +2 -3
  308. package/dist/{styles-DxazJ8Mz.js.map → styles-nwtCRF7y.js.map} +1 -1
  309. package/dist/styles.css +1 -1
  310. package/dist/{svgCache-Dhmbe-7i.js → svgCache-BzvN_fgr.js} +2 -3
  311. package/dist/{svgCache-Dhmbe-7i.js.map → svgCache-BzvN_fgr.js.map} +1 -1
  312. package/dist/{svgTransforms-Hnvev3Vs.js → svgTransforms-BBxxO9T6.js} +4 -6
  313. package/dist/{svgTransforms-Hnvev3Vs.js.map → svgTransforms-BBxxO9T6.js.map} +1 -1
  314. package/dist/testing.d.ts +0 -2
  315. package/dist/testing.js +2 -3
  316. package/dist/{themeScopeContext-CEVXbYvZ.js → themeScopeContext-BZGPdyG8.js} +6 -11
  317. package/dist/{themeScopeContext-CEVXbYvZ.js.map → themeScopeContext-BZGPdyG8.js.map} +1 -1
  318. package/dist/{themeTokens-DCeb62ap.js → themeTokens-B60cQtAY.js} +4 -6
  319. package/dist/{themeTokens-DCeb62ap.js.map → themeTokens-B60cQtAY.js.map} +1 -1
  320. package/dist/{toast-Y3cTMBW8.js → toast-Dzj1EFOb.js} +10 -17
  321. package/dist/{toast-Y3cTMBW8.js.map → toast-Dzj1EFOb.js.map} +1 -1
  322. package/dist/{types-BPcAjMG0.d.ts → types-CsZuwfxc.d.ts} +1 -3
  323. package/dist/{useControllableState-CUYXMsfz.js → useControllableState-BCvUOC6G.js} +2 -3
  324. package/dist/{useControllableState-CUYXMsfz.js.map → useControllableState-BCvUOC6G.js.map} +1 -1
  325. package/dist/{useElement-D-RjrGa4.js → useElement-Dcoo9Jlr.js} +2 -3
  326. package/dist/{useElement-D-RjrGa4.js.map → useElement-Dcoo9Jlr.js.map} +1 -1
  327. package/dist/{useMergeDiff-CvowEXJ1.js → useMergeDiff-DFIATaTw.js} +3 -5
  328. package/dist/{useMergeDiff-CvowEXJ1.js.map → useMergeDiff-DFIATaTw.js.map} +1 -1
  329. package/dist/{utils-DwC9u0tM.js → utils-DjFceY3H.js} +18 -34
  330. package/dist/utils-DjFceY3H.js.map +1 -0
  331. package/dist/vega.d.ts +1 -5
  332. package/dist/vega.js +3 -4
  333. package/dist/{vegaTheme-ISwGXvof.js → vegaTheme-BcTNRmVS.js} +3 -4
  334. package/dist/{vegaTheme-ISwGXvof.js.map → vegaTheme-BcTNRmVS.js.map} +1 -1
  335. package/dist/{vegaTokens-DCkvpIVE.js → vegaTokens-DnCcy7JY.js} +3 -4
  336. package/dist/{vegaTokens-DCkvpIVE.js.map → vegaTokens-DnCcy7JY.js.map} +1 -1
  337. package/package.json +40 -40
  338. package/src/styles.css +70 -4
  339. package/src/theme.css +117 -11
  340. package/dist/AIKit-CaAW4GLx.js.map +0 -1
  341. package/dist/AlertModal-D4AtpvLS.js.map +0 -1
  342. package/dist/Badge-5GHIsgRS.js.map +0 -1
  343. package/dist/Button-BNkyYU8u.js.map +0 -1
  344. package/dist/Calendar-BnKi1kPu.js.map +0 -1
  345. package/dist/Combobox-CaKqgstG.js.map +0 -1
  346. package/dist/DropdownMenu-CcVbZ_5u.js.map +0 -1
  347. package/dist/HoverCard-Cv5rmvJq.js +0 -26
  348. package/dist/HoverCard-Cv5rmvJq.js.map +0 -1
  349. package/dist/Modal-CbUz-5YH.js.map +0 -1
  350. package/dist/ModalTitle-cy0Ht9VY.js.map +0 -1
  351. package/dist/Popconfirm-DwLCYNaF.js.map +0 -1
  352. package/dist/Popover-DtUDwUVO.js.map +0 -1
  353. package/dist/Search-vyZwGKMU.js.map +0 -1
  354. package/dist/SearchInput-DyYXyw3u.js.map +0 -1
  355. package/dist/Select-B22hB_-w.js.map +0 -1
  356. package/dist/Sheet-0TWKTqid.js.map +0 -1
  357. package/dist/TextInput-CR0_USaY.js.map +0 -1
  358. package/dist/utils-DwC9u0tM.js.map +0 -1
@@ -1,16 +1,15 @@
1
- import { cn } from "./classNames-DcGnTh2N.js";
2
- import { useControllableState } from "./useControllableState-CUYXMsfz.js";
3
- import { Collapsible } from "./Collapsible-DD4xTL75.js";
1
+ import { cn } from "./classNames-DkX30VJU.js";
2
+ import { useControllableState } from "./useControllableState-BCvUOC6G.js";
3
+ import { Collapsible } from "./Collapsible-zsXk4Vpp.js";
4
4
  import { createContext, use, useEffect, useMemo, useRef, useState } from "react";
5
5
  import { Slot } from "@radix-ui/react-slot";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
- //#region src/components/Workbench/constants.ts
7
+ // src/components/Workbench/constants.ts
8
8
  const DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM = 2.75;
9
9
  const DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX = 320;
10
10
  const MIN_WORKBENCH_PANEL_HEIGHT_IN_PX = 120;
11
11
  const WORKBENCH_PANEL_FULL_SCREEN_EXIT_RATIO = .8;
12
- //#endregion
13
- //#region src/components/Workbench/context.ts
12
+ // src/components/Workbench/context.ts
14
13
  const createWorkbenchActions = (setState) => ({
15
14
  expand: () => setState((state) => state === "collapsed" ? "expanded" : state),
16
15
  collapse: () => setState("collapsed"),
@@ -29,29 +28,25 @@ const useWorkbench = () => {
29
28
  if (context === null) throw new Error("Workbench compound components must be rendered inside <Workbench>.");
30
29
  return context;
31
30
  };
32
- //#endregion
33
- //#region src/components/Workbench/WorkbenchBar/WorkbenchBarEnd.tsx
31
+ // src/components/Workbench/WorkbenchBar/WorkbenchBarEnd.tsx
34
32
  const WorkbenchBarEnd = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
35
33
  ...props,
36
34
  "data-slot": "workbench-bar-end",
37
35
  className: cn("tw:col-start-3", "tw:row-start-1", "tw:flex", "tw:items-center", "tw:justify-end", "tw:gap-2", className)
38
36
  });
39
- //#endregion
40
- //#region src/components/Workbench/WorkbenchBar/WorkbenchBarMiddle.tsx
37
+ // src/components/Workbench/WorkbenchBar/WorkbenchBarMiddle.tsx
41
38
  const WorkbenchBarMiddle = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
42
39
  ...props,
43
40
  "data-slot": "workbench-bar-middle",
44
41
  className: cn("tw:col-start-2", "tw:row-start-1", "tw:flex", "tw:items-center", "tw:justify-center", "tw:gap-2", className)
45
42
  });
46
- //#endregion
47
- //#region src/components/Workbench/WorkbenchBar/WorkbenchBarStart.tsx
43
+ // src/components/Workbench/WorkbenchBar/WorkbenchBarStart.tsx
48
44
  const WorkbenchBarStart = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
49
45
  ...props,
50
46
  "data-slot": "workbench-bar-start",
51
47
  className: cn("tw:col-start-1", "tw:row-start-1", "tw:flex", "tw:items-center", "tw:gap-2", className)
52
48
  });
53
- //#endregion
54
- //#region src/components/Workbench/WorkbenchBar/WorkbenchBar.tsx
49
+ // src/components/Workbench/WorkbenchBar/WorkbenchBar.tsx
55
50
  const WorkbenchBar = ({ className, children, ...props }) => /* @__PURE__ */ jsx("div", {
56
51
  "data-workbench-slot": "bar",
57
52
  className: cn("tw:grid", "tw:grid-cols-[auto_1fr_auto]", "tw:items-center", "tw:gap-x-2", "tw:h-(--workbench-bar-height)", "tw:shrink-0", "tw:pointer-events-auto", "tw:border-t", "tw:border-sidebar-border", "tw:bg-sidebar", "tw:px-3", "tw:text-xs", className),
@@ -61,8 +56,7 @@ const WorkbenchBar = ({ className, children, ...props }) => /* @__PURE__ */ jsx(
61
56
  WorkbenchBar.Start = WorkbenchBarStart;
62
57
  WorkbenchBar.Middle = WorkbenchBarMiddle;
63
58
  WorkbenchBar.End = WorkbenchBarEnd;
64
- //#endregion
65
- //#region src/components/Workbench/WorkbenchFullScreenTrigger.tsx
59
+ // src/components/Workbench/WorkbenchFullScreenTrigger.tsx
66
60
  const WorkbenchFullScreenTrigger = ({ asChild = false, onClick, ...props }) => {
67
61
  const { state, toggleFullScreen } = useWorkbench();
68
62
  const isFullScreen = state === "full-screen";
@@ -79,8 +73,7 @@ const WorkbenchFullScreenTrigger = ({ asChild = false, onClick, ...props }) => {
79
73
  onClick: handleClick
80
74
  });
81
75
  };
82
- //#endregion
83
- //#region src/components/Workbench/WorkbenchPanel/WorkbenchPanelResizeHandle.tsx
76
+ // src/components/Workbench/WorkbenchPanel/WorkbenchPanelResizeHandle.tsx
84
77
  const getMaxHeight = (panel) => {
85
78
  const hostTop = panel.offsetParent?.getBoundingClientRect().top ?? 0;
86
79
  return Math.max(panel.getBoundingClientRect().bottom - hostTop, 120);
@@ -179,8 +172,7 @@ const WorkbenchPanelResizeHandle = ({ panelRef }) => {
179
172
  })
180
173
  });
181
174
  };
182
- //#endregion
183
- //#region src/components/Workbench/WorkbenchPanel/WorkbenchPanel.tsx
175
+ // src/components/Workbench/WorkbenchPanel/WorkbenchPanel.tsx
184
176
  const clearRadixMeasurementTransitionBlock = (panel) => {
185
177
  if (panel) panel.style.transitionDuration = "";
186
178
  };
@@ -199,8 +191,7 @@ const WorkbenchPanel = ({ className, children, ...props }) => {
199
191
  })]
200
192
  });
201
193
  };
202
- //#endregion
203
- //#region src/components/Workbench/WorkbenchPanel/WorkbenchPanelActions.tsx
194
+ // src/components/Workbench/WorkbenchPanel/WorkbenchPanelActions.tsx
204
195
  const WorkbenchPanelActions = ({ className, asChild = false, ...props }) => {
205
196
  return /* @__PURE__ */ jsx(asChild ? Slot : "div", {
206
197
  ...props,
@@ -208,29 +199,25 @@ const WorkbenchPanelActions = ({ className, asChild = false, ...props }) => {
208
199
  className: cn("tw:col-start-2", "tw:row-start-1", "tw:flex", "tw:items-center", "tw:gap-2", className)
209
200
  });
210
201
  };
211
- //#endregion
212
- //#region src/components/Workbench/WorkbenchPanel/WorkbenchPanelContent.tsx
202
+ // src/components/Workbench/WorkbenchPanel/WorkbenchPanelContent.tsx
213
203
  const WorkbenchPanelContent = ({ className, children, ...props }) => /* @__PURE__ */ jsx("div", {
214
204
  className: cn("tw:min-h-0", "tw:flex-1", "tw:overflow-auto", className),
215
205
  ...props,
216
206
  children
217
207
  });
218
- //#endregion
219
- //#region src/components/Workbench/WorkbenchPanel/WorkbenchPanelHeader.tsx
208
+ // src/components/Workbench/WorkbenchPanel/WorkbenchPanelHeader.tsx
220
209
  const WorkbenchPanelHeader = ({ className, children, ...props }) => /* @__PURE__ */ jsx("div", {
221
210
  className: cn("tw:grid", "tw:grid-cols-[1fr_auto]", "tw:items-center", "tw:gap-x-2", "tw:shrink-0", "tw:bg-sidebar", "tw:px-3", "tw:py-2", "tw:text-xs", className),
222
211
  ...props,
223
212
  children
224
213
  });
225
- //#endregion
226
- //#region src/components/Workbench/WorkbenchPanel/WorkbenchPanelTitle.tsx
214
+ // src/components/Workbench/WorkbenchPanel/WorkbenchPanelTitle.tsx
227
215
  const WorkbenchPanelTitle = ({ className, ...props }) => /* @__PURE__ */ jsx("div", {
228
216
  ...props,
229
217
  "data-slot": "workbench-panel-title",
230
218
  className: cn("tw:col-start-1", "tw:flex", "tw:items-center", "tw:text-sm", "tw:font-semibold", "tw:text-foreground", className)
231
219
  });
232
- //#endregion
233
- //#region src/components/Workbench/Workbench.tsx
220
+ // src/components/Workbench/Workbench.tsx
234
221
  const Workbench = ({ className, children, state: stateProp, defaultState = "collapsed", onStateChange, barHeight = DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM, panelHeight: panelHeightProp, defaultPanelHeight = 320, onPanelHeightChange }) => {
235
222
  const [state, setState] = useControllableState({
236
223
  prop: stateProp,
@@ -289,7 +276,6 @@ Workbench.PanelActions = WorkbenchPanelActions;
289
276
  Workbench.PanelContent = WorkbenchPanelContent;
290
277
  Workbench.Trigger = Collapsible.Trigger;
291
278
  Workbench.FullScreenTrigger = WorkbenchFullScreenTrigger;
292
- //#endregion
293
279
  export { DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM, DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX, Workbench, useWorkbench };
294
280
 
295
- //# sourceMappingURL=Workbench-CxgNCs3I.js.map
281
+ //# sourceMappingURL=Workbench-4s0xP6XU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Workbench-CxgNCs3I.js","names":[],"sources":["../src/components/Workbench/constants.ts","../src/components/Workbench/context.ts","../src/components/Workbench/WorkbenchBar/WorkbenchBarEnd.tsx","../src/components/Workbench/WorkbenchBar/WorkbenchBarMiddle.tsx","../src/components/Workbench/WorkbenchBar/WorkbenchBarStart.tsx","../src/components/Workbench/WorkbenchBar/WorkbenchBar.tsx","../src/components/Workbench/WorkbenchFullScreenTrigger.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelResizeHandle.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanel.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelActions.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelContent.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelHeader.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelTitle.tsx","../src/components/Workbench/Workbench.tsx"],"sourcesContent":["export const DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM = 2.75;\n\nexport const MIN_WORKBENCH_BAR_HEIGHT_IN_REM = 1;\n\nexport const DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX = 320;\n\nexport const MIN_WORKBENCH_PANEL_HEIGHT_IN_PX = 120;\n\nexport const WORKBENCH_PANEL_RESIZE_STEP_IN_PX = 24;\n\nexport const WORKBENCH_PANEL_FULL_SCREEN_EXIT_RATIO = 0.8;\n","import { createContext, use } from 'react';\nimport type { Dispatch, SetStateAction } from 'react';\n\n/**\n * Full screen is a mode of the open panel, not a flag beside it — as two booleans the fourth\n * combination (collapsed *and* full screen) is expressible but meaningless.\n */\nexport type WorkbenchState = 'collapsed' | 'expanded' | 'full-screen';\n\ntype WorkbenchActions = {\n expand: () => void;\n collapse: () => void;\n toggleExpanded: () => void;\n enterFullScreen: () => void;\n exitFullScreen: () => void;\n toggleFullScreen: () => void;\n};\n\ntype WorkbenchContextValue = WorkbenchActions & {\n state: WorkbenchState;\n setState: Dispatch<SetStateAction<WorkbenchState>>;\n panelHeight: number;\n setPanelHeight: Dispatch<SetStateAction<number>>;\n isResizing: boolean;\n setIsResizing: (isResizing: boolean) => void;\n};\n\nexport const createWorkbenchActions = (\n setState: Dispatch<SetStateAction<WorkbenchState>>,\n): WorkbenchActions => ({\n // Opening an already-open panel leaves full screen alone.\n expand: () => setState((state) => (state === 'collapsed' ? 'expanded' : state)),\n collapse: () => setState('collapsed'),\n toggleExpanded: () => setState((state) => (state === 'collapsed' ? 'expanded' : 'collapsed')),\n\n enterFullScreen: () => setState('full-screen'),\n // Exiting returns to the open panel, never to a closed one — this is a restore, not a collapse.\n exitFullScreen: () => setState((state) => (state === 'full-screen' ? 'expanded' : state)),\n toggleFullScreen: () =>\n setState((state) => (state === 'full-screen' ? 'expanded' : 'full-screen')),\n});\n\nexport const WorkbenchContext = createContext<WorkbenchContextValue | null>(null);\n\n/**\n * The parts sit at arbitrary depth under `<Workbench>` — a trigger lives inside the panel header,\n * three levels down — so the state travels by context rather than props.\n */\nexport const useWorkbench = (): WorkbenchContextValue => {\n const context = use(WorkbenchContext);\n\n if (context === null) {\n throw new Error('Workbench compound components must be rendered inside <Workbench>.');\n }\n\n return context;\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchBarEnd = ({ className, ...props }: Props) => (\n <div\n {...props}\n data-slot=\"workbench-bar-end\"\n className={cn(\n // grid placement\n 'tw:col-start-3',\n 'tw:row-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-end',\n 'tw:gap-2',\n\n className,\n )}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchBarMiddle = ({ className, ...props }: Props) => (\n <div\n {...props}\n data-slot=\"workbench-bar-middle\"\n className={cn(\n // grid placement\n 'tw:col-start-2',\n 'tw:row-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:gap-2',\n\n className,\n )}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchBarStart = ({ className, ...props }: Props) => (\n <div\n {...props}\n data-slot=\"workbench-bar-start\"\n className={cn(\n // grid placement\n 'tw:col-start-1',\n 'tw:row-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2',\n\n className,\n )}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\nimport { WorkbenchBarEnd } from './WorkbenchBarEnd';\nimport { WorkbenchBarMiddle } from './WorkbenchBarMiddle';\nimport { WorkbenchBarStart } from './WorkbenchBarStart';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchBar = ({ className, children, ...props }: Props) => (\n <div\n // Marked so a floating surface (kbc-ui's Kai widget) can measure the dock; the root's rect is the bar alone.\n data-workbench-slot=\"bar\"\n className={cn(\n // layout\n 'tw:grid',\n 'tw:grid-cols-[auto_1fr_auto]',\n 'tw:items-center',\n 'tw:gap-x-2',\n\n // sizing\n 'tw:h-(--workbench-bar-height)',\n 'tw:shrink-0',\n 'tw:pointer-events-auto',\n\n // surface\n 'tw:border-t',\n 'tw:border-sidebar-border',\n 'tw:bg-sidebar',\n\n // spacing\n 'tw:px-3',\n\n // typography\n 'tw:text-xs',\n\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nWorkbenchBar.Start = WorkbenchBarStart;\nWorkbenchBar.Middle = WorkbenchBarMiddle;\nWorkbenchBar.End = WorkbenchBarEnd;\n","import type { ComponentProps, MouseEvent } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { useWorkbench } from './context';\n\ntype Props = ComponentProps<'button'> & {\n asChild?: boolean;\n};\n\nexport const WorkbenchFullScreenTrigger = ({ asChild = false, onClick, ...props }: Props) => {\n const { state, toggleFullScreen } = useWorkbench();\n const isFullScreen = state === 'full-screen';\n const Comp = asChild ? Slot : 'button';\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (!event.defaultPrevented) {\n toggleFullScreen();\n }\n };\n\n return (\n <Comp\n {...(asChild ? {} : { type: 'button' as const })}\n {...props}\n data-slot=\"workbench-full-screen-trigger\"\n data-state={isFullScreen ? 'on' : 'off'}\n onClick={handleClick}\n />\n );\n};\n","import { useEffect, useRef } from 'react';\nimport type { KeyboardEvent, PointerEvent, RefObject } from 'react';\n\nimport { cn } from '../../../utils';\nimport {\n MIN_WORKBENCH_PANEL_HEIGHT_IN_PX,\n WORKBENCH_PANEL_FULL_SCREEN_EXIT_RATIO,\n WORKBENCH_PANEL_RESIZE_STEP_IN_PX,\n} from '../constants';\nimport { useWorkbench } from '../context';\n\ntype Props = {\n panelRef: RefObject<HTMLDivElement | null>;\n};\n\nconst getMaxHeight = (panel: HTMLDivElement) => {\n const hostTop = panel.offsetParent?.getBoundingClientRect().top ?? 0;\n\n return Math.max(panel.getBoundingClientRect().bottom - hostTop, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX);\n};\n\nconst clampHeight = (height: number, panel: HTMLDivElement) =>\n Math.min(Math.max(height, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX), getMaxHeight(panel));\n\nexport const WorkbenchPanelResizeHandle = ({ panelRef }: Props) => {\n const {\n state,\n panelHeight,\n setPanelHeight,\n isResizing,\n setIsResizing,\n enterFullScreen,\n exitFullScreen,\n } = useWorkbench();\n const grabOffsetRef = useRef(0);\n const previousStateRef = useRef(state);\n const isFullScreenRequestedRef = useRef(state === 'full-screen');\n const enteredFullScreenByDragRef = useRef(false);\n const exitedFullScreenByDragRef = useRef(false);\n\n useEffect(() => {\n if (!isResizing) return;\n\n const { body } = document;\n const { cursor, userSelect } = body.style;\n\n body.style.cursor = 'ns-resize';\n body.style.userSelect = 'none';\n\n return () => {\n body.style.cursor = cursor;\n body.style.userSelect = userSelect;\n };\n }, [isResizing]);\n\n useEffect(() => {\n const previous = previousStateRef.current;\n const panel = panelRef.current;\n\n previousStateRef.current = state;\n isFullScreenRequestedRef.current = state === 'full-screen';\n\n if (previous !== 'full-screen' || state !== 'expanded' || !panel) return;\n\n const draggedIntoFullScreen = enteredFullScreenByDragRef.current;\n const draggedOutOfFullScreen = exitedFullScreenByDragRef.current;\n\n enteredFullScreenByDragRef.current = false;\n exitedFullScreenByDragRef.current = false;\n\n if (!draggedIntoFullScreen || draggedOutOfFullScreen) return;\n\n setPanelHeight(\n clampHeight(getMaxHeight(panel) * WORKBENCH_PANEL_FULL_SCREEN_EXIT_RATIO, panel),\n );\n }, [state, panelRef, setPanelHeight]);\n\n const applyHeight = (height: number, panel: HTMLDivElement) => {\n const isFullScreen = isFullScreenRequestedRef.current;\n\n if (height >= getMaxHeight(panel)) {\n if (!isFullScreen) {\n isFullScreenRequestedRef.current = true;\n enteredFullScreenByDragRef.current = true;\n enterFullScreen();\n }\n\n return;\n }\n\n if (isFullScreen) {\n isFullScreenRequestedRef.current = false;\n exitedFullScreenByDragRef.current = true;\n exitFullScreen();\n }\n\n setPanelHeight(Math.max(height, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX));\n };\n\n const handlePointerDown = (event: PointerEvent<HTMLDivElement>) => {\n const panel = panelRef.current;\n\n if (event.button !== 0 || !panel) return;\n\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n grabOffsetRef.current = panel.getBoundingClientRect().top - event.clientY;\n setIsResizing(true);\n };\n\n const handlePointerMove = (event: PointerEvent<HTMLDivElement>) => {\n const panel = panelRef.current;\n\n if (!panel || !event.currentTarget.hasPointerCapture(event.pointerId)) return;\n\n const top = event.clientY + grabOffsetRef.current;\n\n applyHeight(panel.getBoundingClientRect().bottom - top, panel);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const panel = panelRef.current;\n\n if (!panel) return;\n\n const step = event.shiftKey\n ? WORKBENCH_PANEL_RESIZE_STEP_IN_PX * 4\n : WORKBENCH_PANEL_RESIZE_STEP_IN_PX;\n const delta = event.key === 'ArrowUp' ? step : event.key === 'ArrowDown' ? -step : 0;\n\n if (delta === 0) return;\n\n event.preventDefault();\n applyHeight(\n (isFullScreenRequestedRef.current ? getMaxHeight(panel) : panelHeight) + delta,\n panel,\n );\n };\n\n return (\n <div\n role=\"separator\"\n aria-orientation=\"horizontal\"\n aria-label=\"Resize panel\"\n aria-valuenow={Math.round(panelHeight)}\n aria-valuemin={MIN_WORKBENCH_PANEL_HEIGHT_IN_PX}\n tabIndex={0}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onLostPointerCapture={() => setIsResizing(false)}\n onKeyDown={handleKeyDown}\n className={cn(\n // group\n 'tw:group/workbench-resize',\n\n // positioning — the panel is the positioned ancestor\n 'tw:absolute',\n 'tw:inset-x-0',\n 'tw:top-0',\n 'tw:z-10',\n\n // sizing\n 'tw:h-2',\n\n // layout — the whole strip grabs, only the pill shows\n 'tw:flex',\n 'tw:justify-center',\n\n // affordance\n 'tw:cursor-ns-resize',\n 'tw:touch-none',\n\n // focus\n 'tw:outline-none',\n )}\n >\n <span\n className={cn(\n // layout — hangs below the strip so the pill sits clear of the top edge, and\n // grabs there too since the events bubble to the strip\n 'tw:flex',\n 'tw:h-3',\n 'tw:w-16',\n 'tw:items-end',\n 'tw:justify-center',\n )}\n >\n <span\n className={cn(\n // sizing\n 'tw:h-1.5',\n 'tw:w-16',\n\n // surface\n 'tw:rounded-full',\n 'tw:bg-input',\n 'tw:transition-colors',\n 'tw:group-hover/workbench-resize:bg-muted-foreground',\n 'tw:group-focus-visible/workbench-resize:bg-muted-foreground',\n 'tw:group-data-[workbench-resizing=true]/workbench:bg-muted-foreground',\n )}\n />\n </span>\n </div>\n );\n};\n","import { useEffect, useRef } from 'react';\nimport type { ComponentProps, CSSProperties } from 'react';\n\nimport { cn } from '../../../utils';\nimport { Collapsible } from '../../Collapsible';\n\nimport { WorkbenchPanelResizeHandle } from './WorkbenchPanelResizeHandle';\n\ntype Props = ComponentProps<'div'>;\n\nconst clearRadixMeasurementTransitionBlock = (panel: HTMLDivElement | null) => {\n if (panel) panel.style.transitionDuration = '';\n};\n\nexport const WorkbenchPanel = ({ className, children, ...props }: Props) => {\n const panelRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => clearRadixMeasurementTransitionBlock(panelRef.current), []);\n\n return (\n <Collapsible.Content\n ref={panelRef}\n // See `WorkbenchBar` — the other half of the dock's measurable area.\n data-workbench-slot=\"panel\"\n style={{ '--workbench-panel-shadow': '0 -8px 24px -6px rgb(0 0 0 / 0.08)' } as CSSProperties}\n className={cn(\n // positioning — against the host, which must be a positioned element\n 'tw:absolute',\n 'tw:inset-x-0',\n 'tw:bottom-(--workbench-bar-height)',\n 'tw:pointer-events-auto',\n\n // height — the drag-controlled var, capped at the space above the bar so the panel\n // never covers it, whatever height was dragged or restored\n 'tw:h-(--workbench-panel-height)',\n 'tw:max-h-[calc(100%-var(--workbench-bar-height))]',\n 'tw:group-data-[workbench-state=full-screen]/workbench:h-[calc(100%-var(--workbench-bar-height))]',\n\n // height transition\n 'tw:transition-[height]',\n 'tw:duration-200',\n 'tw:ease-out',\n 'tw:group-data-[workbench-resizing=true]/workbench:transition-none',\n\n // surface\n 'tw:border-x',\n 'tw:border-t',\n 'tw:border-border',\n\n // clipping\n 'tw:overflow-hidden',\n\n // raised edge\n 'tw:group-not-data-[workbench-state=full-screen]/workbench:rounded-t-2xl',\n 'tw:group-not-data-[workbench-state=full-screen]/workbench:shadow-(--workbench-panel-shadow)',\n )}\n >\n <WorkbenchPanelResizeHandle panelRef={panelRef} />\n\n <div\n className={cn(\n // layout\n 'tw:flex',\n 'tw:flex-col',\n 'tw:h-full',\n\n // surface\n 'tw:bg-background',\n\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </Collapsible.Content>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'> & {\n asChild?: boolean;\n};\n\nexport const WorkbenchPanelActions = ({ className, asChild = false, ...props }: Props) => {\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n {...props}\n data-slot=\"workbench-panel-actions\"\n className={cn(\n // grid placement\n 'tw:col-start-2',\n 'tw:row-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2',\n\n className,\n )}\n />\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchPanelContent = ({ className, children, ...props }: Props) => (\n <div\n className={cn(\n // layout\n 'tw:min-h-0',\n 'tw:flex-1',\n 'tw:overflow-auto',\n\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchPanelHeader = ({ className, children, ...props }: Props) => (\n <div\n className={cn(\n // layout\n 'tw:grid',\n 'tw:grid-cols-[1fr_auto]',\n 'tw:items-center',\n 'tw:gap-x-2',\n\n // sizing\n 'tw:shrink-0',\n\n // surface\n 'tw:bg-sidebar',\n\n // spacing\n 'tw:px-3',\n 'tw:py-2',\n\n // typography\n 'tw:text-xs',\n\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchPanelTitle = ({ className, ...props }: Props) => (\n <div\n {...props}\n data-slot=\"workbench-panel-title\"\n className={cn(\n // grid placement\n 'tw:col-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n\n // typography\n 'tw:text-sm',\n 'tw:font-semibold',\n 'tw:text-foreground',\n\n className,\n )}\n />\n);\n","import { useMemo, useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\n\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { cn } from '../../utils';\nimport { Collapsible } from '../Collapsible';\n\nimport {\n DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM,\n DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX,\n MIN_WORKBENCH_BAR_HEIGHT_IN_REM,\n MIN_WORKBENCH_PANEL_HEIGHT_IN_PX,\n} from './constants';\nimport type { WorkbenchState } from './context';\nimport { createWorkbenchActions, WorkbenchContext } from './context';\nimport {\n WorkbenchBar,\n WorkbenchBarEnd,\n WorkbenchBarMiddle,\n WorkbenchBarStart,\n} from './WorkbenchBar';\nimport { WorkbenchFullScreenTrigger } from './WorkbenchFullScreenTrigger';\nimport {\n WorkbenchPanel,\n WorkbenchPanelActions,\n WorkbenchPanelContent,\n WorkbenchPanelHeader,\n WorkbenchPanelTitle,\n} from './WorkbenchPanel';\n\ntype Props = {\n className?: string;\n children: ReactNode;\n state?: WorkbenchState;\n defaultState?: WorkbenchState;\n onStateChange?: (state: WorkbenchState) => void;\n barHeight?: number;\n panelHeight?: number;\n defaultPanelHeight?: number;\n onPanelHeightChange?: (panelHeight: number) => void;\n};\n\nexport const Workbench = ({\n className,\n children,\n state: stateProp,\n defaultState = 'collapsed',\n onStateChange,\n barHeight = DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM,\n panelHeight: panelHeightProp,\n defaultPanelHeight = DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX,\n onPanelHeightChange,\n}: Props) => {\n const [state, setState] = useControllableState<WorkbenchState>({\n prop: stateProp,\n defaultProp: defaultState,\n onChange: onStateChange,\n });\n const [panelHeight, setPanelHeight] = useControllableState<number>({\n prop: panelHeightProp,\n defaultProp: defaultPanelHeight,\n onChange: onPanelHeightChange,\n });\n const [isResizing, setIsResizing] = useState(false);\n\n const actions = useMemo(() => createWorkbenchActions(setState), [setState]);\n const value = useMemo(\n () => ({\n state,\n setState,\n panelHeight,\n setPanelHeight,\n isResizing,\n setIsResizing,\n ...actions,\n }),\n [state, setState, panelHeight, setPanelHeight, isResizing, actions],\n );\n\n const clampedBarHeight = Math.max(barHeight, MIN_WORKBENCH_BAR_HEIGHT_IN_REM);\n const clampedPanelHeight = Math.max(panelHeight, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX);\n\n return (\n <WorkbenchContext value={value}>\n <Collapsible\n open={state !== 'collapsed'}\n onOpenChange={(open) => setState(open ? 'expanded' : 'collapsed')}\n data-workbench-state={state}\n data-workbench-resizing={isResizing ? 'true' : undefined}\n style={\n {\n '--workbench-bar-height': `${clampedBarHeight}rem`,\n '--workbench-panel-height': `${clampedPanelHeight}px`,\n } as CSSProperties\n }\n className={cn(\n // reset\n 'tailwindcss-preflight',\n\n // group\n 'tw:group/workbench',\n\n // positioning — above the chrome layer (`z-50`) *and* above a `Sidebar` in\n // `expand-on-hover`, which takes `z-51` to float over content; the dock outranks both.\n // Overlays (Modal / Sheet / Popover / Tooltip) live at 1051+, so they still win.\n 'tw:z-[52]',\n\n // layout\n 'tw:shrink-0',\n\n className,\n )}\n >\n {children}\n </Collapsible>\n </WorkbenchContext>\n );\n};\n\nWorkbench.Bar = WorkbenchBar;\nWorkbench.BarStart = WorkbenchBarStart;\nWorkbench.BarMiddle = WorkbenchBarMiddle;\nWorkbench.BarEnd = WorkbenchBarEnd;\n\nWorkbench.Panel = WorkbenchPanel;\nWorkbench.PanelHeader = WorkbenchPanelHeader;\nWorkbench.PanelTitle = WorkbenchPanelTitle;\nWorkbench.PanelActions = WorkbenchPanelActions;\nWorkbench.PanelContent = WorkbenchPanelContent;\n\nWorkbench.Trigger = Collapsible.Trigger;\nWorkbench.FullScreenTrigger = WorkbenchFullScreenTrigger;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Workbench-4s0xP6XU.js","names":[],"sources":["../src/components/Workbench/constants.ts","../src/components/Workbench/context.ts","../src/components/Workbench/WorkbenchBar/WorkbenchBarEnd.tsx","../src/components/Workbench/WorkbenchBar/WorkbenchBarMiddle.tsx","../src/components/Workbench/WorkbenchBar/WorkbenchBarStart.tsx","../src/components/Workbench/WorkbenchBar/WorkbenchBar.tsx","../src/components/Workbench/WorkbenchFullScreenTrigger.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelResizeHandle.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanel.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelActions.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelContent.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelHeader.tsx","../src/components/Workbench/WorkbenchPanel/WorkbenchPanelTitle.tsx","../src/components/Workbench/Workbench.tsx"],"sourcesContent":["export const DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM = 2.75;\n\nexport const MIN_WORKBENCH_BAR_HEIGHT_IN_REM = 1;\n\nexport const DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX = 320;\n\nexport const MIN_WORKBENCH_PANEL_HEIGHT_IN_PX = 120;\n\nexport const WORKBENCH_PANEL_RESIZE_STEP_IN_PX = 24;\n\nexport const WORKBENCH_PANEL_FULL_SCREEN_EXIT_RATIO = 0.8;\n","import { createContext, use } from 'react';\nimport type { Dispatch, SetStateAction } from 'react';\n\n/**\n * Full screen is a mode of the open panel, not a flag beside it — as two booleans the fourth\n * combination (collapsed *and* full screen) is expressible but meaningless.\n */\nexport type WorkbenchState = 'collapsed' | 'expanded' | 'full-screen';\n\ntype WorkbenchActions = {\n expand: () => void;\n collapse: () => void;\n toggleExpanded: () => void;\n enterFullScreen: () => void;\n exitFullScreen: () => void;\n toggleFullScreen: () => void;\n};\n\ntype WorkbenchContextValue = WorkbenchActions & {\n state: WorkbenchState;\n setState: Dispatch<SetStateAction<WorkbenchState>>;\n panelHeight: number;\n setPanelHeight: Dispatch<SetStateAction<number>>;\n isResizing: boolean;\n setIsResizing: (isResizing: boolean) => void;\n};\n\nexport const createWorkbenchActions = (\n setState: Dispatch<SetStateAction<WorkbenchState>>,\n): WorkbenchActions => ({\n // Opening an already-open panel leaves full screen alone.\n expand: () => setState((state) => (state === 'collapsed' ? 'expanded' : state)),\n collapse: () => setState('collapsed'),\n toggleExpanded: () => setState((state) => (state === 'collapsed' ? 'expanded' : 'collapsed')),\n\n enterFullScreen: () => setState('full-screen'),\n // Exiting returns to the open panel, never to a closed one — this is a restore, not a collapse.\n exitFullScreen: () => setState((state) => (state === 'full-screen' ? 'expanded' : state)),\n toggleFullScreen: () =>\n setState((state) => (state === 'full-screen' ? 'expanded' : 'full-screen')),\n});\n\nexport const WorkbenchContext = createContext<WorkbenchContextValue | null>(null);\n\n/**\n * The parts sit at arbitrary depth under `<Workbench>` — a trigger lives inside the panel header,\n * three levels down — so the state travels by context rather than props.\n */\nexport const useWorkbench = (): WorkbenchContextValue => {\n const context = use(WorkbenchContext);\n\n if (context === null) {\n throw new Error('Workbench compound components must be rendered inside <Workbench>.');\n }\n\n return context;\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchBarEnd = ({ className, ...props }: Props) => (\n <div\n {...props}\n data-slot=\"workbench-bar-end\"\n className={cn(\n // grid placement\n 'tw:col-start-3',\n 'tw:row-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-end',\n 'tw:gap-2',\n\n className,\n )}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchBarMiddle = ({ className, ...props }: Props) => (\n <div\n {...props}\n data-slot=\"workbench-bar-middle\"\n className={cn(\n // grid placement\n 'tw:col-start-2',\n 'tw:row-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:gap-2',\n\n className,\n )}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchBarStart = ({ className, ...props }: Props) => (\n <div\n {...props}\n data-slot=\"workbench-bar-start\"\n className={cn(\n // grid placement\n 'tw:col-start-1',\n 'tw:row-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2',\n\n className,\n )}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\nimport { WorkbenchBarEnd } from './WorkbenchBarEnd';\nimport { WorkbenchBarMiddle } from './WorkbenchBarMiddle';\nimport { WorkbenchBarStart } from './WorkbenchBarStart';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchBar = ({ className, children, ...props }: Props) => (\n <div\n // Marked so a floating surface (kbc-ui's Kai widget) can measure the dock; the root's rect is the bar alone.\n data-workbench-slot=\"bar\"\n className={cn(\n // layout\n 'tw:grid',\n 'tw:grid-cols-[auto_1fr_auto]',\n 'tw:items-center',\n 'tw:gap-x-2',\n\n // sizing\n 'tw:h-(--workbench-bar-height)',\n 'tw:shrink-0',\n 'tw:pointer-events-auto',\n\n // surface\n 'tw:border-t',\n 'tw:border-sidebar-border',\n 'tw:bg-sidebar',\n\n // spacing\n 'tw:px-3',\n\n // typography\n 'tw:text-xs',\n\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nWorkbenchBar.Start = WorkbenchBarStart;\nWorkbenchBar.Middle = WorkbenchBarMiddle;\nWorkbenchBar.End = WorkbenchBarEnd;\n","import type { ComponentProps, MouseEvent } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { useWorkbench } from './context';\n\ntype Props = ComponentProps<'button'> & {\n asChild?: boolean;\n};\n\nexport const WorkbenchFullScreenTrigger = ({ asChild = false, onClick, ...props }: Props) => {\n const { state, toggleFullScreen } = useWorkbench();\n const isFullScreen = state === 'full-screen';\n const Comp = asChild ? Slot : 'button';\n\n const handleClick = (event: MouseEvent<HTMLButtonElement>) => {\n onClick?.(event);\n\n if (!event.defaultPrevented) {\n toggleFullScreen();\n }\n };\n\n return (\n <Comp\n {...(asChild ? {} : { type: 'button' as const })}\n {...props}\n data-slot=\"workbench-full-screen-trigger\"\n data-state={isFullScreen ? 'on' : 'off'}\n onClick={handleClick}\n />\n );\n};\n","import { useEffect, useRef } from 'react';\nimport type { KeyboardEvent, PointerEvent, RefObject } from 'react';\n\nimport { cn } from '../../../utils';\nimport {\n MIN_WORKBENCH_PANEL_HEIGHT_IN_PX,\n WORKBENCH_PANEL_FULL_SCREEN_EXIT_RATIO,\n WORKBENCH_PANEL_RESIZE_STEP_IN_PX,\n} from '../constants';\nimport { useWorkbench } from '../context';\n\ntype Props = {\n panelRef: RefObject<HTMLDivElement | null>;\n};\n\nconst getMaxHeight = (panel: HTMLDivElement) => {\n const hostTop = panel.offsetParent?.getBoundingClientRect().top ?? 0;\n\n return Math.max(panel.getBoundingClientRect().bottom - hostTop, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX);\n};\n\nconst clampHeight = (height: number, panel: HTMLDivElement) =>\n Math.min(Math.max(height, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX), getMaxHeight(panel));\n\nexport const WorkbenchPanelResizeHandle = ({ panelRef }: Props) => {\n const {\n state,\n panelHeight,\n setPanelHeight,\n isResizing,\n setIsResizing,\n enterFullScreen,\n exitFullScreen,\n } = useWorkbench();\n const grabOffsetRef = useRef(0);\n const previousStateRef = useRef(state);\n const isFullScreenRequestedRef = useRef(state === 'full-screen');\n const enteredFullScreenByDragRef = useRef(false);\n const exitedFullScreenByDragRef = useRef(false);\n\n useEffect(() => {\n if (!isResizing) return;\n\n const { body } = document;\n const { cursor, userSelect } = body.style;\n\n body.style.cursor = 'ns-resize';\n body.style.userSelect = 'none';\n\n return () => {\n body.style.cursor = cursor;\n body.style.userSelect = userSelect;\n };\n }, [isResizing]);\n\n useEffect(() => {\n const previous = previousStateRef.current;\n const panel = panelRef.current;\n\n previousStateRef.current = state;\n isFullScreenRequestedRef.current = state === 'full-screen';\n\n if (previous !== 'full-screen' || state !== 'expanded' || !panel) return;\n\n const draggedIntoFullScreen = enteredFullScreenByDragRef.current;\n const draggedOutOfFullScreen = exitedFullScreenByDragRef.current;\n\n enteredFullScreenByDragRef.current = false;\n exitedFullScreenByDragRef.current = false;\n\n if (!draggedIntoFullScreen || draggedOutOfFullScreen) return;\n\n setPanelHeight(\n clampHeight(getMaxHeight(panel) * WORKBENCH_PANEL_FULL_SCREEN_EXIT_RATIO, panel),\n );\n }, [state, panelRef, setPanelHeight]);\n\n const applyHeight = (height: number, panel: HTMLDivElement) => {\n const isFullScreen = isFullScreenRequestedRef.current;\n\n if (height >= getMaxHeight(panel)) {\n if (!isFullScreen) {\n isFullScreenRequestedRef.current = true;\n enteredFullScreenByDragRef.current = true;\n enterFullScreen();\n }\n\n return;\n }\n\n if (isFullScreen) {\n isFullScreenRequestedRef.current = false;\n exitedFullScreenByDragRef.current = true;\n exitFullScreen();\n }\n\n setPanelHeight(Math.max(height, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX));\n };\n\n const handlePointerDown = (event: PointerEvent<HTMLDivElement>) => {\n const panel = panelRef.current;\n\n if (event.button !== 0 || !panel) return;\n\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n grabOffsetRef.current = panel.getBoundingClientRect().top - event.clientY;\n setIsResizing(true);\n };\n\n const handlePointerMove = (event: PointerEvent<HTMLDivElement>) => {\n const panel = panelRef.current;\n\n if (!panel || !event.currentTarget.hasPointerCapture(event.pointerId)) return;\n\n const top = event.clientY + grabOffsetRef.current;\n\n applyHeight(panel.getBoundingClientRect().bottom - top, panel);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const panel = panelRef.current;\n\n if (!panel) return;\n\n const step = event.shiftKey\n ? WORKBENCH_PANEL_RESIZE_STEP_IN_PX * 4\n : WORKBENCH_PANEL_RESIZE_STEP_IN_PX;\n const delta = event.key === 'ArrowUp' ? step : event.key === 'ArrowDown' ? -step : 0;\n\n if (delta === 0) return;\n\n event.preventDefault();\n applyHeight(\n (isFullScreenRequestedRef.current ? getMaxHeight(panel) : panelHeight) + delta,\n panel,\n );\n };\n\n return (\n <div\n role=\"separator\"\n aria-orientation=\"horizontal\"\n aria-label=\"Resize panel\"\n aria-valuenow={Math.round(panelHeight)}\n aria-valuemin={MIN_WORKBENCH_PANEL_HEIGHT_IN_PX}\n tabIndex={0}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onLostPointerCapture={() => setIsResizing(false)}\n onKeyDown={handleKeyDown}\n className={cn(\n // group\n 'tw:group/workbench-resize',\n\n // positioning — the panel is the positioned ancestor\n 'tw:absolute',\n 'tw:inset-x-0',\n 'tw:top-0',\n 'tw:z-10',\n\n // sizing\n 'tw:h-2',\n\n // layout — the whole strip grabs, only the pill shows\n 'tw:flex',\n 'tw:justify-center',\n\n // affordance\n 'tw:cursor-ns-resize',\n 'tw:touch-none',\n\n // focus\n 'tw:outline-none',\n )}\n >\n <span\n className={cn(\n // layout — hangs below the strip so the pill sits clear of the top edge, and\n // grabs there too since the events bubble to the strip\n 'tw:flex',\n 'tw:h-3',\n 'tw:w-16',\n 'tw:items-end',\n 'tw:justify-center',\n )}\n >\n <span\n className={cn(\n // sizing\n 'tw:h-1.5',\n 'tw:w-16',\n\n // surface\n 'tw:rounded-full',\n 'tw:bg-input',\n 'tw:transition-colors',\n 'tw:group-hover/workbench-resize:bg-muted-foreground',\n 'tw:group-focus-visible/workbench-resize:bg-muted-foreground',\n 'tw:group-data-[workbench-resizing=true]/workbench:bg-muted-foreground',\n )}\n />\n </span>\n </div>\n );\n};\n","import { useEffect, useRef } from 'react';\nimport type { ComponentProps, CSSProperties } from 'react';\n\nimport { cn } from '../../../utils';\nimport { Collapsible } from '../../Collapsible';\n\nimport { WorkbenchPanelResizeHandle } from './WorkbenchPanelResizeHandle';\n\ntype Props = ComponentProps<'div'>;\n\nconst clearRadixMeasurementTransitionBlock = (panel: HTMLDivElement | null) => {\n if (panel) panel.style.transitionDuration = '';\n};\n\nexport const WorkbenchPanel = ({ className, children, ...props }: Props) => {\n const panelRef = useRef<HTMLDivElement>(null);\n\n useEffect(() => clearRadixMeasurementTransitionBlock(panelRef.current), []);\n\n return (\n <Collapsible.Content\n ref={panelRef}\n // See `WorkbenchBar` — the other half of the dock's measurable area.\n data-workbench-slot=\"panel\"\n style={{ '--workbench-panel-shadow': '0 -8px 24px -6px rgb(0 0 0 / 0.08)' } as CSSProperties}\n className={cn(\n // positioning — against the host, which must be a positioned element\n 'tw:absolute',\n 'tw:inset-x-0',\n 'tw:bottom-(--workbench-bar-height)',\n 'tw:pointer-events-auto',\n\n // height — the drag-controlled var, capped at the space above the bar so the panel\n // never covers it, whatever height was dragged or restored\n 'tw:h-(--workbench-panel-height)',\n 'tw:max-h-[calc(100%-var(--workbench-bar-height))]',\n 'tw:group-data-[workbench-state=full-screen]/workbench:h-[calc(100%-var(--workbench-bar-height))]',\n\n // height transition\n 'tw:transition-[height]',\n 'tw:duration-200',\n 'tw:ease-out',\n 'tw:group-data-[workbench-resizing=true]/workbench:transition-none',\n\n // surface\n 'tw:border-x',\n 'tw:border-t',\n 'tw:border-border',\n\n // clipping\n 'tw:overflow-hidden',\n\n // raised edge\n 'tw:group-not-data-[workbench-state=full-screen]/workbench:rounded-t-2xl',\n 'tw:group-not-data-[workbench-state=full-screen]/workbench:shadow-(--workbench-panel-shadow)',\n )}\n >\n <WorkbenchPanelResizeHandle panelRef={panelRef} />\n\n <div\n className={cn(\n // layout\n 'tw:flex',\n 'tw:flex-col',\n 'tw:h-full',\n\n // surface\n 'tw:bg-background',\n\n className,\n )}\n {...props}\n >\n {children}\n </div>\n </Collapsible.Content>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'> & {\n asChild?: boolean;\n};\n\nexport const WorkbenchPanelActions = ({ className, asChild = false, ...props }: Props) => {\n const Comp = asChild ? Slot : 'div';\n\n return (\n <Comp\n {...props}\n data-slot=\"workbench-panel-actions\"\n className={cn(\n // grid placement\n 'tw:col-start-2',\n 'tw:row-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n 'tw:gap-2',\n\n className,\n )}\n />\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchPanelContent = ({ className, children, ...props }: Props) => (\n <div\n className={cn(\n // layout\n 'tw:min-h-0',\n 'tw:flex-1',\n 'tw:overflow-auto',\n\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchPanelHeader = ({ className, children, ...props }: Props) => (\n <div\n className={cn(\n // layout\n 'tw:grid',\n 'tw:grid-cols-[1fr_auto]',\n 'tw:items-center',\n 'tw:gap-x-2',\n\n // sizing\n 'tw:shrink-0',\n\n // surface\n 'tw:bg-sidebar',\n\n // spacing\n 'tw:px-3',\n 'tw:py-2',\n\n // typography\n 'tw:text-xs',\n\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const WorkbenchPanelTitle = ({ className, ...props }: Props) => (\n <div\n {...props}\n data-slot=\"workbench-panel-title\"\n className={cn(\n // grid placement\n 'tw:col-start-1',\n\n // layout\n 'tw:flex',\n 'tw:items-center',\n\n // typography\n 'tw:text-sm',\n 'tw:font-semibold',\n 'tw:text-foreground',\n\n className,\n )}\n />\n);\n","import { useMemo, useState } from 'react';\nimport type { CSSProperties, ReactNode } from 'react';\n\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { cn } from '../../utils';\nimport { Collapsible } from '../Collapsible';\n\nimport {\n DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM,\n DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX,\n MIN_WORKBENCH_BAR_HEIGHT_IN_REM,\n MIN_WORKBENCH_PANEL_HEIGHT_IN_PX,\n} from './constants';\nimport type { WorkbenchState } from './context';\nimport { createWorkbenchActions, WorkbenchContext } from './context';\nimport {\n WorkbenchBar,\n WorkbenchBarEnd,\n WorkbenchBarMiddle,\n WorkbenchBarStart,\n} from './WorkbenchBar';\nimport { WorkbenchFullScreenTrigger } from './WorkbenchFullScreenTrigger';\nimport {\n WorkbenchPanel,\n WorkbenchPanelActions,\n WorkbenchPanelContent,\n WorkbenchPanelHeader,\n WorkbenchPanelTitle,\n} from './WorkbenchPanel';\n\ntype Props = {\n className?: string;\n children: ReactNode;\n state?: WorkbenchState;\n defaultState?: WorkbenchState;\n onStateChange?: (state: WorkbenchState) => void;\n barHeight?: number;\n panelHeight?: number;\n defaultPanelHeight?: number;\n onPanelHeightChange?: (panelHeight: number) => void;\n};\n\nexport const Workbench = ({\n className,\n children,\n state: stateProp,\n defaultState = 'collapsed',\n onStateChange,\n barHeight = DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM,\n panelHeight: panelHeightProp,\n defaultPanelHeight = DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX,\n onPanelHeightChange,\n}: Props) => {\n const [state, setState] = useControllableState<WorkbenchState>({\n prop: stateProp,\n defaultProp: defaultState,\n onChange: onStateChange,\n });\n const [panelHeight, setPanelHeight] = useControllableState<number>({\n prop: panelHeightProp,\n defaultProp: defaultPanelHeight,\n onChange: onPanelHeightChange,\n });\n const [isResizing, setIsResizing] = useState(false);\n\n const actions = useMemo(() => createWorkbenchActions(setState), [setState]);\n const value = useMemo(\n () => ({\n state,\n setState,\n panelHeight,\n setPanelHeight,\n isResizing,\n setIsResizing,\n ...actions,\n }),\n [state, setState, panelHeight, setPanelHeight, isResizing, actions],\n );\n\n const clampedBarHeight = Math.max(barHeight, MIN_WORKBENCH_BAR_HEIGHT_IN_REM);\n const clampedPanelHeight = Math.max(panelHeight, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX);\n\n return (\n <WorkbenchContext value={value}>\n <Collapsible\n open={state !== 'collapsed'}\n onOpenChange={(open) => setState(open ? 'expanded' : 'collapsed')}\n data-workbench-state={state}\n data-workbench-resizing={isResizing ? 'true' : undefined}\n style={\n {\n '--workbench-bar-height': `${clampedBarHeight}rem`,\n '--workbench-panel-height': `${clampedPanelHeight}px`,\n } as CSSProperties\n }\n className={cn(\n // reset\n 'tailwindcss-preflight',\n\n // group\n 'tw:group/workbench',\n\n // positioning — above the chrome layer (`z-50`) *and* above a `Sidebar` in\n // `expand-on-hover`, which takes `z-51` to float over content; the dock outranks both.\n // Overlays (Modal / Sheet / Popover / Tooltip) live on `z-overlay` and above, so they still win.\n 'tw:z-[52]',\n\n // layout\n 'tw:shrink-0',\n\n className,\n )}\n >\n {children}\n </Collapsible>\n </WorkbenchContext>\n );\n};\n\nWorkbench.Bar = WorkbenchBar;\nWorkbench.BarStart = WorkbenchBarStart;\nWorkbench.BarMiddle = WorkbenchBarMiddle;\nWorkbench.BarEnd = WorkbenchBarEnd;\n\nWorkbench.Panel = WorkbenchPanel;\nWorkbench.PanelHeader = WorkbenchPanelHeader;\nWorkbench.PanelTitle = WorkbenchPanelTitle;\nWorkbench.PanelActions = WorkbenchPanelActions;\nWorkbench.PanelContent = WorkbenchPanelContent;\n\nWorkbench.Trigger = Collapsible.Trigger;\nWorkbench.FullScreenTrigger = WorkbenchFullScreenTrigger;\n"],"mappings":"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"}
@@ -1,13 +1,13 @@
1
- import { cn } from "./classNames-DcGnTh2N.js";
2
- import { Tooltip } from "./utils-DwC9u0tM.js";
3
- import { Maximize2, Minimize2 } from "./icons-ZIeZXXS7.js";
4
- import { Button } from "./Button-BNkyYU8u.js";
5
- import { ClipboardButton } from "./ClipboardButton-B1Hr_n_Z.js";
1
+ import { cn } from "./classNames-DkX30VJU.js";
2
+ import { Tooltip } from "./utils-DjFceY3H.js";
3
+ import { Maximize2, Minimize2 } from "./icons-DDR9dFSr.js";
4
+ import { Button } from "./Button-DbvGzEDb.js";
5
+ import { ClipboardButton } from "./ClipboardButton-71Ugbl8c.js";
6
6
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { createPortal } from "react-dom";
9
9
  import DOMPurify from "dompurify";
10
- //#region src/components/ZoomableSvg/exportSvg.ts
10
+ // src/components/ZoomableSvg/exportSvg.ts
11
11
  const PNG_SCALE = 2;
12
12
  const ROOT_SVG_TAG = /^<svg\b[^>]*>/i;
13
13
  const HAS_DEFAULT_NAMESPACE = /\bxmlns\s*=/i;
@@ -80,8 +80,7 @@ const svgToPngBlob = async (svg, background) => {
80
80
  canvas.toBlob((blob) => blob ? resolve(blob) : reject(/* @__PURE__ */ new Error("Failed to encode the PNG.")), "image/png");
81
81
  });
82
82
  };
83
- //#endregion
84
- //#region src/components/ZoomableSvg/ZoomableSvg.tsx
83
+ // src/components/ZoomableSvg/ZoomableSvg.tsx
85
84
  const MIN_SCALE = .5;
86
85
  const MAX_SCALE = 3;
87
86
  const ZOOM_STEP = .1;
@@ -223,7 +222,7 @@ const ZoomableSvg = ({ html, copyText, className, allowForeignObject, allowUse,
223
222
  if (isFullscreen) return createPortal(/* @__PURE__ */ jsx("div", {
224
223
  role: "presentation",
225
224
  "data-testid": "zoomable-svg-fullscreen",
226
- className: "tw:fixed tw:inset-0 tw:z-[1051] tw:bg-muted tw:p-4 tailwindcss-preflight",
225
+ className: "tw:fixed tw:inset-0 tw:z-overlay tw:bg-muted tw:p-4 tailwindcss-preflight",
227
226
  onClick: stopPropagation,
228
227
  children: diagramContent
229
228
  }), document.body);
@@ -232,7 +231,6 @@ const ZoomableSvg = ({ html, copyText, className, allowForeignObject, allowUse,
232
231
  children: diagramContent
233
232
  });
234
233
  };
235
- //#endregion
236
234
  export { ZoomableSvg, svgToPngBlob, toSvgFileContent };
237
235
 
238
- //# sourceMappingURL=ZoomableSvg-DnFXo2L4.js.map
236
+ //# sourceMappingURL=ZoomableSvg-BRPGgaWJ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ZoomableSvg-DnFXo2L4.js","names":[],"sources":["../src/components/ZoomableSvg/exportSvg.ts","../src/components/ZoomableSvg/ZoomableSvg.tsx"],"sourcesContent":["const PNG_SCALE = 2;\n\n// The root `<svg …>` tag, so the namespace check looks only at its attributes.\n// A plain `includes('xmlns=')` would also match a nested element or body text,\n// and would miss `xmlns = \"…\"` — adding a second declaration, which parsers\n// reject outright with \"Attribute xmlns redefined\".\nconst ROOT_SVG_TAG = /^<svg\\b[^>]*>/i;\nconst HAS_DEFAULT_NAMESPACE = /\\bxmlns\\s*=/i;\n\n// A standalone SVG file needs the namespace declaration; inline diagram output may\n// omit it because an inline <svg> inherits it from the host document.\n// Trim before matching: the anchored `^<svg` misses markup that arrives with a\n// leading newline or indentation, which would emit a standalone file with no\n// namespace — unopenable in an image viewer.\nconst withSvgNamespace = (svg: string) => {\n const trimmed = svg.trim();\n const rootTag = trimmed.match(ROOT_SVG_TAG)?.[0];\n\n if (!rootTag || HAS_DEFAULT_NAMESPACE.test(rootTag)) return trimmed;\n\n return trimmed.replace(/^<svg\\b/i, '<svg xmlns=\"http://www.w3.org/2000/svg\"');\n};\n\nexport const toSvgFileContent = (svg: string) =>\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n${withSvgNamespace(svg).trim()}\\n`;\n\n// A single decimal number: `12`, `12.5`, `.5`. Deliberately stricter than\n// `[\\d.]+`, which also matches `1.2.3` — and `parseFloat` truncates that to\n// `1.2` rather than rejecting it, so a malformed value would pass as a plausible\n// one.\nconst NUMBER = String.raw`\\d+(?:\\.\\d+)?|\\.\\d+`;\n\n// `parseFloat` happily reads a relative length as a number — `\"100%\"` becomes\n// `100`, `\"2em\"` becomes `2` — and `makeResponsive` sets `width=\"100%\"` on every\n// diagram root, so an SVG with no usable viewBox would rasterize 100px wide with\n// no error. Accept only a unitless number or an explicit `px`.\nconst PIXEL_LENGTH = new RegExp(String.raw`^\\s*(?:${NUMBER})(?:px)?\\s*$`, 'i');\n\nconst parsePixelLength = (value: string | null): number | null => {\n if (!PIXEL_LENGTH.test(value ?? '')) return null;\n\n const parsed = Number.parseFloat(value ?? '');\n\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n};\n\nexport const parseSvgSize = (svg: string) => {\n const doc = new DOMParser().parseFromString(withSvgNamespace(svg), 'image/svg+xml');\n const element = doc.documentElement;\n\n const viewBox = element\n .getAttribute('viewBox')\n ?.split(/[\\s,]+/)\n .map(Number);\n // `> 0`, not truthiness: a negative extent is accepted by a truthy check, and\n // negative canvas dimensions silently fall back to the 300x150 default — an\n // export at the wrong size with no error. Falling through to width/height is\n // the better answer, since those are usually still valid.\n if (viewBox?.length === 4 && viewBox.every((value) => Number.isFinite(value))) {\n const [, , width, height] = viewBox;\n if (width !== undefined && height !== undefined && width > 0 && height > 0) {\n return { width, height };\n }\n }\n\n const width = parsePixelLength(element.getAttribute('width'));\n const height = parsePixelLength(element.getAttribute('height'));\n\n return width !== null && height !== null ? { width, height } : null;\n};\n\n// Resolve the themed page background so the exported PNG follows the active\n// brand and color scheme instead of a frozen literal. Falls back to `white`\n// (a CSS keyword, not a brand-locked hex) when the token is unset.\n//\n// The token holds Tailwind's bare channel triplet (\"249 250 251\") so utilities\n// can add an alpha. Canvas `fillStyle` rejects that form *silently* and keeps\n// its previous value (black), so wrap it back into rgb() before use.\nconst CHANNEL_TRIPLET = new RegExp(String.raw`^(?:${NUMBER})\\s+(?:${NUMBER})\\s+(?:${NUMBER})$`);\n\nexport const toCanvasColor = (token: string) => {\n const trimmed = token.trim();\n if (!trimmed) return 'white';\n\n // Only wrap a well-formed triplet. A malformed one (`1.2.3 4 5`) would produce\n // an invalid `rgb()` that `fillStyle` rejects silently, painting the PNG on\n // whatever colour was set before — passing it through unwrapped at least lets\n // a genuine CSS color value work.\n return CHANNEL_TRIPLET.test(trimmed) ? `rgb(${trimmed})` : trimmed;\n};\n\nconst resolveBackground = () =>\n toCanvasColor(getComputedStyle(document.documentElement).getPropertyValue('--color-background'));\n\n/**\n * Rasterize SVG markup to a PNG blob at 2x for legible text.\n *\n * The SVG is loaded as a data URL rather than a blob URL: an <img> loading SVG\n * is treated as a foreign resource, so a blob URL would taint the canvas and\n * make toBlob throw a SecurityError. A background is painted first because a\n * transparent PNG reads as unusable when pasted into a slide deck.\n */\nexport const svgToPngBlob = async (svg: string, background?: string): Promise<Blob> => {\n const size = parseSvgSize(svg);\n if (!size) throw new Error('Cannot determine diagram dimensions.');\n\n const encoded = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(toSvgFileContent(svg))}`;\n\n const image = new Image();\n image.decoding = 'sync';\n await new Promise<void>((resolve, reject) => {\n image.onload = () => resolve();\n image.onerror = () => reject(new Error('Failed to load the diagram for export.'));\n image.src = encoded;\n });\n\n const canvas = document.createElement('canvas');\n canvas.width = Math.round(size.width * PNG_SCALE);\n canvas.height = Math.round(size.height * PNG_SCALE);\n\n const context = canvas.getContext('2d');\n if (!context) throw new Error('Canvas is unavailable in this browser.');\n\n context.fillStyle = background ?? resolveBackground();\n context.fillRect(0, 0, canvas.width, canvas.height);\n context.drawImage(image, 0, 0, canvas.width, canvas.height);\n\n return new Promise<Blob>((resolve, reject) => {\n canvas.toBlob(\n (blob) => (blob ? resolve(blob) : reject(new Error('Failed to encode the PNG.'))),\n 'image/png',\n );\n });\n};\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport DOMPurify from 'dompurify';\n\nimport { ClipboardButton } from '../../blocks/ClipboardButton';\nimport { Maximize2, Minimize2 } from '../../icons';\nimport { cn } from '../../utils';\nimport { Button } from '../Button';\nimport { Tooltip } from '../Tooltip';\n\nconst MIN_SCALE = 0.5;\nconst MAX_SCALE = 3;\nconst ZOOM_STEP = 0.1;\n\ntype Props = {\n /** Raw SVG markup; DOMPurify-sanitized (SVG profile), so user/LLM content is safe. */\n html: string;\n copyText?: string;\n className?: string;\n /** Keep `<foreignObject>` through sanitization; its HTML children are still stripped.\n * Enable only when each one is pre-flattened to bare text. */\n allowForeignObject?: boolean;\n /** Keep `<use>` through sanitization. Enable only when every `href` is already a `#` reference. */\n allowUse?: boolean;\n /** Extra toolbar controls (e.g. `ExportMenu`) between copy and fullscreen; receives the\n * sanitized SVG. Injected so this lazy chunk carries no export dependencies. */\n renderActions?: (safeSvg: string) => ReactNode;\n};\n\nexport const ZoomableSvg = ({\n html,\n copyText,\n className,\n allowForeignObject,\n allowUse,\n renderActions,\n}: Props) => {\n const safeHtml = useMemo(\n () =>\n DOMPurify.sanitize(html, {\n USE_PROFILES: { svg: true, svgFilters: true },\n ADD_TAGS: [...(allowForeignObject ? ['foreignObject'] : []), ...(allowUse ? ['use'] : [])],\n }),\n [html, allowForeignObject, allowUse],\n );\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [scale, setScale] = useState(1);\n const [translate, setTranslate] = useState({ x: 0, y: 0 });\n const [isFullscreen, setIsFullscreen] = useState(false);\n\n useEffect(() => {\n if (!isFullscreen) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n setIsFullscreen(false);\n }\n };\n document.addEventListener('keydown', onKeyDown, { capture: true });\n return () => document.removeEventListener('keydown', onKeyDown, { capture: true });\n }, [isFullscreen]);\n\n const dragRef = useRef<{\n startX: number;\n startY: number;\n startTx: number;\n startTy: number;\n } | null>(null);\n\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n const onWheel = (e: WheelEvent) => {\n if (!e.ctrlKey && !e.metaKey) return;\n e.preventDefault();\n const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP;\n setScale((s) => Math.min(MAX_SCALE, Math.max(MIN_SCALE, s + delta)));\n };\n\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n // Re-bind when toggling fullscreen: the portal/inline switch remounts the\n // container element, so the listener must attach to the new node.\n }, [isFullscreen]);\n\n const didDragRef = useRef(false);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (e.button !== 0) return;\n e.preventDefault();\n didDragRef.current = false;\n dragRef.current = {\n startX: e.clientX,\n startY: e.clientY,\n startTx: translate.x,\n startTy: translate.y,\n };\n },\n [translate],\n );\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!dragRef.current) return;\n didDragRef.current = true;\n setTranslate({\n x: dragRef.current.startTx + e.clientX - dragRef.current.startX,\n y: dragRef.current.startTy + e.clientY - dragRef.current.startY,\n });\n }, []);\n\n const handleMouseUp = useCallback(() => {\n dragRef.current = null;\n }, []);\n\n const handleReset = useCallback(() => {\n setScale(1);\n setTranslate({ x: 0, y: 0 });\n }, []);\n\n const isZoomed = Math.abs(scale - 1) > 0.001 || translate.x !== 0 || translate.y !== 0;\n\n const handleClick = useCallback((e: React.MouseEvent) => {\n if (didDragRef.current) {\n e.stopPropagation();\n }\n }, []);\n\n const stopPropagation = useCallback((e: React.SyntheticEvent) => {\n e.stopPropagation();\n }, []);\n\n const diagramContent = (\n <div\n role=\"presentation\"\n className={cn('tw:group/zoom tw:relative', isFullscreen && 'tw:h-full')}\n onClick={handleClick}\n >\n <div\n role=\"presentation\"\n ref={containerRef}\n className={cn(\n 'tw:overflow-hidden tw:cursor-grab tw:active:cursor-grabbing tw:p-3',\n isFullscreen && 'tw:h-full',\n )}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n >\n <div\n className={cn(\n 'tw:flex tw:justify-center tw:origin-center',\n isFullscreen && 'tw:h-full tw:[&>svg]:h-full',\n )}\n style={{ transform: `translate(${translate.x}px, ${translate.y}px) scale(${scale})` }}\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n </div>\n <div\n role=\"presentation\"\n // `focus-within` too: the opacity-0 toolbar is still in the tab order.\n className=\"tw:absolute tw:right-1 tw:top-1 tw:flex tw:gap-1 tw:opacity-0 tw:transition-opacity tw:focus-within:opacity-100 tw:group-hover/zoom:opacity-100\"\n onClick={stopPropagation}\n >\n {isZoomed && (\n <Tooltip tooltip=\"Reset zoom\" placement=\"top\" triggerAsChild>\n <Button size=\"small\" variant=\"outline\" onClick={handleReset}>\n Reset\n </Button>\n </Tooltip>\n )}\n {copyText && (\n <ClipboardButton text={copyText} tooltip=\"Copy code\" size=\"icon-sm\" variant=\"outline\" />\n )}\n {renderActions?.(safeHtml)}\n <Tooltip\n tooltip={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}\n placement=\"top\"\n triggerAsChild\n >\n <Button\n size=\"icon-sm\"\n variant=\"outline\"\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}\n onClick={() => setIsFullscreen((f) => !f)}\n >\n {isFullscreen ? (\n <Minimize2 className=\"tw:size-4\" />\n ) : (\n <Maximize2 className=\"tw:size-4\" />\n )}\n </Button>\n </Tooltip>\n </div>\n </div>\n );\n\n if (isFullscreen) {\n return createPortal(\n <div\n role=\"presentation\"\n data-testid=\"zoomable-svg-fullscreen\"\n // z-1051 (Modal band): must stay below floating panels (z-1055) or toolbar menus hide.\n // Tooltip (z-1060) and SpotlightBackdrop (z-1056) sit above it by design.\n className=\"tw:fixed tw:inset-0 tw:z-[1051] tw:bg-muted tw:p-4 tailwindcss-preflight\"\n onClick={stopPropagation}\n >\n {diagramContent}\n </div>,\n document.body,\n );\n }\n\n return (\n <div\n className={cn(\n 'tw:overflow-hidden tw:rounded-md tw:border tw:border-border tw:bg-muted',\n className,\n )}\n >\n {diagramContent}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ZoomableSvg-BRPGgaWJ.js","names":[],"sources":["../src/components/ZoomableSvg/exportSvg.ts","../src/components/ZoomableSvg/ZoomableSvg.tsx"],"sourcesContent":["const PNG_SCALE = 2;\n\n// The root `<svg …>` tag, so the namespace check looks only at its attributes.\n// A plain `includes('xmlns=')` would also match a nested element or body text,\n// and would miss `xmlns = \"…\"` — adding a second declaration, which parsers\n// reject outright with \"Attribute xmlns redefined\".\nconst ROOT_SVG_TAG = /^<svg\\b[^>]*>/i;\nconst HAS_DEFAULT_NAMESPACE = /\\bxmlns\\s*=/i;\n\n// A standalone SVG file needs the namespace declaration; inline diagram output may\n// omit it because an inline <svg> inherits it from the host document.\n// Trim before matching: the anchored `^<svg` misses markup that arrives with a\n// leading newline or indentation, which would emit a standalone file with no\n// namespace — unopenable in an image viewer.\nconst withSvgNamespace = (svg: string) => {\n const trimmed = svg.trim();\n const rootTag = trimmed.match(ROOT_SVG_TAG)?.[0];\n\n if (!rootTag || HAS_DEFAULT_NAMESPACE.test(rootTag)) return trimmed;\n\n return trimmed.replace(/^<svg\\b/i, '<svg xmlns=\"http://www.w3.org/2000/svg\"');\n};\n\nexport const toSvgFileContent = (svg: string) =>\n `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n${withSvgNamespace(svg).trim()}\\n`;\n\n// A single decimal number: `12`, `12.5`, `.5`. Deliberately stricter than\n// `[\\d.]+`, which also matches `1.2.3` — and `parseFloat` truncates that to\n// `1.2` rather than rejecting it, so a malformed value would pass as a plausible\n// one.\nconst NUMBER = String.raw`\\d+(?:\\.\\d+)?|\\.\\d+`;\n\n// `parseFloat` happily reads a relative length as a number — `\"100%\"` becomes\n// `100`, `\"2em\"` becomes `2` — and `makeResponsive` sets `width=\"100%\"` on every\n// diagram root, so an SVG with no usable viewBox would rasterize 100px wide with\n// no error. Accept only a unitless number or an explicit `px`.\nconst PIXEL_LENGTH = new RegExp(String.raw`^\\s*(?:${NUMBER})(?:px)?\\s*$`, 'i');\n\nconst parsePixelLength = (value: string | null): number | null => {\n if (!PIXEL_LENGTH.test(value ?? '')) return null;\n\n const parsed = Number.parseFloat(value ?? '');\n\n return Number.isFinite(parsed) && parsed > 0 ? parsed : null;\n};\n\nexport const parseSvgSize = (svg: string) => {\n const doc = new DOMParser().parseFromString(withSvgNamespace(svg), 'image/svg+xml');\n const element = doc.documentElement;\n\n const viewBox = element\n .getAttribute('viewBox')\n ?.split(/[\\s,]+/)\n .map(Number);\n // `> 0`, not truthiness: a negative extent is accepted by a truthy check, and\n // negative canvas dimensions silently fall back to the 300x150 default — an\n // export at the wrong size with no error. Falling through to width/height is\n // the better answer, since those are usually still valid.\n if (viewBox?.length === 4 && viewBox.every((value) => Number.isFinite(value))) {\n const [, , width, height] = viewBox;\n if (width !== undefined && height !== undefined && width > 0 && height > 0) {\n return { width, height };\n }\n }\n\n const width = parsePixelLength(element.getAttribute('width'));\n const height = parsePixelLength(element.getAttribute('height'));\n\n return width !== null && height !== null ? { width, height } : null;\n};\n\n// Resolve the themed page background so the exported PNG follows the active\n// brand and color scheme instead of a frozen literal. Falls back to `white`\n// (a CSS keyword, not a brand-locked hex) when the token is unset.\n//\n// The token holds Tailwind's bare channel triplet (\"249 250 251\") so utilities\n// can add an alpha. Canvas `fillStyle` rejects that form *silently* and keeps\n// its previous value (black), so wrap it back into rgb() before use.\nconst CHANNEL_TRIPLET = new RegExp(String.raw`^(?:${NUMBER})\\s+(?:${NUMBER})\\s+(?:${NUMBER})$`);\n\nexport const toCanvasColor = (token: string) => {\n const trimmed = token.trim();\n if (!trimmed) return 'white';\n\n // Only wrap a well-formed triplet. A malformed one (`1.2.3 4 5`) would produce\n // an invalid `rgb()` that `fillStyle` rejects silently, painting the PNG on\n // whatever colour was set before — passing it through unwrapped at least lets\n // a genuine CSS color value work.\n return CHANNEL_TRIPLET.test(trimmed) ? `rgb(${trimmed})` : trimmed;\n};\n\nconst resolveBackground = () =>\n toCanvasColor(getComputedStyle(document.documentElement).getPropertyValue('--color-background'));\n\n/**\n * Rasterize SVG markup to a PNG blob at 2x for legible text.\n *\n * The SVG is loaded as a data URL rather than a blob URL: an <img> loading SVG\n * is treated as a foreign resource, so a blob URL would taint the canvas and\n * make toBlob throw a SecurityError. A background is painted first because a\n * transparent PNG reads as unusable when pasted into a slide deck.\n */\nexport const svgToPngBlob = async (svg: string, background?: string): Promise<Blob> => {\n const size = parseSvgSize(svg);\n if (!size) throw new Error('Cannot determine diagram dimensions.');\n\n const encoded = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(toSvgFileContent(svg))}`;\n\n const image = new Image();\n image.decoding = 'sync';\n await new Promise<void>((resolve, reject) => {\n image.onload = () => resolve();\n image.onerror = () => reject(new Error('Failed to load the diagram for export.'));\n image.src = encoded;\n });\n\n const canvas = document.createElement('canvas');\n canvas.width = Math.round(size.width * PNG_SCALE);\n canvas.height = Math.round(size.height * PNG_SCALE);\n\n const context = canvas.getContext('2d');\n if (!context) throw new Error('Canvas is unavailable in this browser.');\n\n context.fillStyle = background ?? resolveBackground();\n context.fillRect(0, 0, canvas.width, canvas.height);\n context.drawImage(image, 0, 0, canvas.width, canvas.height);\n\n return new Promise<Blob>((resolve, reject) => {\n canvas.toBlob(\n (blob) => (blob ? resolve(blob) : reject(new Error('Failed to encode the PNG.'))),\n 'image/png',\n );\n });\n};\n","import { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport { createPortal } from 'react-dom';\nimport DOMPurify from 'dompurify';\n\nimport { ClipboardButton } from '../../blocks/ClipboardButton';\nimport { Maximize2, Minimize2 } from '../../icons';\nimport { cn } from '../../utils';\nimport { Button } from '../Button';\nimport { Tooltip } from '../Tooltip';\n\nconst MIN_SCALE = 0.5;\nconst MAX_SCALE = 3;\nconst ZOOM_STEP = 0.1;\n\ntype Props = {\n /** Raw SVG markup; DOMPurify-sanitized (SVG profile), so user/LLM content is safe. */\n html: string;\n copyText?: string;\n className?: string;\n /** Keep `<foreignObject>` through sanitization; its HTML children are still stripped.\n * Enable only when each one is pre-flattened to bare text. */\n allowForeignObject?: boolean;\n /** Keep `<use>` through sanitization. Enable only when every `href` is already a `#` reference. */\n allowUse?: boolean;\n /** Extra toolbar controls (e.g. `ExportMenu`) between copy and fullscreen; receives the\n * sanitized SVG. Injected so this lazy chunk carries no export dependencies. */\n renderActions?: (safeSvg: string) => ReactNode;\n};\n\nexport const ZoomableSvg = ({\n html,\n copyText,\n className,\n allowForeignObject,\n allowUse,\n renderActions,\n}: Props) => {\n const safeHtml = useMemo(\n () =>\n DOMPurify.sanitize(html, {\n USE_PROFILES: { svg: true, svgFilters: true },\n ADD_TAGS: [...(allowForeignObject ? ['foreignObject'] : []), ...(allowUse ? ['use'] : [])],\n }),\n [html, allowForeignObject, allowUse],\n );\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [scale, setScale] = useState(1);\n const [translate, setTranslate] = useState({ x: 0, y: 0 });\n const [isFullscreen, setIsFullscreen] = useState(false);\n\n useEffect(() => {\n if (!isFullscreen) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Escape') {\n e.stopPropagation();\n setIsFullscreen(false);\n }\n };\n document.addEventListener('keydown', onKeyDown, { capture: true });\n return () => document.removeEventListener('keydown', onKeyDown, { capture: true });\n }, [isFullscreen]);\n\n const dragRef = useRef<{\n startX: number;\n startY: number;\n startTx: number;\n startTy: number;\n } | null>(null);\n\n useEffect(() => {\n const el = containerRef.current;\n if (!el) return;\n\n const onWheel = (e: WheelEvent) => {\n if (!e.ctrlKey && !e.metaKey) return;\n e.preventDefault();\n const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP;\n setScale((s) => Math.min(MAX_SCALE, Math.max(MIN_SCALE, s + delta)));\n };\n\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n // Re-bind when toggling fullscreen: the portal/inline switch remounts the\n // container element, so the listener must attach to the new node.\n }, [isFullscreen]);\n\n const didDragRef = useRef(false);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n if (e.button !== 0) return;\n e.preventDefault();\n didDragRef.current = false;\n dragRef.current = {\n startX: e.clientX,\n startY: e.clientY,\n startTx: translate.x,\n startTy: translate.y,\n };\n },\n [translate],\n );\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!dragRef.current) return;\n didDragRef.current = true;\n setTranslate({\n x: dragRef.current.startTx + e.clientX - dragRef.current.startX,\n y: dragRef.current.startTy + e.clientY - dragRef.current.startY,\n });\n }, []);\n\n const handleMouseUp = useCallback(() => {\n dragRef.current = null;\n }, []);\n\n const handleReset = useCallback(() => {\n setScale(1);\n setTranslate({ x: 0, y: 0 });\n }, []);\n\n const isZoomed = Math.abs(scale - 1) > 0.001 || translate.x !== 0 || translate.y !== 0;\n\n const handleClick = useCallback((e: React.MouseEvent) => {\n if (didDragRef.current) {\n e.stopPropagation();\n }\n }, []);\n\n const stopPropagation = useCallback((e: React.SyntheticEvent) => {\n e.stopPropagation();\n }, []);\n\n const diagramContent = (\n <div\n role=\"presentation\"\n className={cn('tw:group/zoom tw:relative', isFullscreen && 'tw:h-full')}\n onClick={handleClick}\n >\n <div\n role=\"presentation\"\n ref={containerRef}\n className={cn(\n 'tw:overflow-hidden tw:cursor-grab tw:active:cursor-grabbing tw:p-3',\n isFullscreen && 'tw:h-full',\n )}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n >\n <div\n className={cn(\n 'tw:flex tw:justify-center tw:origin-center',\n isFullscreen && 'tw:h-full tw:[&>svg]:h-full',\n )}\n style={{ transform: `translate(${translate.x}px, ${translate.y}px) scale(${scale})` }}\n dangerouslySetInnerHTML={{ __html: safeHtml }}\n />\n </div>\n <div\n role=\"presentation\"\n // `focus-within` too: the opacity-0 toolbar is still in the tab order.\n className=\"tw:absolute tw:right-1 tw:top-1 tw:flex tw:gap-1 tw:opacity-0 tw:transition-opacity tw:focus-within:opacity-100 tw:group-hover/zoom:opacity-100\"\n onClick={stopPropagation}\n >\n {isZoomed && (\n <Tooltip tooltip=\"Reset zoom\" placement=\"top\" triggerAsChild>\n <Button size=\"small\" variant=\"outline\" onClick={handleReset}>\n Reset\n </Button>\n </Tooltip>\n )}\n {copyText && (\n <ClipboardButton text={copyText} tooltip=\"Copy code\" size=\"icon-sm\" variant=\"outline\" />\n )}\n {renderActions?.(safeHtml)}\n <Tooltip\n tooltip={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}\n placement=\"top\"\n triggerAsChild\n >\n <Button\n size=\"icon-sm\"\n variant=\"outline\"\n aria-label={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'}\n onClick={() => setIsFullscreen((f) => !f)}\n >\n {isFullscreen ? (\n <Minimize2 className=\"tw:size-4\" />\n ) : (\n <Maximize2 className=\"tw:size-4\" />\n )}\n </Button>\n </Tooltip>\n </div>\n </div>\n );\n\n if (isFullscreen) {\n return createPortal(\n <div\n role=\"presentation\"\n data-testid=\"zoomable-svg-fullscreen\"\n // `z-overlay`: a toolbar menu opened later paints over it.\n // Tooltip (z-1060) and SpotlightBackdrop (z-1056) sit above it by design.\n className=\"tw:fixed tw:inset-0 tw:z-overlay tw:bg-muted tw:p-4 tailwindcss-preflight\"\n onClick={stopPropagation}\n >\n {diagramContent}\n </div>,\n document.body,\n );\n }\n\n return (\n <div\n className={cn(\n 'tw:overflow-hidden tw:rounded-md tw:border tw:border-border tw:bg-muted',\n className,\n )}\n >\n {diagramContent}\n </div>\n );\n};\n"],"mappings":"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"}
package/dist/charts.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { ComponentProps, ReactElement } from "react";
2
2
  import { Tooltip } from "recharts";
3
- //#region src/blocks/Charts/ChartContainer.d.ts
4
3
  /** A length that recharts' `<ResponsiveContainer>` accepts: px number or `"NN%"`. */
5
4
  type ChartDimension = number | `${number}%`;
6
5
  type ChartContainerProps = Omit<ComponentProps<'div'>, 'children'> & {
@@ -13,8 +12,6 @@ type ChartContainerProps = Omit<ComponentProps<'div'>, 'children'> & {
13
12
  };
14
13
  /** Responsive frame that themes the chart's axis, grid and cursor with semantic tokens via CSS. */
15
14
  declare const ChartContainer: ({ height, width, className, children, ...props }: ChartContainerProps) => import("react").JSX.Element;
16
- //#endregion
17
- //#region src/blocks/Charts/ChartTooltip.d.ts
18
15
  type TooltipPayloadEntry = {
19
16
  name?: string | number;
20
17
  value?: string | number;
@@ -43,14 +40,10 @@ type ChartTooltipProps = ComponentProps<typeof Tooltip> & {
43
40
  * Each chart mounts one by default; pass `showTooltip={false}` on the chart to omit.
44
41
  */
45
42
  declare const ChartTooltip: ({ valueFormatter, ...props }: ChartTooltipProps) => import("react").JSX.Element;
46
- //#endregion
47
- //#region src/blocks/Charts/theme.d.ts
48
43
  /** Number of the semantic chart token (`1`–`5`) a series maps to. */
49
44
  type ChartColorToken = 1 | 2 | 3 | 4 | 5;
50
45
  /** The CSS color for a 0-based series `index`, wrapping around the palette. */
51
46
  declare const chartTokenColor: (index: number) => string;
52
- //#endregion
53
- //#region src/blocks/Charts/types.d.ts
54
47
  /** A single row of chart data — an object keyed by the axis + series keys. */
55
48
  type ChartDatum = Record<string, string | number | null | undefined>;
56
49
  /**
@@ -106,8 +99,6 @@ type CartesianChartProps = {
106
99
  valueFormatter?: (value: number) => string;
107
100
  className?: string;
108
101
  };
109
- //#endregion
110
- //#region src/blocks/Charts/LineChart.d.ts
111
102
  type LineChartProps = CartesianChartProps & {
112
103
  /**
113
104
  * Y-axis `[min, max]`; defaults to a zero baseline. Line-only: a truncated baseline misstates
@@ -122,8 +113,6 @@ type LineChartProps = CartesianChartProps & {
122
113
  * - Mounts its own {@link ChartContainer}.
123
114
  */
124
115
  declare const LineChart: ({ data, xKey, series, height, width, className, ...chrome }: LineChartProps) => import("react").JSX.Element;
125
- //#endregion
126
- //#region src/blocks/Charts/BarChart.d.ts
127
116
  type BarChartProps = CartesianChartProps & {
128
117
  /** Stack the series into a single bar per category. Defaults to grouped. */
129
118
  stacked?: boolean;
@@ -138,8 +127,6 @@ type BarChartProps = CartesianChartProps & {
138
127
  * <BarChart data={data} xKey="month" series={[{ dataKey: 'revenue' }]} />
139
128
  */
140
129
  declare const BarChart: ({ data, xKey, series, height, width, className, stacked, ...chrome }: BarChartProps) => import("react").JSX.Element;
141
- //#endregion
142
- //#region src/blocks/Charts/AreaChart.d.ts
143
130
  type AreaChartProps = CartesianChartProps & {
144
131
  /** Stack the series into a cumulative area. Defaults to overlaid. */
145
132
  stacked?: boolean;
@@ -154,8 +141,6 @@ type AreaChartProps = CartesianChartProps & {
154
141
  * <AreaChart data={data} xKey="month" series={[{ dataKey: 'revenue' }]} />
155
142
  */
156
143
  declare const AreaChart: ({ data, xKey, series, height, width, className, stacked, ...chrome }: AreaChartProps) => import("react").JSX.Element;
157
- //#endregion
158
- //#region src/blocks/Charts/PieChart.d.ts
159
144
  type PieChartProps = {
160
145
  /** The rows to plot — one sector per row. */
161
146
  data: ChartDatum[];
@@ -187,6 +172,5 @@ type PieChartProps = {
187
172
  * <PieChart data={data} nameKey="engine" dataKey="rows" innerRadius="60%" />
188
173
  */
189
174
  declare const PieChart: ({ data, nameKey, dataKey, innerRadius, height, width, className, showLegend, showTooltip, valueFormatter }: PieChartProps) => import("react").JSX.Element;
190
- //#endregion
191
175
  export { AreaChart, type AreaChartProps, BarChart, type BarChartProps, type CartesianChartProps, type ChartAxisDomain, type ChartAxisLowerBound, type ChartAxisUpperBound, type ChartColorToken, ChartContainer, type ChartContainerProps, type ChartDatum, type ChartDimension, type ChartSeries, ChartTooltip, ChartTooltipContent, type ChartTooltipProps, LineChart, type LineChartProps, PieChart, type PieChartProps, chartTokenColor };
192
176
  //# sourceMappingURL=charts.d.ts.map
package/dist/charts.js CHANGED
@@ -1,7 +1,7 @@
1
- import { cn } from "./classNames-DcGnTh2N.js";
1
+ import { cn } from "./classNames-DkX30VJU.js";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { Area, AreaChart as AreaChart$1, Bar, BarChart as BarChart$1, CartesianGrid, Cell, Legend, Line, LineChart as LineChart$1, Pie, PieChart as PieChart$1, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts";
4
- //#region src/blocks/Charts/ChartContainer.tsx
4
+ // src/blocks/Charts/ChartContainer.tsx
5
5
  /** Responsive frame that themes the chart's axis, grid and cursor with semantic tokens via CSS. */
6
6
  const ChartContainer = ({ height = 300, width = "100%", className, children, ...props }) => /* @__PURE__ */ jsx("div", {
7
7
  className: cn("tw:text-xs", "tw:[&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground", "tw:[&_.recharts-polar-angle-axis-tick_text]:fill-muted-foreground", "tw:[&_.recharts-label]:fill-muted-foreground", "tw:[&_.recharts-legend-item-text]:!text-muted-foreground", "tw:[&_.recharts-cartesian-grid_line]:stroke-border/60", "tw:[&_.recharts-cartesian-axis-line]:stroke-border", "tw:[&_.recharts-cartesian-axis-tick-line]:stroke-border", "tw:[&_.recharts-curve.recharts-tooltip-cursor]:stroke-border", "tw:[&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted/60", "tw:[&_.recharts-surface]:outline-hidden", className),
@@ -12,8 +12,7 @@ const ChartContainer = ({ height = 300, width = "100%", className, children, ...
12
12
  children
13
13
  })
14
14
  });
15
- //#endregion
16
- //#region src/blocks/Charts/ChartTooltip.tsx
15
+ // src/blocks/Charts/ChartTooltip.tsx
17
16
  /**
18
17
  * Brand-themed tooltip body. Surfaces (background, border, text) resolve from
19
18
  * semantic tokens, and each series swatch reuses the recharts-provided series
@@ -61,8 +60,7 @@ const ChartTooltip = ({ valueFormatter, ...props }) => /* @__PURE__ */ jsx(Toolt
61
60
  content: /* @__PURE__ */ jsx(ChartTooltipContent, { valueFormatter }),
62
61
  ...props
63
62
  });
64
- //#endregion
65
- //#region src/blocks/Charts/format.ts
63
+ // src/blocks/Charts/format.ts
66
64
  /**
67
65
  * Apply a numeric `valueFormatter` safely. recharts hands axis ticks and
68
66
  * tooltip payload values as `string | number | null | undefined`, and partial
@@ -77,8 +75,7 @@ const formatValue = (value, valueFormatter) => {
77
75
  if (!Number.isFinite(num)) return "";
78
76
  return valueFormatter ? valueFormatter(num) : String(num);
79
77
  };
80
- //#endregion
81
- //#region src/blocks/Charts/cartesian.tsx
78
+ // src/blocks/Charts/cartesian.tsx
82
79
  const AXIS_PROPS = {
83
80
  tickLine: false,
84
81
  axisLine: false,
@@ -108,8 +105,7 @@ const cartesianChrome = ({ xKey, showGrid = true, showYAxis = true, showLegend =
108
105
  showTooltip && /* @__PURE__ */ jsx(ChartTooltip, { valueFormatter: valueFormatter ? (value) => formatValue(value, valueFormatter) : void 0 }),
109
106
  showLegend && /* @__PURE__ */ jsx(Legend, { wrapperStyle: { fontSize: 11 } })
110
107
  ] });
111
- //#endregion
112
- //#region src/blocks/Charts/theme.ts
108
+ // src/blocks/Charts/theme.ts
113
109
  /**
114
110
  * Chart series colors, from the `--chart-1` … `--chart-5` CSS variables only.
115
111
  *
@@ -124,8 +120,7 @@ const chartTokenColor = (index) => {
124
120
  };
125
121
  /** Resolve an explicit token (1–5) or fall back to the series position. */
126
122
  const resolveSeriesColor = (index, token) => chartTokenColor(token ? token - 1 : index);
127
- //#endregion
128
- //#region src/blocks/Charts/LineChart.tsx
123
+ // src/blocks/Charts/LineChart.tsx
129
124
  /**
130
125
  * A themed multi-series line chart.
131
126
  *
@@ -166,8 +161,7 @@ const LineChart = ({ data, xKey, series, height, width, className, ...chrome })
166
161
  })]
167
162
  })
168
163
  });
169
- //#endregion
170
- //#region src/blocks/Charts/BarChart.tsx
164
+ // src/blocks/Charts/BarChart.tsx
171
165
  /**
172
166
  * A themed multi-series bar chart. Series colors come from the semantic
173
167
  * `--chart-*` palette (by order, or pinned via `series[].color`), which
@@ -207,8 +201,7 @@ const BarChart = ({ data, xKey, series, height, width, className, stacked = fals
207
201
  }, s.dataKey))]
208
202
  })
209
203
  });
210
- //#endregion
211
- //#region src/blocks/Charts/AreaChart.tsx
204
+ // src/blocks/Charts/AreaChart.tsx
212
205
  /**
213
206
  * Themed multi-series area chart.
214
207
  *
@@ -249,8 +242,7 @@ const AreaChart = ({ data, xKey, series, height, width, className, stacked = fal
249
242
  })]
250
243
  })
251
244
  });
252
- //#endregion
253
- //#region src/blocks/Charts/PieChart.tsx
245
+ // src/blocks/Charts/PieChart.tsx
254
246
  /**
255
247
  * A themed pie / donut chart. Each sector cycles through the semantic
256
248
  * `--chart-*` palette, which follows the active color scheme and the
@@ -278,7 +270,6 @@ const PieChart = ({ data, nameKey, dataKey, innerRadius = 0, height, width, clas
278
270
  })
279
271
  ] })
280
272
  });
281
- //#endregion
282
273
  export { AreaChart, BarChart, ChartContainer, ChartTooltip, ChartTooltipContent, LineChart, PieChart, chartTokenColor };
283
274
 
284
275
  //# sourceMappingURL=charts.js.map