@keboola/design 10.1.0 → 11.0.1

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 (382) hide show
  1. package/AGENTS.md +2 -0
  2. package/dist/AIKit-Dre37SJr.js +1320 -0
  3. package/dist/AIKit-Dre37SJr.js.map +1 -0
  4. package/dist/Alert-DfZq9kGe.js +133 -0
  5. package/dist/Alert-DfZq9kGe.js.map +1 -0
  6. package/dist/AlertModal-BUC4Es8o.js +222 -0
  7. package/dist/AlertModal-BUC4Es8o.js.map +1 -0
  8. package/dist/AppShell-B5GQN6Zs.js +143 -0
  9. package/dist/AppShell-B5GQN6Zs.js.map +1 -0
  10. package/dist/AutoSaveTextarea-BeuWuszr.js +58 -0
  11. package/dist/AutoSaveTextarea-BeuWuszr.js.map +1 -0
  12. package/dist/Badge-Ch26CXoP.js +195 -0
  13. package/dist/Badge-Ch26CXoP.js.map +1 -0
  14. package/dist/BrandEditor-B8o9zdZO.js +903 -0
  15. package/dist/BrandEditor-B8o9zdZO.js.map +1 -0
  16. package/dist/BrandLogo-CJkRd0F8.js +46 -0
  17. package/dist/BrandLogo-CJkRd0F8.js.map +1 -0
  18. package/dist/Breadcrumb-DJp7WwSv.js +330 -0
  19. package/dist/Breadcrumb-DJp7WwSv.js.map +1 -0
  20. package/dist/Button-nzmDNS2q.js +391 -0
  21. package/dist/Button-nzmDNS2q.js.map +1 -0
  22. package/dist/Calendar-cG5NIJ4O.js +6768 -0
  23. package/dist/Calendar-cG5NIJ4O.js.map +1 -0
  24. package/dist/Card-BAoZ35CV.js +105 -0
  25. package/dist/Card-BAoZ35CV.js.map +1 -0
  26. package/dist/Checkbox-GJ8-srt4.js +97 -0
  27. package/dist/Checkbox-GJ8-srt4.js.map +1 -0
  28. package/dist/Clipboard-CBJZiviP.js +58 -0
  29. package/dist/Clipboard-CBJZiviP.js.map +1 -0
  30. package/dist/ClipboardButton-ez5V3fkk.js +43 -0
  31. package/dist/ClipboardButton-ez5V3fkk.js.map +1 -0
  32. package/dist/CodeEditor-BfQJfbhL.js +952 -0
  33. package/dist/CodeEditor-BfQJfbhL.js.map +1 -0
  34. package/dist/Collapsible-BQXWEOBC.js +34 -0
  35. package/dist/Collapsible-BQXWEOBC.js.map +1 -0
  36. package/dist/ColorInput-Dx8Dsv7Y.js +180 -0
  37. package/dist/ColorInput-Dx8Dsv7Y.js.map +1 -0
  38. package/dist/ColorModeSwitch-CCqj7tjE.js +77 -0
  39. package/dist/ColorModeSwitch-CCqj7tjE.js.map +1 -0
  40. package/dist/Combobox-c_xBjf0P.js +439 -0
  41. package/dist/Combobox-c_xBjf0P.js.map +1 -0
  42. package/dist/Command-CQ_bQsJp.js +102 -0
  43. package/dist/Command-CQ_bQsJp.js.map +1 -0
  44. package/dist/CopyField-BJ96zvXs.js +322 -0
  45. package/dist/CopyField-BJ96zvXs.js.map +1 -0
  46. package/dist/DateInput-CMD3dY-T.js +141 -0
  47. package/dist/DateInput-CMD3dY-T.js.map +1 -0
  48. package/dist/DatePicker-BbFbmsGl.js +24 -0
  49. package/dist/DatePicker-BbFbmsGl.js.map +1 -0
  50. package/dist/DateRangeInput-D3BhiKyk.js +139 -0
  51. package/dist/DateRangeInput-D3BhiKyk.js.map +1 -0
  52. package/dist/DateRangePicker-BiUgtt_M.js +159 -0
  53. package/dist/DateRangePicker-BiUgtt_M.js.map +1 -0
  54. package/dist/DiagramSkeleton-lwBS2YBa.js +11 -0
  55. package/dist/DiagramSkeleton-lwBS2YBa.js.map +1 -0
  56. package/dist/DiffView-ppTIzh2h.js +429 -0
  57. package/dist/DiffView-ppTIzh2h.js.map +1 -0
  58. package/dist/DropdownMenu-B6ZbYvaM.js +327 -0
  59. package/dist/DropdownMenu-B6ZbYvaM.js.map +1 -0
  60. package/dist/FieldBox-D7DYtX_m.js +70 -0
  61. package/dist/FieldBox-D7DYtX_m.js.map +1 -0
  62. package/dist/FileUpload-sXRv7JiY.js +2527 -0
  63. package/dist/FileUpload-sXRv7JiY.js.map +1 -0
  64. package/dist/Form-BDCef6O9.js +371 -0
  65. package/dist/Form-BDCef6O9.js.map +1 -0
  66. package/dist/FormGroup-S9mPNHKH.js +124 -0
  67. package/dist/FormGroup-S9mPNHKH.js.map +1 -0
  68. package/dist/FullScreenModal-CJa2VkJ2.js +96 -0
  69. package/dist/FullScreenModal-CJa2VkJ2.js.map +1 -0
  70. package/dist/HoverCard-WfDkLK1s.js +31 -0
  71. package/dist/HoverCard-WfDkLK1s.js.map +1 -0
  72. package/dist/InputGroup-BJWsI35s.js +292 -0
  73. package/dist/InputGroup-BJWsI35s.js.map +1 -0
  74. package/dist/Kbd-CxHAo1oo.js +111 -0
  75. package/dist/Kbd-CxHAo1oo.js.map +1 -0
  76. package/dist/MarkedText-Ckbft5mw.js +44 -0
  77. package/dist/MarkedText-Ckbft5mw.js.map +1 -0
  78. package/dist/MermaidDiagram-BB06gymm.js +399 -0
  79. package/dist/MermaidDiagram-BB06gymm.js.map +1 -0
  80. package/dist/Modal-BA5Wc3sx.js +185 -0
  81. package/dist/Modal-BA5Wc3sx.js.map +1 -0
  82. package/dist/ModalTitle-C76ke2eo.js +28 -0
  83. package/dist/ModalTitle-C76ke2eo.js.map +1 -0
  84. package/dist/MultiActionButtonGroup-CiBHxsSk.js +33 -0
  85. package/dist/MultiActionButtonGroup-CiBHxsSk.js.map +1 -0
  86. package/dist/Navbar-t16usFZQ.js +322 -0
  87. package/dist/Navbar-t16usFZQ.js.map +1 -0
  88. package/dist/OtpInput-CbbymqYs.js +93 -0
  89. package/dist/OtpInput-CbbymqYs.js.map +1 -0
  90. package/dist/PageHeader-Q3IpCnQd.js +177 -0
  91. package/dist/PageHeader-Q3IpCnQd.js.map +1 -0
  92. package/dist/PageLayout-DSVM-ASz.js +176 -0
  93. package/dist/PageLayout-DSVM-ASz.js.map +1 -0
  94. package/dist/PageToolbar-0_1OBzaZ.js +153 -0
  95. package/dist/PageToolbar-0_1OBzaZ.js.map +1 -0
  96. package/dist/Pagination-CM_Rszz-.js +70 -0
  97. package/dist/Pagination-CM_Rszz-.js.map +1 -0
  98. package/dist/Popconfirm-BGe1jLov.js +170 -0
  99. package/dist/Popconfirm-BGe1jLov.js.map +1 -0
  100. package/dist/Popover-Ca0V6AD1.js +92 -0
  101. package/dist/Popover-Ca0V6AD1.js.map +1 -0
  102. package/dist/RadioGroup-sIveSsNa.js +233 -0
  103. package/dist/RadioGroup-sIveSsNa.js.map +1 -0
  104. package/dist/Resizable-D3vYToZH.js +52 -0
  105. package/dist/Resizable-D3vYToZH.js.map +1 -0
  106. package/dist/Search-3UiqNZRj.js +184 -0
  107. package/dist/Search-3UiqNZRj.js.map +1 -0
  108. package/dist/SearchInput-D2fcOv7E.js +102 -0
  109. package/dist/SearchInput-D2fcOv7E.js.map +1 -0
  110. package/dist/SectionNav--7bw2b6u.js +276 -0
  111. package/dist/SectionNav--7bw2b6u.js.map +1 -0
  112. package/dist/Select-4YX38G5h.js +181 -0
  113. package/dist/Select-4YX38G5h.js.map +1 -0
  114. package/dist/Sheet-BQrX8-h5.js +169 -0
  115. package/dist/Sheet-BQrX8-h5.js.map +1 -0
  116. package/dist/Sidebar-ROaR_AqC.js +799 -0
  117. package/dist/Sidebar-ROaR_AqC.js.map +1 -0
  118. package/dist/Slider-Da_3mS5v.js +127 -0
  119. package/dist/Slider-Da_3mS5v.js.map +1 -0
  120. package/dist/Stepper-C8sm9ZFM.js +325 -0
  121. package/dist/Stepper-C8sm9ZFM.js.map +1 -0
  122. package/dist/Switch-CX2A0v50.js +201 -0
  123. package/dist/Switch-CX2A0v50.js.map +1 -0
  124. package/dist/Table-CvYuTuNU.js +104 -0
  125. package/dist/Table-CvYuTuNU.js.map +1 -0
  126. package/dist/Tabs-EAihyqCt.js +74 -0
  127. package/dist/Tabs-EAihyqCt.js.map +1 -0
  128. package/dist/TextInput-BGed-V13.js +110 -0
  129. package/dist/TextInput-BGed-V13.js.map +1 -0
  130. package/dist/ThemeProvider-QncUrfJn.js +203 -0
  131. package/dist/ThemeProvider-QncUrfJn.js.map +1 -0
  132. package/dist/TimePicker-B_NegL-7.js +98 -0
  133. package/dist/TimePicker-B_NegL-7.js.map +1 -0
  134. package/dist/Timeline-6btyJl4D.js +154 -0
  135. package/dist/Timeline-6btyJl4D.js.map +1 -0
  136. package/dist/Toast-DQSbs3oA.js +49 -0
  137. package/dist/Toast-DQSbs3oA.js.map +1 -0
  138. package/dist/ToggleGroup-Cy_10Mvu.js +47 -0
  139. package/dist/ToggleGroup-Cy_10Mvu.js.map +1 -0
  140. package/dist/Workbench-BzE-Vvd9.js +293 -0
  141. package/dist/Workbench-BzE-Vvd9.js.map +1 -0
  142. package/dist/ZoomableSvg-DG9PnAm8.js +248 -0
  143. package/dist/ZoomableSvg-DG9PnAm8.js.map +1 -0
  144. package/dist/charts.d.ts +124 -111
  145. package/dist/charts.js +303 -249
  146. package/dist/charts.js.map +1 -1
  147. package/dist/classNames-BzrkDnOD.js +9 -0
  148. package/dist/classNames-BzrkDnOD.js.map +1 -0
  149. package/dist/constants-D6JcsD4_.d.ts +41 -0
  150. package/dist/context-KxxeMHbR.js +62 -0
  151. package/dist/context-KxxeMHbR.js.map +1 -0
  152. package/dist/editors.d.ts +180 -173
  153. package/dist/editors.js +747 -420
  154. package/dist/editors.js.map +1 -1
  155. package/dist/escapeStringRegexp-8MxP2knR.js +6 -0
  156. package/dist/escapeStringRegexp-8MxP2knR.js.map +1 -0
  157. package/dist/icons-Cek151jC.js +640 -0
  158. package/dist/icons-Cek151jC.js.map +1 -0
  159. package/dist/icons.d.ts +2 -41
  160. package/dist/icons.js +2 -4
  161. package/dist/index-m-kQEWiY.d.ts +54 -0
  162. package/dist/index.d.ts +6192 -9904
  163. package/dist/index.js +112 -15803
  164. package/dist/internal/blocks/AIKit.js +2 -0
  165. package/dist/internal/blocks/AppShell.js +2 -0
  166. package/dist/internal/blocks/AutoSaveTextarea.js +2 -0
  167. package/dist/internal/blocks/BrandEditor.js +2 -0
  168. package/dist/internal/blocks/ChartPanel.js +46 -0
  169. package/dist/internal/blocks/ChartPanel.js.map +1 -0
  170. package/dist/internal/blocks/ClipboardButton.js +2 -0
  171. package/dist/internal/blocks/ColorInput.js +2 -0
  172. package/dist/internal/blocks/ColorModeSwitch.js +2 -0
  173. package/dist/internal/blocks/Command.js +2 -0
  174. package/dist/internal/blocks/CopyField.js +2 -0
  175. package/dist/internal/blocks/DashboardHero.js +59 -0
  176. package/dist/internal/blocks/DashboardHero.js.map +1 -0
  177. package/dist/internal/blocks/DateInput.js +2 -0
  178. package/dist/internal/blocks/DateRangeInput.js +2 -0
  179. package/dist/internal/blocks/EmptyConfigurationActionCard.js +16 -0
  180. package/dist/internal/blocks/EmptyConfigurationActionCard.js.map +1 -0
  181. package/dist/internal/blocks/EmptyState.js +142 -0
  182. package/dist/internal/blocks/EmptyState.js.map +1 -0
  183. package/dist/internal/blocks/ErrorState.js +179 -0
  184. package/dist/internal/blocks/ErrorState.js.map +1 -0
  185. package/dist/internal/blocks/ExportMenu.js +41 -0
  186. package/dist/internal/blocks/ExportMenu.js.map +1 -0
  187. package/dist/internal/blocks/Form.js +2 -0
  188. package/dist/internal/blocks/FormGroup.js +2 -0
  189. package/dist/internal/blocks/GoogleButton.js +95 -0
  190. package/dist/internal/blocks/GoogleButton.js.map +1 -0
  191. package/dist/internal/blocks/MicrosoftButton.js +64 -0
  192. package/dist/internal/blocks/MicrosoftButton.js.map +1 -0
  193. package/dist/internal/blocks/MultiActionButtonGroup.js +2 -0
  194. package/dist/internal/blocks/MultiCombobox.js +188 -0
  195. package/dist/internal/blocks/MultiCombobox.js.map +1 -0
  196. package/dist/internal/blocks/NumberInput.js +44 -0
  197. package/dist/internal/blocks/NumberInput.js.map +1 -0
  198. package/dist/internal/blocks/OtpInput.js +2 -0
  199. package/dist/internal/blocks/PageHeader.js +2 -0
  200. package/dist/internal/blocks/PageLayout.js +2 -0
  201. package/dist/internal/blocks/PageToolbar.js +2 -0
  202. package/dist/internal/blocks/PasswordInput.js +97 -0
  203. package/dist/internal/blocks/PasswordInput.js.map +1 -0
  204. package/dist/internal/blocks/SearchInput.js +2 -0
  205. package/dist/internal/blocks/SearchInputWithNavigation.js +65 -0
  206. package/dist/internal/blocks/SearchInputWithNavigation.js.map +1 -0
  207. package/dist/internal/blocks/SectionNav.js +2 -0
  208. package/dist/internal/blocks/SplitButton.js +46 -0
  209. package/dist/internal/blocks/SplitButton.js.map +1 -0
  210. package/dist/internal/blocks/StatCard.js +97 -0
  211. package/dist/internal/blocks/StatCard.js.map +1 -0
  212. package/dist/internal/blocks/TextInput.js +2 -0
  213. package/dist/internal/blocks/Textarea.js +32 -0
  214. package/dist/internal/blocks/Textarea.js.map +1 -0
  215. package/dist/internal/blocks/TimeInput.js +77 -0
  216. package/dist/internal/blocks/TimeInput.js.map +1 -0
  217. package/dist/internal/components/Alert.js +2 -0
  218. package/dist/internal/components/AlertModal.js +2 -0
  219. package/dist/internal/components/Avatar.js +53 -0
  220. package/dist/internal/components/Avatar.js.map +1 -0
  221. package/dist/internal/components/Badge.js +2 -0
  222. package/dist/internal/components/BrandLogo.js +2 -0
  223. package/dist/internal/components/Breadcrumb.js +2 -0
  224. package/dist/internal/components/Button.js +2 -0
  225. package/dist/internal/components/ButtonGroup.js +66 -0
  226. package/dist/internal/components/ButtonGroup.js.map +1 -0
  227. package/dist/internal/components/Calendar.js +2 -0
  228. package/dist/internal/components/Card.js +2 -0
  229. package/dist/internal/components/Checkbox.js +2 -0
  230. package/dist/internal/components/Clipboard.js +2 -0
  231. package/dist/internal/components/Collapsible.js +2 -0
  232. package/dist/internal/components/CollapsiblePanel.js +87 -0
  233. package/dist/internal/components/CollapsiblePanel.js.map +1 -0
  234. package/dist/internal/components/Combobox.js +2 -0
  235. package/dist/internal/components/DatePicker.js +2 -0
  236. package/dist/internal/components/DateRangePicker.js +2 -0
  237. package/dist/internal/components/DiffView.js +2 -0
  238. package/dist/internal/components/DotsLoader.js +18 -0
  239. package/dist/internal/components/DotsLoader.js.map +1 -0
  240. package/dist/internal/components/DropdownMenu.js +2 -0
  241. package/dist/internal/components/EmptySearchContent.js +12 -0
  242. package/dist/internal/components/EmptySearchContent.js.map +1 -0
  243. package/dist/internal/components/FileUpload.js +2 -0
  244. package/dist/internal/components/FullScreenModal.js +2 -0
  245. package/dist/internal/components/HelpBlock.js +25 -0
  246. package/dist/internal/components/HelpBlock.js.map +1 -0
  247. package/dist/internal/components/HoverCard.js +2 -0
  248. package/dist/internal/components/InputGroup.js +2 -0
  249. package/dist/internal/components/Kbd.js +2 -0
  250. package/dist/internal/components/Label.js +39 -0
  251. package/dist/internal/components/Label.js.map +1 -0
  252. package/dist/internal/components/Link.js +22 -0
  253. package/dist/internal/components/Link.js.map +1 -0
  254. package/dist/internal/components/MarkedText.js +2 -0
  255. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +20 -0
  256. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js.map +1 -0
  257. package/dist/internal/components/MergeEditor/PaneHeader.js +13 -0
  258. package/dist/internal/components/MergeEditor/PaneHeader.js.map +1 -0
  259. package/dist/internal/components/MergeEditor/constants.js +18 -0
  260. package/dist/internal/components/MergeEditor/constants.js.map +1 -0
  261. package/dist/internal/components/MergeEditor/useMergeDiff.js +2 -0
  262. package/dist/internal/components/Modal.js +2 -0
  263. package/dist/internal/components/Navbar.js +2 -0
  264. package/dist/internal/components/Pagination.js +2 -0
  265. package/dist/internal/components/PanelWithDetails.js +31 -0
  266. package/dist/internal/components/PanelWithDetails.js.map +1 -0
  267. package/dist/internal/components/Popconfirm.js +2 -0
  268. package/dist/internal/components/Popover.js +2 -0
  269. package/dist/internal/components/Progress.js +47 -0
  270. package/dist/internal/components/Progress.js.map +1 -0
  271. package/dist/internal/components/RadioGroup.js +2 -0
  272. package/dist/internal/components/Resizable.js +2 -0
  273. package/dist/internal/components/ScrollArea.js +42 -0
  274. package/dist/internal/components/ScrollArea.js.map +1 -0
  275. package/dist/internal/components/Search.js +2 -0
  276. package/dist/internal/components/Select.js +2 -0
  277. package/dist/internal/components/Separator.js +84 -0
  278. package/dist/internal/components/Separator.js.map +1 -0
  279. package/dist/internal/components/Sheet.js +2 -0
  280. package/dist/internal/components/Sidebar.js +2 -0
  281. package/dist/internal/components/Skeleton/Skeleton.js +39 -0
  282. package/dist/internal/components/Skeleton/Skeleton.js.map +1 -0
  283. package/dist/internal/components/Skeleton/SkeletonList.js +41 -0
  284. package/dist/internal/components/Skeleton/SkeletonList.js.map +1 -0
  285. package/dist/internal/components/Slider.js +2 -0
  286. package/dist/internal/components/SpotlightBackdrop.js +132 -0
  287. package/dist/internal/components/SpotlightBackdrop.js.map +1 -0
  288. package/dist/internal/components/Stepper.js +2 -0
  289. package/dist/internal/components/Switch.js +2 -0
  290. package/dist/internal/components/Table.js +2 -0
  291. package/dist/internal/components/Tabs.js +2 -0
  292. package/dist/internal/components/ThemeProvider.js +3 -0
  293. package/dist/internal/components/TimePicker.js +2 -0
  294. package/dist/internal/components/Timeline.js +2 -0
  295. package/dist/internal/components/Toast.js +3 -0
  296. package/dist/internal/components/Toggle.js +169 -0
  297. package/dist/internal/components/Toggle.js.map +1 -0
  298. package/dist/internal/components/ToggleGroup.js +2 -0
  299. package/dist/internal/components/Tooltip.js +2 -0
  300. package/dist/internal/components/Truncated.js +45 -0
  301. package/dist/internal/components/Truncated.js.map +1 -0
  302. package/dist/internal/components/Workbench.js +2 -0
  303. package/dist/internal/components/ZoomableSvg.js +2 -0
  304. package/dist/internal/hooks/useAutosizeInput.js +77 -0
  305. package/dist/internal/hooks/useAutosizeInput.js.map +1 -0
  306. package/dist/internal/hooks/useScrollbarPosition.js +45 -0
  307. package/dist/internal/hooks/useScrollbarPosition.js.map +1 -0
  308. package/dist/internal/hooks/useStableCallback.js +29 -0
  309. package/dist/internal/hooks/useStableCallback.js.map +1 -0
  310. package/dist/internal/utils/mergeRefs.js +20 -0
  311. package/dist/internal/utils/mergeRefs.js.map +1 -0
  312. package/dist/internal/utils.js +5 -0
  313. package/dist/markdown-editor.d.ts +72 -72
  314. package/dist/markdown-editor.js +1122 -1193
  315. package/dist/markdown-editor.js.map +1 -1
  316. package/dist/mermaid.d.ts +12 -12
  317. package/dist/mermaid.js +2 -10
  318. package/dist/rjsf.d.ts +33 -34
  319. package/dist/rjsf.js +1543 -1600
  320. package/dist/rjsf.js.map +1 -1
  321. package/dist/rolldown-runtime-Bdc48AWt.js +33 -0
  322. package/dist/styles-DSUP_-9Z.js +158 -0
  323. package/dist/styles-DSUP_-9Z.js.map +1 -0
  324. package/dist/styles.css +1 -1
  325. package/dist/testing.d.ts +8 -7
  326. package/dist/testing.js +36 -16
  327. package/dist/testing.js.map +1 -1
  328. package/dist/themeTokens-BNg98Mu9.js +85 -0
  329. package/dist/themeTokens-BNg98Mu9.js.map +1 -0
  330. package/dist/toast-CjkURw0M.js +184 -0
  331. package/dist/toast-CjkURw0M.js.map +1 -0
  332. package/dist/useColorSchemeState-CYqcUfSH.js +61 -0
  333. package/dist/useColorSchemeState-CYqcUfSH.js.map +1 -0
  334. package/dist/useControllableState-M6494mCT.js +31 -0
  335. package/dist/useControllableState-M6494mCT.js.map +1 -0
  336. package/dist/useElement-DkF6esWL.js +15 -0
  337. package/dist/useElement-DkF6esWL.js.map +1 -0
  338. package/dist/useMergeDiff-CvowEXJ1.js +465 -0
  339. package/dist/useMergeDiff-CvowEXJ1.js.map +1 -0
  340. package/dist/utils-D0c5VAyF.js +308 -0
  341. package/dist/utils-D0c5VAyF.js.map +1 -0
  342. package/package.json +10 -9
  343. package/src/styles.css +35 -7
  344. package/src/theme.css +64 -0
  345. package/dist/MermaidDiagram-EOKJHQQV.js +0 -10
  346. package/dist/MermaidDiagram-EOKJHQQV.js.map +0 -1
  347. package/dist/chunk-63NSN2VL.js +0 -274
  348. package/dist/chunk-63NSN2VL.js.map +0 -1
  349. package/dist/chunk-6FPEI4EM.js +0 -6683
  350. package/dist/chunk-6FPEI4EM.js.map +0 -1
  351. package/dist/chunk-7PUUHEJQ.js +0 -1313
  352. package/dist/chunk-7PUUHEJQ.js.map +0 -1
  353. package/dist/chunk-BOHNXTMM.js +0 -606
  354. package/dist/chunk-BOHNXTMM.js.map +0 -1
  355. package/dist/chunk-C3L3TBBT.js +0 -242
  356. package/dist/chunk-C3L3TBBT.js.map +0 -1
  357. package/dist/chunk-CTCFYWJC.js +0 -407
  358. package/dist/chunk-CTCFYWJC.js.map +0 -1
  359. package/dist/chunk-ESBL3IPF.js +0 -23
  360. package/dist/chunk-ESBL3IPF.js.map +0 -1
  361. package/dist/chunk-IJTHFNNJ.js +0 -261
  362. package/dist/chunk-IJTHFNNJ.js.map +0 -1
  363. package/dist/chunk-JP7PNHLH.js +0 -40
  364. package/dist/chunk-JP7PNHLH.js.map +0 -1
  365. package/dist/chunk-KPNAW5MU.js +0 -229
  366. package/dist/chunk-KPNAW5MU.js.map +0 -1
  367. package/dist/chunk-L37JJ6MR.js +0 -152
  368. package/dist/chunk-L37JJ6MR.js.map +0 -1
  369. package/dist/chunk-Q7NWXLCT.js +0 -90
  370. package/dist/chunk-Q7NWXLCT.js.map +0 -1
  371. package/dist/chunk-SYIEF644.js +0 -1016
  372. package/dist/chunk-SYIEF644.js.map +0 -1
  373. package/dist/chunk-VMFSRV5H.js +0 -16
  374. package/dist/chunk-VMFSRV5H.js.map +0 -1
  375. package/dist/chunk-VPPM7UUQ.js +0 -47
  376. package/dist/chunk-VPPM7UUQ.js.map +0 -1
  377. package/dist/chunk-XV3UUOYF.js +0 -845
  378. package/dist/chunk-XV3UUOYF.js.map +0 -1
  379. package/dist/constants-D3gaMY-W.d.ts +0 -39
  380. package/dist/icons.js.map +0 -1
  381. package/dist/index.js.map +0 -1
  382. package/dist/mermaid.js.map +0 -1
package/dist/editors.js CHANGED
@@ -1,433 +1,760 @@
1
- import { LINE_HEIGHT_PX, PANE_HEADER_HEIGHT_PX, CHANGE_CLASS } from './chunk-VMFSRV5H.js';
2
- import { useThemedExtension, isDarkScheme, resolveToken, buildBasicSetup } from './chunk-7PUUHEJQ.js';
3
- export { CodeEditor, LANGUAGE_MODES, SqlEditor, isLanguageMode } from './chunk-7PUUHEJQ.js';
4
- import { useStableCallback } from './chunk-Q7NWXLCT.js';
5
- import './chunk-L37JJ6MR.js';
6
- import './chunk-ESBL3IPF.js';
7
- import { Button } from './chunk-CTCFYWJC.js';
8
- import { X, ChevronsRight, ChevronsLeft } from './chunk-BOHNXTMM.js';
9
- import './chunk-63NSN2VL.js';
10
- import { cn } from './chunk-JP7PNHLH.js';
11
- import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
12
- import { useRef, useCallback, useMemo, useEffect } from 'react';
13
- import { Decoration, GutterMarker, EditorView, gutterLineClass } from '@codemirror/view';
14
- import CodeMirror from '@uiw/react-codemirror';
15
- import colors from '@keboola/tailwind-config/colors';
16
- import { StateEffect, StateField, RangeSet, RangeSetBuilder } from '@codemirror/state';
17
-
18
- var AcceptButton = ({ side, onAccept }) => {
19
- const label = `Accept ${side === "left" ? "production" : "branch"} version`;
20
- const Chevron = side === "left" ? ChevronsRight : ChevronsLeft;
21
- return /* @__PURE__ */ jsx(Button, { onClick: onAccept, variant: "outline", size: "icon-sm", title: label, "aria-label": label, children: /* @__PURE__ */ jsx(Chevron, { className: "tw:size-5" }) });
1
+ import { cn } from "./classNames-BzrkDnOD.js";
2
+ import { ChevronsLeft, ChevronsRight, X } from "./icons-Cek151jC.js";
3
+ import { Button } from "./Button-nzmDNS2q.js";
4
+ import { CHANGE_CLASS } from "./internal/components/MergeEditor/constants.js";
5
+ import { useStableCallback } from "./internal/hooks/useStableCallback.js";
6
+ import { resolveToken } from "./themeTokens-BNg98Mu9.js";
7
+ import { CodeEditor, LANGUAGE_MODES, buildBaseThemeStyles, buildBasicSetup, buildCanvasChrome, buildChromeStyles, buildCustomTheme, isLanguageMode, searchExtension, updateSearch, useThemedExtension, useTooltipsExtension, useVariableCompletion } from "./CodeEditor-BfQJfbhL.js";
8
+ import { useCallback, useEffect, useMemo, useRef } from "react";
9
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
10
+ import { Decoration, EditorView, GutterMarker, ViewPlugin, gutter, gutterLineClass } from "@codemirror/view";
11
+ import CodeMirror, { EditorView as EditorView$1, keymap as keymap$1 } from "@uiw/react-codemirror";
12
+ import colors from "@keboola/tailwind-config/colors";
13
+ import { installExtensions } from "@keboola/codemirror-lang-sql";
14
+ import { RangeSet, RangeSetBuilder, StateEffect, StateField } from "@codemirror/state";
15
+ import { defaultKeymap } from "@codemirror/commands";
16
+ //#region src/components/CodeEditor/activeQueryHighlight.ts
17
+ const activeQueryFirstLine = Decoration.line({ class: "cm-active-query cm-active-query-first" });
18
+ const activeQueryMiddleLine = Decoration.line({ class: "cm-active-query" });
19
+ const activeQueryLastLine = Decoration.line({ class: "cm-active-query cm-active-query-last" });
20
+ const activeQuerySingleLine = Decoration.line({ class: "cm-active-query cm-active-query-first cm-active-query-last" });
21
+ /**
22
+ * Given pre-computed query boundaries and a cursor position, find which query
23
+ * the cursor is in. Returns trimmed character offsets or null.
24
+ */
25
+ const findActiveQueryRange = (doc, cursorPos, boundaries) => {
26
+ if (boundaries.length === 0) return null;
27
+ let match = boundaries[boundaries.length - 1];
28
+ for (const boundary of boundaries) if (cursorPos <= boundary.to) {
29
+ match = boundary;
30
+ break;
31
+ }
32
+ if (!match) return null;
33
+ const queryText = doc.slice(match.from, match.to);
34
+ const leadingWhitespace = queryText.length - queryText.trimStart().length;
35
+ const trailingWhitespace = queryText.length - queryText.trimEnd().length;
36
+ const trimmedStart = match.from + leadingWhitespace;
37
+ const trimmedEnd = match.to - trailingWhitespace;
38
+ if (trimmedStart >= trimmedEnd) return null;
39
+ return {
40
+ from: trimmedStart,
41
+ to: trimmedEnd
42
+ };
43
+ };
44
+ /**
45
+ * Convert splitSqlQueries result (array of query strings that join back to the
46
+ * original doc) into character-offset boundaries.
47
+ */
48
+ const computeBoundaries = (queries) => {
49
+ const boundaries = [];
50
+ let offset = 0;
51
+ for (const query of queries) {
52
+ boundaries.push({
53
+ from: offset,
54
+ to: offset + query.length
55
+ });
56
+ offset += query.length;
57
+ }
58
+ return boundaries;
59
+ };
60
+ /**
61
+ * Synchronously map cached boundaries through a changeset.
62
+ *
63
+ * Boundaries can outlive the document state they were computed from (the async
64
+ * re-parse in `scheduleDocParse` is debounced, so several edits may land
65
+ * before new boundaries are produced). When that happens a cached position
66
+ * can exceed the changeset's pre-change length and `ChangeSet.mapPos` throws
67
+ * `RangeError: Position X is out of range for changeset of length Y`.
68
+ *
69
+ * Clamp positions into the valid `[0, changes.length]` range before mapping
70
+ * and drop degenerate boundaries so the mapping is safe even with stale cache.
71
+ */
72
+ const mapBoundariesThroughChanges = (boundaries, changes) => {
73
+ const prevLen = changes.length;
74
+ const mapped = [];
75
+ for (const b of boundaries) {
76
+ const from = changes.mapPos(Math.max(0, Math.min(b.from, prevLen)), -1);
77
+ const to = changes.mapPos(Math.max(0, Math.min(b.to, prevLen)), 1);
78
+ if (from < to) mapped.push({
79
+ from,
80
+ to
81
+ });
82
+ }
83
+ return mapped;
84
+ };
85
+ const buildDecorations = (view, range) => {
86
+ const startLine = view.state.doc.lineAt(range.from).number;
87
+ const endLine = view.state.doc.lineAt(range.to).number;
88
+ const decorations = [];
89
+ for (let lineNum = startLine; lineNum <= endLine; lineNum++) {
90
+ const lineStart = view.state.doc.line(lineNum).from;
91
+ if (startLine === endLine) decorations.push(activeQuerySingleLine.range(lineStart));
92
+ else if (lineNum === startLine) decorations.push(activeQueryFirstLine.range(lineStart));
93
+ else if (lineNum === endLine) decorations.push(activeQueryLastLine.range(lineStart));
94
+ else decorations.push(activeQueryMiddleLine.range(lineStart));
95
+ }
96
+ return Decoration.set(decorations);
97
+ };
98
+ const activeQueryHighlight = (splitQueries) => {
99
+ return [ViewPlugin.fromClass(class {
100
+ decorations = Decoration.none;
101
+ debounceTimer = null;
102
+ seq = 0;
103
+ cachedDoc = "";
104
+ cachedBoundaries = [];
105
+ destroyed = false;
106
+ constructor(view) {
107
+ this.scheduleDocParse(view);
108
+ }
109
+ update(update) {
110
+ if (update.focusChanged && !update.view.hasFocus) {
111
+ this.decorations = Decoration.none;
112
+ return;
113
+ }
114
+ if (update.docChanged) {
115
+ if (this.cachedBoundaries.length > 0) {
116
+ this.cachedBoundaries = mapBoundariesThroughChanges(this.cachedBoundaries, update.changes);
117
+ this.cachedDoc = update.state.doc.toString();
118
+ this.updateFromCache(update.view);
119
+ }
120
+ this.scheduleDocParse(update.view);
121
+ } else if (update.selectionSet || update.focusChanged && update.view.hasFocus) this.updateFromCache(update.view);
122
+ }
123
+ destroy() {
124
+ this.destroyed = true;
125
+ if (this.debounceTimer) clearTimeout(this.debounceTimer);
126
+ }
127
+ /**
128
+ * Update decorations using cached query boundaries.
129
+ * Only mutates this.decorations — does NOT call view.dispatch().
130
+ * When called from update() (sync), CodeMirror picks up the new
131
+ * decorations via the accessor. When called from the async
132
+ * scheduleDocParse callback, the caller must dispatch separately.
133
+ */
134
+ updateFromCache(view) {
135
+ if (!view.hasFocus) {
136
+ this.decorations = Decoration.none;
137
+ return;
138
+ }
139
+ const { main } = view.state.selection;
140
+ if (main.from !== main.to) {
141
+ this.decorations = Decoration.none;
142
+ return;
143
+ }
144
+ const doc = view.state.doc.toString();
145
+ if (doc !== this.cachedDoc) return;
146
+ if (this.cachedBoundaries.length === 0) {
147
+ this.decorations = Decoration.none;
148
+ return;
149
+ }
150
+ const range = findActiveQueryRange(doc, main.head, this.cachedBoundaries);
151
+ this.decorations = range ? buildDecorations(view, range) : Decoration.none;
152
+ }
153
+ /** Parse queries async (debounced) and update decorations. */
154
+ scheduleDocParse(view) {
155
+ if (this.debounceTimer) clearTimeout(this.debounceTimer);
156
+ this.debounceTimer = setTimeout(async () => {
157
+ const seq = ++this.seq;
158
+ const doc = view.state.doc.toString();
159
+ if (!doc.trim()) {
160
+ this.cachedDoc = doc;
161
+ this.cachedBoundaries = [];
162
+ if (this.decorations !== Decoration.none) {
163
+ this.decorations = Decoration.none;
164
+ if (!this.destroyed) view.dispatch();
165
+ }
166
+ return;
167
+ }
168
+ let queries;
169
+ try {
170
+ queries = await splitQueries(doc);
171
+ } catch {
172
+ return;
173
+ }
174
+ if (this.destroyed || seq !== this.seq) return;
175
+ this.cachedDoc = doc;
176
+ this.cachedBoundaries = computeBoundaries(queries);
177
+ this.updateFromCache(view);
178
+ if (!this.destroyed) view.dispatch();
179
+ }, 100);
180
+ }
181
+ }, { decorations: (v) => v.decorations }), EditorView.baseTheme({
182
+ ".cm-active-query": {
183
+ boxShadow: `inset -1px 0 0 0 ${colors.blue[300]}, inset 1px 0 0 0 ${colors.blue[300]}`,
184
+ marginRight: "8px"
185
+ },
186
+ ".cm-active-query-first": {
187
+ boxShadow: `inset -1px 0 0 0 ${colors.blue[300]}, inset 1px 0 0 0 ${colors.blue[300]}, inset 0 1px 0 0 ${colors.blue[300]}`,
188
+ borderRadius: "4px 4px 0 0"
189
+ },
190
+ ".cm-active-query-last": {
191
+ boxShadow: `inset -1px 0 0 0 ${colors.blue[300]}, inset 1px 0 0 0 ${colors.blue[300]}, inset 0 -1px 0 0 ${colors.blue[300]}`,
192
+ borderRadius: "0 0 4px 4px"
193
+ },
194
+ ".cm-active-query-first.cm-active-query-last": {
195
+ boxShadow: `inset 0 0 0 1px ${colors.blue[300]}`,
196
+ borderRadius: "4px"
197
+ }
198
+ })];
22
199
  };
23
- var AcceptControls = ({ conflicts, side, onAccept, onDismiss, contentRef }) => /* @__PURE__ */ jsx(
24
- "div",
25
- {
26
- className: cn(
27
- "tw:z-10 tw:flex tw:shrink-0 tw:flex-col tw:items-center",
28
- conflicts.length > 0 ? "tw:w-7" : "tw:w-0"
29
- ),
30
- children: conflicts.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
31
- /* @__PURE__ */ jsx("div", { className: "tw:shrink-0", style: { height: `${PANE_HEADER_HEIGHT_PX}px` } }),
32
- /* @__PURE__ */ jsx("div", { className: "tw:relative tw:w-full tw:flex-1 tw:overflow-y-clip tw:overflow-x-visible", children: /* @__PURE__ */ jsx("div", { ref: contentRef, className: "tw:relative tw:size-full", children: conflicts.map((conflict) => {
33
- const topLine = side === "left" ? conflict.oldStartLine : conflict.newStartLine;
34
- const topOffset = (topLine - 1) * LINE_HEIGHT_PX - 2;
35
- return /* @__PURE__ */ jsxs(
36
- "div",
37
- {
38
- className: "tw:absolute tw:inset-x-0 tw:flex tw:flex-col tw:items-center tw:gap-0.5",
39
- style: { top: `${topOffset}px` },
40
- children: [
41
- /* @__PURE__ */ jsx(AcceptButton, { side, onAccept: () => onAccept(conflict) }),
42
- onDismiss && /* @__PURE__ */ jsx(
43
- Button,
44
- {
45
- onClick: () => onDismiss(conflict),
46
- variant: "outline",
47
- size: "icon-sm",
48
- title: "Dismiss",
49
- "aria-label": `Dismiss ${side === "left" ? "production" : "branch"} change`,
50
- children: /* @__PURE__ */ jsx(X, { className: "tw:size-4" })
51
- }
52
- )
53
- ]
54
- },
55
- conflict.id
56
- );
57
- }) }) })
58
- ] })
59
- }
60
- );
61
- var setHighlightedLines = StateEffect.define();
62
- var safeDecoration = Decoration.line({ class: "cm-merge-safe-line" });
63
- var conflictDecoration = Decoration.line({ class: "cm-merge-conflict-line" });
200
+ //#endregion
201
+ //#region src/components/CodeEditor/highlighting.ts
202
+ var HighlightMarker = class extends GutterMarker {
203
+ toDOM() {
204
+ const marker = document.createElement("div");
205
+ marker.className = "cm-highlight-marker";
206
+ return marker;
207
+ }
208
+ };
209
+ const highlightMarker = new HighlightMarker();
210
+ const forEachLineInRange = (doc, from, to, callback) => {
211
+ const results = [];
212
+ const fromLine = Math.max(1, from + 1);
213
+ const toLine = Math.min(doc.lines, to + 1);
214
+ for (let i = fromLine; i <= toLine; i++) {
215
+ const line = doc.line(i);
216
+ results.push(callback(line.from));
217
+ }
218
+ return results;
219
+ };
220
+ const setHighlightedLinesEffect = StateEffect.define();
221
+ const highlightedLinesField = StateField.define({
222
+ create() {
223
+ return null;
224
+ },
225
+ update(value, transaction) {
226
+ for (const effect of transaction.effects) if (effect.is(setHighlightedLinesEffect)) return effect.value;
227
+ return value;
228
+ }
229
+ });
230
+ const highlightGutter = gutter({
231
+ class: "cm-highlight-gutter",
232
+ markers: (view) => {
233
+ const highlightInfo = view.state.field(highlightedLinesField, false);
234
+ if (!highlightInfo) return RangeSet.empty;
235
+ const markers = forEachLineInRange(view.state.doc, highlightInfo.from, highlightInfo.to, (lineFrom) => highlightMarker.range(lineFrom));
236
+ return RangeSet.of(markers);
237
+ }
238
+ });
239
+ const errorLineDecorations = StateField.define({
240
+ create() {
241
+ return Decoration.none;
242
+ },
243
+ update(decorations, transaction) {
244
+ decorations = decorations.map(transaction.changes);
245
+ for (const effect of transaction.effects) {
246
+ if (!effect.is(setHighlightedLinesEffect)) continue;
247
+ if (!effect.value || !effect.value.error) return Decoration.none;
248
+ const decorationArray = forEachLineInRange(transaction.state.doc, effect.value.error.from, effect.value.error.to, (lineFrom) => Decoration.line({ class: "cm-error-line" }).range(lineFrom));
249
+ return Decoration.set(decorationArray);
250
+ }
251
+ return decorations;
252
+ },
253
+ provide: (f) => EditorView.decorations.from(f)
254
+ });
255
+ const processingLineDecorations = StateField.define({
256
+ create() {
257
+ return Decoration.none;
258
+ },
259
+ update(decorations, transaction) {
260
+ decorations = decorations.map(transaction.changes);
261
+ for (const effect of transaction.effects) {
262
+ if (!effect.is(setHighlightedLinesEffect)) continue;
263
+ if (!effect.value || !effect.value.processing) return Decoration.none;
264
+ const decorationArray = forEachLineInRange(transaction.state.doc, effect.value.processing.from, effect.value.processing.to, (lineFrom) => Decoration.line({ class: "cm-processing-line" }).range(lineFrom));
265
+ return Decoration.set(decorationArray);
266
+ }
267
+ return decorations;
268
+ },
269
+ provide: (f) => EditorView.decorations.from(f)
270
+ });
271
+ const highlightedLinesTheme = EditorView.baseTheme({
272
+ ".cm-highlight-gutter": {
273
+ width: "2px",
274
+ marginRight: "2px"
275
+ },
276
+ ".cm-highlight-marker": {
277
+ width: "2px",
278
+ height: "100%",
279
+ backgroundColor: colors.blue[500]
280
+ },
281
+ ".cm-error-line": { backgroundColor: `${colors.error[100]} !important` },
282
+ ".cm-processing-line": { backgroundColor: `${colors.blue[100]} !important` }
283
+ });
284
+ function highlightingExtension() {
285
+ return [
286
+ highlightedLinesField,
287
+ highlightGutter,
288
+ errorLineDecorations,
289
+ processingLineDecorations,
290
+ highlightedLinesTheme
291
+ ];
292
+ }
293
+ function updateHighlighting(view, lines) {
294
+ view.dispatch({ effects: setHighlightedLinesEffect.of(lines ?? null) });
295
+ }
296
+ //#endregion
297
+ //#region src/components/CodeEditor/SqlEditor.tsx
298
+ const OWN_KEYMAPS = {
299
+ defaultKeymap: false,
300
+ completionKeymap: false,
301
+ searchKeymap: false
302
+ };
303
+ const CUSTOM_KEYMAP = [{
304
+ key: "Escape",
305
+ stopPropagation: true,
306
+ run: (view) => {
307
+ view.contentDOM.blur();
308
+ return true;
309
+ }
310
+ }];
311
+ const OWN_KEYMAP_EXTENSION = keymap$1.of([...defaultKeymap, ...CUSTOM_KEYMAP]);
312
+ const buildTheme = () => ({
313
+ ...buildBaseThemeStyles(),
314
+ ...buildChromeStyles(buildCanvasChrome())
315
+ });
316
+ const SqlEditor = ({ value, onChange, onSelectionChange, onCreateEditor, onDestroyEditor, onBlurEditor, onFocusEditor, placeholder = "", searchQuery = "", searchMatchIndex, readOnly = false, queryParser, autoFocus = false, lineNumbers = true, className, schema, completionSource, variables, defaultDatabase, defaultSchema, highlightLines, dialect }) => {
317
+ const editorRef = useRef(null);
318
+ const handleChange = useStableCallback((next) => onChange?.(next));
319
+ const parseQueries = useStableCallback(async (sql) => await queryParser?.(sql) ?? []);
320
+ const handleBlur = useStableCallback((view) => onBlurEditor?.(view));
321
+ const handleFocus = useStableCallback((view) => onFocusEditor?.(view));
322
+ const handleUpdate = useStableCallback((update) => {
323
+ if (update.selectionSet) {
324
+ const { main } = update.state.selection;
325
+ onSelectionChange?.(update.state.sliceDoc(main.from, main.to));
326
+ }
327
+ });
328
+ const variableCompletion = useVariableCompletion(variables);
329
+ const withQueryParser = queryParser !== void 0;
330
+ const tooltipLayer = useTooltipsExtension();
331
+ const customTheme = useThemedExtension("editor:syntax", buildCustomTheme);
332
+ const themeExtension = useThemedExtension("sql-editor:chrome", () => EditorView$1.theme(buildTheme()));
333
+ const extensions = useMemo(() => {
334
+ return [
335
+ EditorView$1.lineWrapping,
336
+ OWN_KEYMAP_EXTENSION,
337
+ ...installExtensions({
338
+ schema,
339
+ defaultDatabase,
340
+ defaultSchema,
341
+ variableCompletion,
342
+ completionSource,
343
+ dialect
344
+ }),
345
+ searchExtension(),
346
+ highlightingExtension(),
347
+ withQueryParser ? activeQueryHighlight(parseQueries) : [],
348
+ tooltipLayer,
349
+ themeExtension,
350
+ EditorView$1.domEventHandlers({
351
+ blur: (_, view) => handleBlur(view),
352
+ focus: (_, view) => handleFocus(view)
353
+ })
354
+ ];
355
+ }, [
356
+ withQueryParser,
357
+ parseQueries,
358
+ schema,
359
+ completionSource,
360
+ defaultDatabase,
361
+ defaultSchema,
362
+ variableCompletion,
363
+ dialect,
364
+ handleBlur,
365
+ handleFocus,
366
+ themeExtension,
367
+ tooltipLayer
368
+ ]);
369
+ const defaultSetup = useMemo(() => {
370
+ return {
371
+ ...buildBasicSetup(readOnly),
372
+ ...OWN_KEYMAPS,
373
+ lineNumbers
374
+ };
375
+ }, [readOnly, lineNumbers]);
376
+ useEffect(() => {
377
+ if (editorRef.current?.view) updateHighlighting(editorRef.current.view, highlightLines);
378
+ }, [highlightLines]);
379
+ useEffect(() => {
380
+ if (editorRef.current?.view) updateSearch(editorRef.current.view, searchQuery, searchMatchIndex);
381
+ }, [searchQuery, searchMatchIndex]);
382
+ const handleDestroy = useStableCallback(() => onDestroyEditor?.());
383
+ useEffect(() => handleDestroy, [handleDestroy]);
384
+ const handleCreate = useStableCallback((view, state) => {
385
+ onCreateEditor?.(view, state);
386
+ if (highlightLines) updateHighlighting(view, highlightLines);
387
+ if (searchQuery) updateSearch(view, searchQuery, searchMatchIndex);
388
+ });
389
+ return /* @__PURE__ */ jsx(CodeMirror, {
390
+ ref: editorRef,
391
+ theme: customTheme,
392
+ extensions,
393
+ value,
394
+ onChange: handleChange,
395
+ onUpdate: handleUpdate,
396
+ onCreateEditor: handleCreate,
397
+ autoFocus,
398
+ placeholder,
399
+ className,
400
+ readOnly,
401
+ editable: !readOnly,
402
+ basicSetup: defaultSetup
403
+ });
404
+ };
405
+ //#endregion
406
+ //#region src/components/MergeEditor/AcceptControls/AcceptButton.tsx
407
+ const AcceptButton = ({ side, onAccept }) => {
408
+ const label = `Accept ${side === "left" ? "production" : "branch"} version`;
409
+ return /* @__PURE__ */ jsx(Button, {
410
+ onClick: onAccept,
411
+ variant: "outline",
412
+ size: "icon-sm",
413
+ title: label,
414
+ "aria-label": label,
415
+ children: /* @__PURE__ */ jsx(side === "left" ? ChevronsRight : ChevronsLeft, { className: "tw:size-5" })
416
+ });
417
+ };
418
+ //#endregion
419
+ //#region src/components/MergeEditor/AcceptControls/AcceptControls.tsx
420
+ const AcceptControls = ({ conflicts, side, onAccept, onDismiss, contentRef }) => /* @__PURE__ */ jsx("div", {
421
+ className: cn("tw:z-10 tw:flex tw:shrink-0 tw:flex-col tw:items-center", conflicts.length > 0 ? "tw:w-7" : "tw:w-0"),
422
+ children: conflicts.length > 0 && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", {
423
+ className: "tw:shrink-0",
424
+ style: { height: `58px` }
425
+ }), /* @__PURE__ */ jsx("div", {
426
+ className: "tw:relative tw:w-full tw:flex-1 tw:overflow-y-clip tw:overflow-x-visible",
427
+ children: /* @__PURE__ */ jsx("div", {
428
+ ref: contentRef,
429
+ className: "tw:relative tw:size-full",
430
+ children: conflicts.map((conflict) => {
431
+ const topOffset = ((side === "left" ? conflict.oldStartLine : conflict.newStartLine) - 1) * 20 - 2;
432
+ return /* @__PURE__ */ jsxs("div", {
433
+ className: "tw:absolute tw:inset-x-0 tw:flex tw:flex-col tw:items-center tw:gap-0.5",
434
+ style: { top: `${topOffset}px` },
435
+ children: [/* @__PURE__ */ jsx(AcceptButton, {
436
+ side,
437
+ onAccept: () => onAccept(conflict)
438
+ }), onDismiss && /* @__PURE__ */ jsx(Button, {
439
+ onClick: () => onDismiss(conflict),
440
+ variant: "outline",
441
+ size: "icon-sm",
442
+ title: "Dismiss",
443
+ "aria-label": `Dismiss ${side === "left" ? "production" : "branch"} change`,
444
+ children: /* @__PURE__ */ jsx(X, { className: "tw:size-4" })
445
+ })]
446
+ }, conflict.id);
447
+ })
448
+ })
449
+ })] })
450
+ });
451
+ //#endregion
452
+ //#region src/components/MergeEditor/decorations.ts
453
+ const setHighlightedLines = StateEffect.define();
454
+ const safeDecoration = Decoration.line({ class: "cm-merge-safe-line" });
455
+ const conflictDecoration = Decoration.line({ class: "cm-merge-conflict-line" });
64
456
  var SafeGutterMarker = class extends GutterMarker {
65
- elementClass = "cm-merge-safe-gutter";
457
+ elementClass = "cm-merge-safe-gutter";
66
458
  };
67
459
  var ConflictGutterMarker = class extends GutterMarker {
68
- elementClass = "cm-merge-conflict-gutter";
460
+ elementClass = "cm-merge-conflict-gutter";
69
461
  };
70
- var safeGutterMarker = new SafeGutterMarker();
71
- var conflictGutterMarker = new ConflictGutterMarker();
72
- var createDiffHighlightExtension = () => StateField.define({
73
- create: () => ({ decorations: Decoration.none, gutterMarkers: RangeSet.empty }),
74
- update(value, tr) {
75
- let payload = null;
76
- for (const effect of tr.effects) {
77
- if (effect.is(setHighlightedLines)) {
78
- payload = effect.value;
79
- }
80
- }
81
- if (!payload) {
82
- return {
83
- decorations: value.decorations.map(tr.changes),
84
- gutterMarkers: value.gutterMarkers.map(tr.changes)
85
- };
86
- }
87
- const decoBuilder = new RangeSetBuilder();
88
- const gutterBuilder = new RangeSetBuilder();
89
- const doc = tr.state.doc;
90
- const { lines, classification } = payload;
91
- const sorted = [...lines].filter((l) => l >= 1 && l <= doc.lines).sort((a, b) => a - b);
92
- for (const i of sorted) {
93
- const cls = classification.get(i);
94
- if (!cls) continue;
95
- const isSafe = cls === CHANGE_CLASS.SAFE;
96
- const line = doc.line(i);
97
- decoBuilder.add(line.from, line.from, isSafe ? safeDecoration : conflictDecoration);
98
- gutterBuilder.add(line.from, line.from, isSafe ? safeGutterMarker : conflictGutterMarker);
99
- }
100
- return {
101
- decorations: decoBuilder.finish(),
102
- gutterMarkers: gutterBuilder.finish()
103
- };
104
- },
105
- provide: (f) => [
106
- EditorView.decorations.from(f, (val) => val.decorations),
107
- gutterLineClass.from(f, (val) => val.gutterMarkers)
108
- ]
462
+ const safeGutterMarker = new SafeGutterMarker();
463
+ const conflictGutterMarker = new ConflictGutterMarker();
464
+ const createDiffHighlightExtension = () => StateField.define({
465
+ create: () => ({
466
+ decorations: Decoration.none,
467
+ gutterMarkers: RangeSet.empty
468
+ }),
469
+ update(value, tr) {
470
+ let payload = null;
471
+ for (const effect of tr.effects) if (effect.is(setHighlightedLines)) payload = effect.value;
472
+ if (!payload) return {
473
+ decorations: value.decorations.map(tr.changes),
474
+ gutterMarkers: value.gutterMarkers.map(tr.changes)
475
+ };
476
+ const decoBuilder = new RangeSetBuilder();
477
+ const gutterBuilder = new RangeSetBuilder();
478
+ const doc = tr.state.doc;
479
+ const { lines, classification } = payload;
480
+ const sorted = [...lines].filter((l) => l >= 1 && l <= doc.lines).sort((a, b) => a - b);
481
+ for (const i of sorted) {
482
+ const cls = classification.get(i);
483
+ if (!cls) continue;
484
+ const isSafe = cls === CHANGE_CLASS.SAFE;
485
+ const line = doc.line(i);
486
+ decoBuilder.add(line.from, line.from, isSafe ? safeDecoration : conflictDecoration);
487
+ gutterBuilder.add(line.from, line.from, isSafe ? safeGutterMarker : conflictGutterMarker);
488
+ }
489
+ return {
490
+ decorations: decoBuilder.finish(),
491
+ gutterMarkers: gutterBuilder.finish()
492
+ };
493
+ },
494
+ provide: (f) => [EditorView.decorations.from(f, (val) => val.decorations), gutterLineClass.from(f, (val) => val.gutterMarkers)]
109
495
  });
110
- var DARK_LINE_ALPHA = "29";
111
- var DARK_GUTTER_ALPHA = "47";
112
- var buildDiffHighlightTheme = () => {
113
- const dark = isDarkScheme();
114
- const line = (hue, pastel) => dark ? `${hue}${DARK_LINE_ALPHA}` : pastel;
115
- const gutter = (hue, pastel) => dark ? `${hue}${DARK_GUTTER_ALPHA}` : pastel;
116
- const safeNumber = dark ? colors.green[300] : colors.green[900];
117
- const conflictNumber = dark ? colors.warning[300] : colors.warning[800];
118
- return EditorView.theme({
119
- ".cm-merge-safe-line": {
120
- backgroundColor: `${line(colors.green[500], colors.green[100])} !important`,
121
- boxShadow: `inset 3px 0 0 ${colors.green[500]}`
122
- },
123
- ".cm-merge-conflict-line": {
124
- backgroundColor: `${line(colors.warning[500], colors.warning[100])} !important`,
125
- boxShadow: `inset 3px 0 0 ${colors.warning[500]}`
126
- },
127
- ".cm-merge-safe-gutter": {
128
- backgroundColor: `${gutter(colors.green[500], colors.green[200])} !important`,
129
- color: safeNumber
130
- },
131
- ".cm-merge-conflict-gutter": {
132
- backgroundColor: `${gutter(colors.warning[500], colors.warning[200])} !important`,
133
- color: conflictNumber
134
- }
135
- });
496
+ const DARK_LINE_ALPHA = "29";
497
+ const DARK_GUTTER_ALPHA = "47";
498
+ /**
499
+ * The highlight palette, split out of the StateField above so it can be built
500
+ * through `useThemedExtension` — the field instance must stay stable across a
501
+ * scheme change (a fresh one would drop the current highlights), the colours
502
+ * must not.
503
+ *
504
+ * `!important` overrides CodeMirror's built-in active-line and selection
505
+ * backgrounds. SAFE = change present on one side only (green). CONFLICT = both
506
+ * sides edited this region (amber/warning — NOT red, since red reads as
507
+ * "deletion" and the 3-pane editor only ever displays additions in each side
508
+ * pane). The colored left border doubles as a scan-lane so changes are easy to
509
+ * spot when zoomed out.
510
+ *
511
+ * Light mode paints an opaque pastel wash. Dark mode tints the same hue at low
512
+ * alpha over the pane's token-driven surface instead — the pastel is opaque, so
513
+ * it put the dark scheme's near-white line text and grey line numbers on a
514
+ * light slab.
515
+ *
516
+ * A pure function of `scheme`, which `useThemedExtension` passes from the same
517
+ * read that produced its cache key.
518
+ */
519
+ const buildDiffHighlightTheme = (scheme) => {
520
+ const dark = scheme === "dark";
521
+ const line = (hue, pastel) => dark ? `${hue}${DARK_LINE_ALPHA}` : pastel;
522
+ const gutter = (hue, pastel) => dark ? `${hue}${DARK_GUTTER_ALPHA}` : pastel;
523
+ const safeNumber = dark ? colors.green[300] : colors.green[900];
524
+ const conflictNumber = dark ? colors.warning[300] : colors.warning[800];
525
+ return EditorView.theme({
526
+ ".cm-merge-safe-line": {
527
+ backgroundColor: `${line(colors.green[500], colors.green[100])} !important`,
528
+ boxShadow: `inset 3px 0 0 ${colors.green[500]}`
529
+ },
530
+ ".cm-merge-conflict-line": {
531
+ backgroundColor: `${line(colors.warning[500], colors.warning[100])} !important`,
532
+ boxShadow: `inset 3px 0 0 ${colors.warning[500]}`
533
+ },
534
+ ".cm-merge-safe-gutter": {
535
+ backgroundColor: `${gutter(colors.green[500], colors.green[200])} !important`,
536
+ color: safeNumber
537
+ },
538
+ ".cm-merge-conflict-gutter": {
539
+ backgroundColor: `${gutter(colors.warning[500], colors.warning[200])} !important`,
540
+ color: conflictNumber
541
+ }
542
+ });
136
543
  };
137
- var updateHighlightedLines = (view, lines, classification) => {
138
- view.dispatch({ effects: setHighlightedLines.of({ lines, classification }) });
544
+ const updateHighlightedLines = (view, lines, classification) => {
545
+ view.dispatch({ effects: setHighlightedLines.of({
546
+ lines,
547
+ classification
548
+ }) });
139
549
  };
140
- var EMPTY_LINES = /* @__PURE__ */ new Set();
141
- var EMPTY_CLASSIFICATION = /* @__PURE__ */ new Map();
142
- var MergePane = ({
143
- value,
144
- highlightedLines,
145
- lineClassification,
146
- readOnly = false,
147
- onChange,
148
- header,
149
- headerClassName,
150
- className,
151
- onScrollDOMReady,
152
- deleted = false
153
- }) => {
154
- const editorRef = useRef(null);
155
- const handleChange = useStableCallback((next) => onChange?.(next));
156
- const themeExtension = useThemedExtension(`merge-pane:${deleted}`, () => {
157
- const dark = isDarkScheme();
158
- const deletedSurface = dark ? `${colors.error[500]}1f` : colors.error[100];
159
- const deletedGutter = dark ? `${colors.error[500]}3d` : colors.error[200];
160
- const deletedGutterText = dark ? colors.error[300] : colors.error[700];
161
- return EditorView.theme({
162
- "&.cm-editor": {
163
- height: "100%",
164
- backgroundColor: deleted ? deletedSurface : resolveToken("background", "249 250 251"),
165
- // Pair the token-driven surface with a token-driven text color so line
166
- // content stays readable when the pane's `--background` goes dark.
167
- color: resolveToken("foreground", "30 41 59"),
168
- outline: "none"
169
- },
170
- ".cm-gutters": {
171
- backgroundColor: deleted ? deletedGutter : resolveToken("muted", "241 245 249"),
172
- color: deleted ? deletedGutterText : resolveToken("muted-foreground", "100 116 139")
173
- },
174
- "*": { lineHeight: `${LINE_HEIGHT_PX}px` },
175
- ".cm-lineNumbers .cm-gutterElement": { padding: "0 0 0 25px" }
176
- });
177
- });
178
- const diffHighlightExtension = useMemo(() => createDiffHighlightExtension(), []);
179
- const diffHighlightTheme = useThemedExtension("merge-diff-highlight", buildDiffHighlightTheme);
180
- const basicSetup = useMemo(
181
- () => ({ ...buildBasicSetup(readOnly), lineNumbers: true }),
182
- [readOnly]
183
- );
184
- const extensions = useMemo(
185
- () => [
186
- diffHighlightExtension,
187
- diffHighlightTheme,
188
- themeExtension,
189
- // Recalc viewport after every doc change so late-settling layouts (alerts
190
- // appearing above the editor) don't leave trailing lines blank.
191
- EditorView.updateListener.of((update) => {
192
- if (update.docChanged) {
193
- requestAnimationFrame(() => update.view.dispatch({}));
194
- }
195
- })
196
- ],
197
- [diffHighlightExtension, diffHighlightTheme, themeExtension]
198
- );
199
- useEffect(() => {
200
- const view = editorRef.current?.view;
201
- if (!view) return;
202
- updateHighlightedLines(
203
- view,
204
- deleted ? EMPTY_LINES : highlightedLines,
205
- deleted ? EMPTY_CLASSIFICATION : lineClassification
206
- );
207
- }, [highlightedLines, lineClassification, deleted]);
208
- const handleCreateEditor = useCallback(
209
- (view) => {
210
- updateHighlightedLines(
211
- view,
212
- deleted ? EMPTY_LINES : highlightedLines,
213
- deleted ? EMPTY_CLASSIFICATION : lineClassification
214
- );
215
- onScrollDOMReady?.(view.scrollDOM);
216
- },
217
- [highlightedLines, lineClassification, onScrollDOMReady, deleted]
218
- );
219
- useEffect(() => {
220
- return () => onScrollDOMReady?.(null);
221
- }, [onScrollDOMReady]);
222
- useEffect(() => {
223
- const view = editorRef.current?.view;
224
- const wrapper = view?.dom.parentElement;
225
- if (!view || !wrapper) return;
226
- const observer = new ResizeObserver(() => view.dispatch({}));
227
- observer.observe(wrapper);
228
- return () => observer.disconnect();
229
- }, []);
230
- return /* @__PURE__ */ jsxs(
231
- "div",
232
- {
233
- className: cn(
234
- "tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:overflow-hidden",
235
- className,
236
- deleted && "tw:border-error-300 tw:[[data-theme=dark]_&]:border-error-500/50"
237
- ),
238
- children: [
239
- header && /* @__PURE__ */ jsx(
240
- "div",
241
- {
242
- className: cn(
243
- "tw:px-4 tw:py-3",
244
- // Same light/dark split as the editor wash below — `PaneHeader` pins
245
- // `text-foreground`, which goes near-white and vanishes on the
246
- // opaque light-red band.
247
- deleted ? "tw:border-b tw:border-error-200 tw:bg-error-100 tw:[[data-theme=dark]_&]:border-error-500/30 tw:[[data-theme=dark]_&]:bg-error-500/15" : "tw:bg-background",
248
- headerClassName
249
- ),
250
- children: header
251
- }
252
- ),
253
- /* @__PURE__ */ jsx("div", { className: "tw:flex tw:h-0 tw:flex-1 tw:flex-col tw:[&_>div]:h-full", children: /* @__PURE__ */ jsx(
254
- CodeMirror,
255
- {
256
- ref: editorRef,
257
- height: "100%",
258
- value,
259
- onChange: handleChange,
260
- extensions,
261
- readOnly,
262
- onCreateEditor: handleCreateEditor,
263
- basicSetup
264
- }
265
- ) })
266
- ]
267
- }
268
- );
550
+ //#endregion
551
+ //#region src/components/MergeEditor/MergePane.tsx
552
+ const EMPTY_LINES$1 = /* @__PURE__ */ new Set();
553
+ const EMPTY_CLASSIFICATION$1 = /* @__PURE__ */ new Map();
554
+ const MergePane = ({ value, highlightedLines, lineClassification, readOnly = false, onChange, header, headerClassName, className, onScrollDOMReady, deleted = false }) => {
555
+ const editorRef = useRef(null);
556
+ const handleChange = useStableCallback((next) => onChange?.(next));
557
+ const themeExtension = useThemedExtension(`merge-pane:${deleted}`, (scheme) => {
558
+ const dark = scheme === "dark";
559
+ const deletedSurface = dark ? `${colors.error[500]}1f` : colors.error[100];
560
+ const deletedGutter = dark ? `${colors.error[500]}3d` : colors.error[200];
561
+ const deletedGutterText = dark ? colors.error[300] : colors.error[700];
562
+ return EditorView.theme({
563
+ "&.cm-editor": {
564
+ height: "100%",
565
+ backgroundColor: deleted ? deletedSurface : resolveToken("background", "249 250 251"),
566
+ color: resolveToken("foreground", "30 41 59"),
567
+ outline: "none"
568
+ },
569
+ ".cm-gutters": {
570
+ backgroundColor: deleted ? deletedGutter : resolveToken("muted", "241 245 249"),
571
+ color: deleted ? deletedGutterText : resolveToken("muted-foreground", "100 116 139")
572
+ },
573
+ "*": { lineHeight: `20px` },
574
+ ".cm-lineNumbers .cm-gutterElement": { padding: "0 0 0 25px" }
575
+ });
576
+ });
577
+ const diffHighlightExtension = useMemo(() => createDiffHighlightExtension(), []);
578
+ const diffHighlightTheme = useThemedExtension("merge-diff-highlight", buildDiffHighlightTheme);
579
+ const basicSetup = useMemo(() => ({
580
+ ...buildBasicSetup(readOnly),
581
+ lineNumbers: true
582
+ }), [readOnly]);
583
+ const extensions = useMemo(() => [
584
+ diffHighlightExtension,
585
+ diffHighlightTheme,
586
+ themeExtension,
587
+ EditorView.updateListener.of((update) => {
588
+ if (update.docChanged) requestAnimationFrame(() => update.view.dispatch({}));
589
+ })
590
+ ], [
591
+ diffHighlightExtension,
592
+ diffHighlightTheme,
593
+ themeExtension
594
+ ]);
595
+ useEffect(() => {
596
+ const view = editorRef.current?.view;
597
+ if (!view) return;
598
+ updateHighlightedLines(view, deleted ? EMPTY_LINES$1 : highlightedLines, deleted ? EMPTY_CLASSIFICATION$1 : lineClassification);
599
+ }, [
600
+ highlightedLines,
601
+ lineClassification,
602
+ deleted
603
+ ]);
604
+ const handleCreateEditor = useCallback((view) => {
605
+ updateHighlightedLines(view, deleted ? EMPTY_LINES$1 : highlightedLines, deleted ? EMPTY_CLASSIFICATION$1 : lineClassification);
606
+ onScrollDOMReady?.(view.scrollDOM);
607
+ }, [
608
+ highlightedLines,
609
+ lineClassification,
610
+ onScrollDOMReady,
611
+ deleted
612
+ ]);
613
+ useEffect(() => {
614
+ return () => onScrollDOMReady?.(null);
615
+ }, [onScrollDOMReady]);
616
+ useEffect(() => {
617
+ const view = editorRef.current?.view;
618
+ const wrapper = view?.dom.parentElement;
619
+ if (!view || !wrapper) return;
620
+ const observer = new ResizeObserver(() => view.dispatch({}));
621
+ observer.observe(wrapper);
622
+ return () => observer.disconnect();
623
+ }, []);
624
+ return /* @__PURE__ */ jsxs("div", {
625
+ className: cn("tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:overflow-hidden", className, deleted && "tw:border-error-300 tw:[[data-theme=dark]_&]:border-error-500/50"),
626
+ children: [header && /* @__PURE__ */ jsx("div", {
627
+ className: cn("tw:px-4 tw:py-3", deleted ? "tw:border-b tw:border-error-200 tw:bg-error-100 tw:[[data-theme=dark]_&]:border-error-500/30 tw:[[data-theme=dark]_&]:bg-error-500/15" : "tw:bg-background", headerClassName),
628
+ children: header
629
+ }), /* @__PURE__ */ jsx("div", {
630
+ className: "tw:flex tw:h-0 tw:flex-1 tw:flex-col tw:[&_>div]:h-full",
631
+ children: /* @__PURE__ */ jsx(CodeMirror, {
632
+ ref: editorRef,
633
+ height: "100%",
634
+ value,
635
+ onChange: handleChange,
636
+ extensions,
637
+ readOnly,
638
+ onCreateEditor: handleCreateEditor,
639
+ basicSetup
640
+ })
641
+ })]
642
+ });
269
643
  };
270
- var useScrollSync = () => {
271
- const scrollersRef = useRef([]);
272
- const followersRef = useRef(/* @__PURE__ */ new Map());
273
- const isSyncingRef = useRef(false);
274
- const scrollerCallbacksRef = useRef(/* @__PURE__ */ new Map());
275
- const followerCallbacksRef = useRef(/* @__PURE__ */ new Map());
276
- const updateFollowers = useCallback(() => {
277
- for (const [, { paneIndex, el }] of followersRef.current) {
278
- const scroller = scrollersRef.current[paneIndex];
279
- if (!scroller) continue;
280
- el.style.transform = `translateY(-${scroller.scrollTop}px)`;
281
- }
282
- }, []);
283
- const handleScroll = useCallback(
284
- (e) => {
285
- if (isSyncingRef.current) return;
286
- isSyncingRef.current = true;
287
- const sourceScrollTop = e.target.scrollTop;
288
- for (const scroller of scrollersRef.current) {
289
- if (!scroller || scroller === e.target) continue;
290
- const targetMax = Math.max(0, scroller.scrollHeight - scroller.clientHeight);
291
- scroller.scrollTop = Math.min(sourceScrollTop, targetMax);
292
- }
293
- updateFollowers();
294
- isSyncingRef.current = false;
295
- },
296
- [updateFollowers]
297
- );
298
- const registerScroller = useCallback(
299
- (index) => {
300
- const existing = scrollerCallbacksRef.current.get(index);
301
- if (existing) return existing;
302
- const callback = (el) => {
303
- const prev = scrollersRef.current[index];
304
- if (prev === el) return;
305
- prev?.removeEventListener("scroll", handleScroll);
306
- scrollersRef.current[index] = el;
307
- el?.addEventListener("scroll", handleScroll, { passive: true });
308
- };
309
- scrollerCallbacksRef.current.set(index, callback);
310
- return callback;
311
- },
312
- [handleScroll]
313
- );
314
- const registerFollower = useCallback((paneIndex, key) => {
315
- const existing = followerCallbacksRef.current.get(key);
316
- if (existing) return existing;
317
- const callback = (el) => {
318
- if (el) {
319
- followersRef.current.set(key, { paneIndex, el });
320
- } else {
321
- followersRef.current.delete(key);
322
- }
323
- };
324
- followerCallbacksRef.current.set(key, callback);
325
- return callback;
326
- }, []);
327
- return { registerScroller, registerFollower };
644
+ //#endregion
645
+ //#region src/components/MergeEditor/useScrollSync.ts
646
+ const useScrollSync = () => {
647
+ const scrollersRef = useRef([]);
648
+ const followersRef = useRef(/* @__PURE__ */ new Map());
649
+ const isSyncingRef = useRef(false);
650
+ const scrollerCallbacksRef = useRef(/* @__PURE__ */ new Map());
651
+ const followerCallbacksRef = useRef(/* @__PURE__ */ new Map());
652
+ const updateFollowers = useCallback(() => {
653
+ for (const [, { paneIndex, el }] of followersRef.current) {
654
+ const scroller = scrollersRef.current[paneIndex];
655
+ if (!scroller) continue;
656
+ el.style.transform = `translateY(-${scroller.scrollTop}px)`;
657
+ }
658
+ }, []);
659
+ const handleScroll = useCallback((e) => {
660
+ if (isSyncingRef.current) return;
661
+ isSyncingRef.current = true;
662
+ const sourceScrollTop = e.target.scrollTop;
663
+ for (const scroller of scrollersRef.current) {
664
+ if (!scroller || scroller === e.target) continue;
665
+ const targetMax = Math.max(0, scroller.scrollHeight - scroller.clientHeight);
666
+ scroller.scrollTop = Math.min(sourceScrollTop, targetMax);
667
+ }
668
+ updateFollowers();
669
+ isSyncingRef.current = false;
670
+ }, [updateFollowers]);
671
+ return {
672
+ registerScroller: useCallback((index) => {
673
+ const existing = scrollerCallbacksRef.current.get(index);
674
+ if (existing) return existing;
675
+ const callback = (el) => {
676
+ const prev = scrollersRef.current[index];
677
+ if (prev === el) return;
678
+ prev?.removeEventListener("scroll", handleScroll);
679
+ scrollersRef.current[index] = el;
680
+ el?.addEventListener("scroll", handleScroll, { passive: true });
681
+ };
682
+ scrollerCallbacksRef.current.set(index, callback);
683
+ return callback;
684
+ }, [handleScroll]),
685
+ registerFollower: useCallback((paneIndex, key) => {
686
+ const existing = followerCallbacksRef.current.get(key);
687
+ if (existing) return existing;
688
+ const callback = (el) => {
689
+ if (el) followersRef.current.set(key, {
690
+ paneIndex,
691
+ el
692
+ });
693
+ else followersRef.current.delete(key);
694
+ };
695
+ followerCallbacksRef.current.set(key, callback);
696
+ return callback;
697
+ }, [])
698
+ };
328
699
  };
329
- var EMPTY_LINES2 = /* @__PURE__ */ new Set();
330
- var EMPTY_CLASSIFICATION2 = /* @__PURE__ */ new Map();
331
- var MergeEditor = ({
332
- mergeValue,
333
- handleMergeChange,
334
- leftText,
335
- rightText,
336
- leftConflicts,
337
- rightConflicts,
338
- leftHighlightedLines,
339
- rightHighlightedLines,
340
- leftClassification,
341
- rightClassification,
342
- mergeHighlightedLines,
343
- mergeClassification,
344
- acceptLeft,
345
- acceptRight,
346
- dismissLeft,
347
- dismissRight,
348
- leftHeader,
349
- middleHeader,
350
- middleHeaderClassName,
351
- middleClassName,
352
- rightHeader,
353
- className,
354
- leftDeleted = false,
355
- rightDeleted = false
356
- }) => {
357
- const { registerScroller, registerFollower } = useScrollSync();
358
- const anySideDeleted = leftDeleted || rightDeleted;
359
- return /* @__PURE__ */ jsxs(
360
- "div",
361
- {
362
- className: cn(
363
- "tw:flex tw:h-full tw:min-h-0 tw:overflow-hidden tw:bg-background tw:gap-3",
364
- className
365
- ),
366
- children: [
367
- /* @__PURE__ */ jsx(
368
- MergePane,
369
- {
370
- value: leftText,
371
- highlightedLines: leftHighlightedLines,
372
- lineClassification: leftClassification,
373
- readOnly: true,
374
- header: leftHeader,
375
- className: "tw:rounded-r-lg tw:border tw:border-border",
376
- onScrollDOMReady: registerScroller(0),
377
- deleted: leftDeleted
378
- }
379
- ),
380
- /* @__PURE__ */ jsx(
381
- AcceptControls,
382
- {
383
- conflicts: leftDeleted ? [] : leftConflicts,
384
- side: "left",
385
- onAccept: acceptLeft,
386
- onDismiss: dismissLeft,
387
- contentRef: registerFollower(0, "left-controls")
388
- }
389
- ),
390
- /* @__PURE__ */ jsx(
391
- MergePane,
392
- {
393
- value: mergeValue,
394
- highlightedLines: anySideDeleted ? EMPTY_LINES2 : mergeHighlightedLines,
395
- lineClassification: anySideDeleted ? EMPTY_CLASSIFICATION2 : mergeClassification,
396
- onChange: handleMergeChange,
397
- header: middleHeader,
398
- headerClassName: middleHeaderClassName,
399
- className: cn("tw:border tw:border-border tw:rounded-lg", middleClassName),
400
- onScrollDOMReady: registerScroller(1)
401
- }
402
- ),
403
- /* @__PURE__ */ jsx(
404
- AcceptControls,
405
- {
406
- conflicts: rightDeleted ? [] : rightConflicts,
407
- side: "right",
408
- onAccept: acceptRight,
409
- onDismiss: dismissRight,
410
- contentRef: registerFollower(2, "right-controls")
411
- }
412
- ),
413
- /* @__PURE__ */ jsx(
414
- MergePane,
415
- {
416
- value: rightText,
417
- highlightedLines: rightHighlightedLines,
418
- lineClassification: rightClassification,
419
- readOnly: true,
420
- header: rightHeader,
421
- className: "tw:rounded-l-lg tw:border tw:border-border",
422
- onScrollDOMReady: registerScroller(2),
423
- deleted: rightDeleted
424
- }
425
- )
426
- ]
427
- }
428
- );
700
+ //#endregion
701
+ //#region src/components/MergeEditor/MergeEditor.tsx
702
+ const EMPTY_LINES = /* @__PURE__ */ new Set();
703
+ const EMPTY_CLASSIFICATION = /* @__PURE__ */ new Map();
704
+ const MergeEditor = ({ mergeValue, handleMergeChange, leftText, rightText, leftConflicts, rightConflicts, leftHighlightedLines, rightHighlightedLines, leftClassification, rightClassification, mergeHighlightedLines, mergeClassification, acceptLeft, acceptRight, dismissLeft, dismissRight, leftHeader, middleHeader, middleHeaderClassName, middleClassName, rightHeader, className, leftDeleted = false, rightDeleted = false }) => {
705
+ const { registerScroller, registerFollower } = useScrollSync();
706
+ const anySideDeleted = leftDeleted || rightDeleted;
707
+ return /* @__PURE__ */ jsxs("div", {
708
+ className: cn("tw:flex tw:h-full tw:min-h-0 tw:overflow-hidden tw:bg-background tw:gap-3", className),
709
+ children: [
710
+ /* @__PURE__ */ jsx(MergePane, {
711
+ value: leftText,
712
+ highlightedLines: leftHighlightedLines,
713
+ lineClassification: leftClassification,
714
+ readOnly: true,
715
+ header: leftHeader,
716
+ className: "tw:rounded-r-lg tw:border tw:border-border",
717
+ onScrollDOMReady: registerScroller(0),
718
+ deleted: leftDeleted
719
+ }),
720
+ /* @__PURE__ */ jsx(AcceptControls, {
721
+ conflicts: leftDeleted ? [] : leftConflicts,
722
+ side: "left",
723
+ onAccept: acceptLeft,
724
+ onDismiss: dismissLeft,
725
+ contentRef: registerFollower(0, "left-controls")
726
+ }),
727
+ /* @__PURE__ */ jsx(MergePane, {
728
+ value: mergeValue,
729
+ highlightedLines: anySideDeleted ? EMPTY_LINES : mergeHighlightedLines,
730
+ lineClassification: anySideDeleted ? EMPTY_CLASSIFICATION : mergeClassification,
731
+ onChange: handleMergeChange,
732
+ header: middleHeader,
733
+ headerClassName: middleHeaderClassName,
734
+ className: cn("tw:border tw:border-border tw:rounded-lg", middleClassName),
735
+ onScrollDOMReady: registerScroller(1)
736
+ }),
737
+ /* @__PURE__ */ jsx(AcceptControls, {
738
+ conflicts: rightDeleted ? [] : rightConflicts,
739
+ side: "right",
740
+ onAccept: acceptRight,
741
+ onDismiss: dismissRight,
742
+ contentRef: registerFollower(2, "right-controls")
743
+ }),
744
+ /* @__PURE__ */ jsx(MergePane, {
745
+ value: rightText,
746
+ highlightedLines: rightHighlightedLines,
747
+ lineClassification: rightClassification,
748
+ readOnly: true,
749
+ header: rightHeader,
750
+ className: "tw:rounded-l-lg tw:border tw:border-border",
751
+ onScrollDOMReady: registerScroller(2),
752
+ deleted: rightDeleted
753
+ })
754
+ ]
755
+ });
429
756
  };
757
+ //#endregion
758
+ export { CodeEditor, LANGUAGE_MODES, MergeEditor, SqlEditor, isLanguageMode };
430
759
 
431
- export { MergeEditor };
432
- //# sourceMappingURL=editors.js.map
433
760
  //# sourceMappingURL=editors.js.map