@keboola/design 11.2.0 → 11.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (233) hide show
  1. package/AGENTS.md +25 -14
  2. package/CHANGELOG.md +254 -0
  3. package/COMPONENT-API.md +1 -1
  4. package/dist/{AIKit-DiS0CVOW.js → AIKit-DaFT7p92.js} +23 -22
  5. package/dist/AIKit-DaFT7p92.js.map +1 -0
  6. package/dist/{Alert-DfZq9kGe.js → Alert-CseY3yAj.js} +3 -3
  7. package/dist/{Alert-DfZq9kGe.js.map → Alert-CseY3yAj.js.map} +1 -1
  8. package/dist/{AlertModal-Dp_XuJBW.js → AlertModal-DQAGpsEy.js} +3 -3
  9. package/dist/{AlertModal-Dp_XuJBW.js.map → AlertModal-DQAGpsEy.js.map} +1 -1
  10. package/dist/{AppShell-B5GQN6Zs.js → AppShell-BUoxM3fv.js} +29 -10
  11. package/dist/AppShell-BUoxM3fv.js.map +1 -0
  12. package/dist/{BrandEditor-DyzgfVkl.js → BrandEditor-BnTLMRMp.js} +6 -6
  13. package/dist/{BrandEditor-DyzgfVkl.js.map → BrandEditor-BnTLMRMp.js.map} +1 -1
  14. package/dist/{BrandLogo-CJkRd0F8.js → BrandLogo-V2pRUAeO.js} +2 -2
  15. package/dist/{BrandLogo-CJkRd0F8.js.map → BrandLogo-V2pRUAeO.js.map} +1 -1
  16. package/dist/{Breadcrumb-Frst8MTA.js → Breadcrumb-CQTPn_KB.js} +3 -3
  17. package/dist/{Breadcrumb-Frst8MTA.js.map → Breadcrumb-CQTPn_KB.js.map} +1 -1
  18. package/dist/{Button-6xBX0nNl.js → Button-CPsEQuTN.js} +2 -2
  19. package/dist/{Button-6xBX0nNl.js.map → Button-CPsEQuTN.js.map} +1 -1
  20. package/dist/{Card-BAoZ35CV.js → Card-Cd5HSBmv.js} +2 -2
  21. package/dist/{Card-BAoZ35CV.js.map → Card-Cd5HSBmv.js.map} +1 -1
  22. package/dist/{Checkbox-GJ8-srt4.js → Checkbox-5VNCcV7E.js} +3 -3
  23. package/dist/{Checkbox-GJ8-srt4.js.map → Checkbox-5VNCcV7E.js.map} +1 -1
  24. package/dist/{Clipboard-CBJZiviP.js → Clipboard-B7rckqV_.js} +2 -2
  25. package/dist/{Clipboard-CBJZiviP.js.map → Clipboard-B7rckqV_.js.map} +1 -1
  26. package/dist/{ClipboardButton-ClcluT0C.js → ClipboardButton-CQ6Aewpg.js} +3 -3
  27. package/dist/{ClipboardButton-ClcluT0C.js.map → ClipboardButton-CQ6Aewpg.js.map} +1 -1
  28. package/dist/{CodeEditor-DyaN-Ij2.js → CodeEditor-CUse8znx.js} +237 -95
  29. package/dist/CodeEditor-CUse8znx.js.map +1 -0
  30. package/dist/{ColorInput-B8z4j4Y_.js → ColorInput-Q1D9Vcc_.js} +3 -3
  31. package/dist/{ColorInput-B8z4j4Y_.js.map → ColorInput-Q1D9Vcc_.js.map} +1 -1
  32. package/dist/{ColorModeSwitch-dZFZyqy1.js → ColorModeSwitch-B5PXCVqB.js} +3 -3
  33. package/dist/{ColorModeSwitch-dZFZyqy1.js.map → ColorModeSwitch-B5PXCVqB.js.map} +1 -1
  34. package/dist/{Combobox-Dgm6Z4ib.js → Combobox-CyoRA7oY.js} +5 -5
  35. package/dist/Combobox-CyoRA7oY.js.map +1 -0
  36. package/dist/{Command-C0aZfVTq.js → Command-Ds68v2rX.js} +3 -3
  37. package/dist/{Command-C0aZfVTq.js.map → Command-Ds68v2rX.js.map} +1 -1
  38. package/dist/{CopyField-BJ96zvXs.js → CopyField-DI66uY_g.js} +2 -2
  39. package/dist/{CopyField-BJ96zvXs.js.map → CopyField-DI66uY_g.js.map} +1 -1
  40. package/dist/{DateInput-B3UdzRfW.js → DateInput-BPj2pzsn.js} +4 -4
  41. package/dist/{DateInput-B3UdzRfW.js.map → DateInput-BPj2pzsn.js.map} +1 -1
  42. package/dist/{DatePicker-Dw3DpbUh.js → DatePicker-DyEGuW9m.js} +2 -2
  43. package/dist/{DatePicker-Dw3DpbUh.js.map → DatePicker-DyEGuW9m.js.map} +1 -1
  44. package/dist/{DateRangeInput-DTuySEiq.js → DateRangeInput-u9DxNbHW.js} +4 -4
  45. package/dist/{DateRangeInput-DTuySEiq.js.map → DateRangeInput-u9DxNbHW.js.map} +1 -1
  46. package/dist/{DateRangePicker-DCmMHg4s.js → DateRangePicker-CYYhX6S7.js} +6 -6
  47. package/dist/{DateRangePicker-DCmMHg4s.js.map → DateRangePicker-CYYhX6S7.js.map} +1 -1
  48. package/dist/{DropdownMenu-t90tVw6l.js → DropdownMenu-DpMEcyCq.js} +2 -2
  49. package/dist/{DropdownMenu-t90tVw6l.js.map → DropdownMenu-DpMEcyCq.js.map} +1 -1
  50. package/dist/{FieldItem-D-h1NeBo.js → FieldItem-qQKGU9lF.js} +3 -3
  51. package/dist/{FieldItem-D-h1NeBo.js.map → FieldItem-qQKGU9lF.js.map} +1 -1
  52. package/dist/{FieldItem-CAPj9lj3.d.ts → FieldItem-vhIJW4pj.d.ts} +2 -10
  53. package/dist/{FileUpload-BRv0TaZk.js → FileUpload-C336MVnU.js} +2 -2
  54. package/dist/{FileUpload-BRv0TaZk.js.map → FileUpload-C336MVnU.js.map} +1 -1
  55. package/dist/{Form-DHvcFoEi.js → Form-CTygENDc.js} +8 -8
  56. package/dist/{Form-DHvcFoEi.js.map → Form-CTygENDc.js.map} +1 -1
  57. package/dist/{FormGroup-C41n65cE.js → FormGroup-BnwP0jNu.js} +3 -3
  58. package/dist/{FormGroup-C41n65cE.js.map → FormGroup-BnwP0jNu.js.map} +1 -1
  59. package/dist/{FullScreenModal-Cb3PGgh4.js → FullScreenModal-j-M4aPFd.js} +3 -3
  60. package/dist/{FullScreenModal-Cb3PGgh4.js.map → FullScreenModal-j-M4aPFd.js.map} +1 -1
  61. package/dist/{HoverCard-WfDkLK1s.js → HoverCard-yQq-O49c.js} +2 -2
  62. package/dist/{HoverCard-WfDkLK1s.js.map → HoverCard-yQq-O49c.js.map} +1 -1
  63. package/dist/{InputGroup-CdTq8H7c.js → InputGroup-D7zlmqPB.js} +3 -3
  64. package/dist/{InputGroup-CdTq8H7c.js.map → InputGroup-D7zlmqPB.js.map} +1 -1
  65. package/dist/{Kbd-CxHAo1oo.js → Kbd-D6LpR7G2.js} +2 -2
  66. package/dist/{Kbd-CxHAo1oo.js.map → Kbd-D6LpR7G2.js.map} +1 -1
  67. package/dist/{MermaidDiagram-ChL3WIQT.js → MermaidDiagram-JlvuGcY-.js} +6 -87
  68. package/dist/MermaidDiagram-JlvuGcY-.js.map +1 -0
  69. package/dist/{Modal-wqG8nJiK.js → Modal-o4ATIexE.js} +3 -3
  70. package/dist/{Modal-wqG8nJiK.js.map → Modal-o4ATIexE.js.map} +1 -1
  71. package/dist/{MultiActionButtonGroup-BiIIubiL.js → MultiActionButtonGroup-GTeFk-L8.js} +3 -3
  72. package/dist/{MultiActionButtonGroup-BiIIubiL.js.map → MultiActionButtonGroup-GTeFk-L8.js.map} +1 -1
  73. package/dist/{Navbar-BfaPeLUL.js → Navbar-CAQs4BZz.js} +2 -2
  74. package/dist/{Navbar-BfaPeLUL.js.map → Navbar-CAQs4BZz.js.map} +1 -1
  75. package/dist/{PageToolbar-OQg3mPF-.js → PageToolbar-bG2YtSa3.js} +3 -3
  76. package/dist/{PageToolbar-OQg3mPF-.js.map → PageToolbar-bG2YtSa3.js.map} +1 -1
  77. package/dist/{Pagination-Cjfda8KG.js → Pagination-BB3X7ooY.js} +2 -2
  78. package/dist/{Pagination-Cjfda8KG.js.map → Pagination-BB3X7ooY.js.map} +1 -1
  79. package/dist/{Popconfirm-D7_vfxFd.js → Popconfirm-C2Ky5hJO.js} +3 -3
  80. package/dist/{Popconfirm-D7_vfxFd.js.map → Popconfirm-C2Ky5hJO.js.map} +1 -1
  81. package/dist/{Popover-CzeHjvrB.js → Popover-DsbI2HKu.js} +2 -2
  82. package/dist/{Popover-CzeHjvrB.js.map → Popover-DsbI2HKu.js.map} +1 -1
  83. package/dist/{RadioGroup-sIveSsNa.js → RadioGroup-BMxuZEbT.js} +3 -3
  84. package/dist/{RadioGroup-sIveSsNa.js.map → RadioGroup-BMxuZEbT.js.map} +1 -1
  85. package/dist/{Search-3UiqNZRj.js → Search-DFeECt5D.js} +2 -2
  86. package/dist/{Search-3UiqNZRj.js.map → Search-DFeECt5D.js.map} +1 -1
  87. package/dist/{SearchInput-C7dF_Ir-.js → SearchInput-CCpdUego.js} +3 -3
  88. package/dist/{SearchInput-C7dF_Ir-.js.map → SearchInput-CCpdUego.js.map} +1 -1
  89. package/dist/{SectionNav-8NoTOKO8.js → SectionNav-Bw_MVL0_.js} +4 -4
  90. package/dist/{SectionNav-8NoTOKO8.js.map → SectionNav-Bw_MVL0_.js.map} +1 -1
  91. package/dist/{Select-Is0VkePH.js → Select-D6IZVvwL.js} +5 -5
  92. package/dist/Select-D6IZVvwL.js.map +1 -0
  93. package/dist/{Sheet-Dw9BDvjI.js → Sheet-BIzs2K2H.js} +3 -3
  94. package/dist/{Sheet-Dw9BDvjI.js.map → Sheet-BIzs2K2H.js.map} +1 -1
  95. package/dist/{Sidebar-Dcb4rinA.js → Sidebar-r1TW4g_b.js} +5 -5
  96. package/dist/{Sidebar-Dcb4rinA.js.map → Sidebar-r1TW4g_b.js.map} +1 -1
  97. package/dist/{Slider-BOPfMOMm.js → Slider-CjxyfEty.js} +3 -3
  98. package/dist/{Slider-BOPfMOMm.js.map → Slider-CjxyfEty.js.map} +1 -1
  99. package/dist/{Switch-CX2A0v50.js → Switch-BueTV03C.js} +2 -2
  100. package/dist/{Switch-CX2A0v50.js.map → Switch-BueTV03C.js.map} +1 -1
  101. package/dist/{Tabs-UMQuDoW8.js → Tabs-l72-WuhK.js} +2 -2
  102. package/dist/{Tabs-UMQuDoW8.js.map → Tabs-l72-WuhK.js.map} +1 -1
  103. package/dist/{TextInput-CMuN1WfY.js → TextInput-DhdRk8qm.js} +3 -3
  104. package/dist/{TextInput-CMuN1WfY.js.map → TextInput-DhdRk8qm.js.map} +1 -1
  105. package/dist/{ThemeProvider-QncUrfJn.js → ThemeProvider-DZfGdf1v.js} +5 -4
  106. package/dist/{ThemeProvider-QncUrfJn.js.map → ThemeProvider-DZfGdf1v.js.map} +1 -1
  107. package/dist/{TimePicker-D9zktB8A.js → TimePicker-B6d2rAbX.js} +2 -2
  108. package/dist/{TimePicker-D9zktB8A.js.map → TimePicker-B6d2rAbX.js.map} +1 -1
  109. package/dist/{Toast-DQSbs3oA.js → Toast-CxXUulYN.js} +2 -2
  110. package/dist/{Toast-DQSbs3oA.js.map → Toast-CxXUulYN.js.map} +1 -1
  111. package/dist/{ZoomableSvg-CZEu6sAq.js → ZoomableSvg-CNIzRHKH.js} +4 -4
  112. package/dist/{ZoomableSvg-CZEu6sAq.js.map → ZoomableSvg-CNIzRHKH.js.map} +1 -1
  113. package/dist/{context-KxxeMHbR.js → context-BrNtMc1H.js} +3 -33
  114. package/dist/context-BrNtMc1H.js.map +1 -0
  115. package/dist/defaults-CTfvj2KB.js +34 -0
  116. package/dist/defaults-CTfvj2KB.js.map +1 -0
  117. package/dist/editors.d.ts +12 -2
  118. package/dist/editors.js +20 -12
  119. package/dist/editors.js.map +1 -1
  120. package/dist/flint.d.ts +15 -0
  121. package/dist/flint.js +212 -0
  122. package/dist/flint.js.map +1 -0
  123. package/dist/index.d.ts +49 -7
  124. package/dist/index.js +57 -55
  125. package/dist/internal/blocks/AIKit.js +1 -1
  126. package/dist/internal/blocks/AppShell.js +2 -2
  127. package/dist/internal/blocks/BrandEditor.js +1 -1
  128. package/dist/internal/blocks/ChartPanel.js +1 -1
  129. package/dist/internal/blocks/ClipboardButton.js +1 -1
  130. package/dist/internal/blocks/ColorInput.js +1 -1
  131. package/dist/internal/blocks/ColorModeSwitch.js +1 -1
  132. package/dist/internal/blocks/Command.js +1 -1
  133. package/dist/internal/blocks/CopyField.js +1 -1
  134. package/dist/internal/blocks/DateInput.js +1 -1
  135. package/dist/internal/blocks/DateRangeInput.js +1 -1
  136. package/dist/{DiagramSkeleton-lwBS2YBa.js → internal/blocks/DiagramShared/DiagramSkeleton.js} +3 -3
  137. package/dist/internal/blocks/DiagramShared/DiagramSkeleton.js.map +1 -0
  138. package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
  139. package/dist/internal/blocks/ErrorState.js +1 -1
  140. package/dist/internal/blocks/ExportMenu.js +3 -3
  141. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
  142. package/dist/internal/blocks/Form.js +1 -1
  143. package/dist/internal/blocks/FormGroup.js +1 -1
  144. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  145. package/dist/internal/blocks/MultiCombobox.js +4 -3
  146. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  147. package/dist/internal/blocks/NumberInput.js +1 -1
  148. package/dist/internal/blocks/PageToolbar.js +1 -1
  149. package/dist/internal/blocks/PasswordInput.js +2 -2
  150. package/dist/internal/blocks/SearchInput.js +1 -1
  151. package/dist/internal/blocks/SearchInputWithNavigation.js +3 -3
  152. package/dist/internal/blocks/SectionNav.js +1 -1
  153. package/dist/internal/blocks/SplitButton.js +2 -2
  154. package/dist/internal/blocks/StatCard.js +1 -1
  155. package/dist/internal/blocks/TextInput.js +1 -1
  156. package/dist/internal/blocks/Textarea.js +1 -1
  157. package/dist/internal/blocks/TimeInput.js +3 -3
  158. package/dist/internal/components/Alert.js +1 -1
  159. package/dist/internal/components/AlertModal.js +1 -1
  160. package/dist/internal/components/Avatar.js +1 -1
  161. package/dist/internal/components/BrandLogo.js +1 -1
  162. package/dist/internal/components/Breadcrumb.js +1 -1
  163. package/dist/internal/components/Button.js +1 -1
  164. package/dist/internal/components/Card.js +1 -1
  165. package/dist/internal/components/Checkbox.js +1 -1
  166. package/dist/internal/components/Clipboard.js +1 -1
  167. package/dist/internal/components/CollapsiblePanel.js +1 -1
  168. package/dist/internal/components/Combobox.js +1 -1
  169. package/dist/internal/components/DatePicker.js +1 -1
  170. package/dist/internal/components/DateRangePicker.js +1 -1
  171. package/dist/internal/components/DropdownMenu.js +1 -1
  172. package/dist/internal/components/FileUpload.js +1 -1
  173. package/dist/internal/components/FullScreenModal.js +1 -1
  174. package/dist/internal/components/HoverCard.js +1 -1
  175. package/dist/internal/components/InputGroup.js +1 -1
  176. package/dist/internal/components/Kbd.js +1 -1
  177. package/dist/internal/components/Modal.js +1 -1
  178. package/dist/internal/components/Navbar.js +1 -1
  179. package/dist/internal/components/Pagination.js +1 -1
  180. package/dist/internal/components/Popconfirm.js +1 -1
  181. package/dist/internal/components/Popover.js +1 -1
  182. package/dist/internal/components/RadioGroup.js +1 -1
  183. package/dist/internal/components/Search.js +1 -1
  184. package/dist/internal/components/Select.js +1 -1
  185. package/dist/internal/components/Sheet.js +1 -1
  186. package/dist/internal/components/Sidebar.js +1 -1
  187. package/dist/internal/components/Slider.js +1 -1
  188. package/dist/internal/components/Switch.js +1 -1
  189. package/dist/internal/components/Tabs.js +1 -1
  190. package/dist/internal/components/ThemeProvider.js +3 -2
  191. package/dist/internal/components/TimePicker.js +1 -1
  192. package/dist/internal/components/Toast.js +2 -2
  193. package/dist/internal/components/Tooltip.js +1 -1
  194. package/dist/internal/components/Truncated.js +16 -8
  195. package/dist/internal/components/Truncated.js.map +1 -1
  196. package/dist/internal/components/ZoomableSvg.js +1 -1
  197. package/dist/internal/utils.js +1 -1
  198. package/dist/markdown-editor.js +7 -7
  199. package/dist/mermaid.js +1 -1
  200. package/dist/rjsf.js +11 -11
  201. package/dist/{styles-DSUP_-9Z.js → styles-BAFscjSV.js} +4 -3
  202. package/dist/styles-BAFscjSV.js.map +1 -0
  203. package/dist/styles.css +1 -1
  204. package/dist/svgTransforms-C9njt92h.js +89 -0
  205. package/dist/svgTransforms-C9njt92h.js.map +1 -0
  206. package/dist/testing.js +3 -2
  207. package/dist/testing.js.map +1 -1
  208. package/dist/{themeTokens-BNg98Mu9.js → themeTokens-7T1AFLhq.js} +13 -6
  209. package/dist/{themeTokens-BNg98Mu9.js.map → themeTokens-7T1AFLhq.js.map} +1 -1
  210. package/dist/{toast-CjkURw0M.js → toast-BweSoKn3.js} +3 -3
  211. package/dist/toast-BweSoKn3.js.map +1 -0
  212. package/dist/types-BPcAjMG0.d.ts +10 -0
  213. package/dist/{useColorSchemeState-CYqcUfSH.js → useColorSchemeState-BJEk6esG.js} +2 -2
  214. package/dist/{useColorSchemeState-CYqcUfSH.js.map → useColorSchemeState-BJEk6esG.js.map} +1 -1
  215. package/dist/{utils-D0c5VAyF.js → utils-B-g7d_Jb.js} +2 -2
  216. package/dist/{utils-D0c5VAyF.js.map → utils-B-g7d_Jb.js.map} +1 -1
  217. package/dist/vega.d.ts +46 -0
  218. package/dist/vega.js +26 -0
  219. package/dist/vega.js.map +1 -0
  220. package/dist/vegaTheme-FBXgAdHK.js +146 -0
  221. package/dist/vegaTheme-FBXgAdHK.js.map +1 -0
  222. package/package.json +26 -7
  223. package/src/styles.css +27 -4
  224. package/dist/AIKit-DiS0CVOW.js.map +0 -1
  225. package/dist/AppShell-B5GQN6Zs.js.map +0 -1
  226. package/dist/CodeEditor-DyaN-Ij2.js.map +0 -1
  227. package/dist/Combobox-Dgm6Z4ib.js.map +0 -1
  228. package/dist/DiagramSkeleton-lwBS2YBa.js.map +0 -1
  229. package/dist/MermaidDiagram-ChL3WIQT.js.map +0 -1
  230. package/dist/Select-Is0VkePH.js.map +0 -1
  231. package/dist/context-KxxeMHbR.js.map +0 -1
  232. package/dist/styles-DSUP_-9Z.js.map +0 -1
  233. package/dist/toast-CjkURw0M.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"AppShell-B5GQN6Zs.js","names":["Root"],"sources":["../src/blocks/AppShell/SidebarShell.tsx","../src/blocks/AppShell/TopNavShell.tsx","../src/blocks/AppShell/AppShell.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nimport type { AppShellHeaderSpan } from './types';\n\n// Required, not defaulted: `AppShell` owns the default so the generated component\n// API reports it, and this shell is internal — nothing else constructs it.\ntype Props = ComponentProps<'div'> & { headerSpan: AppShellHeaderSpan };\n\n/**\n * Sidebar geometry: left-rail navigation + header row + main outlet, with an\n * optional right rail. The grid template names match the `[grid-area:*]`\n * utilities the `AppShell.*` slots write onto themselves, so slot placement\n * is independent of source order.\n *\n * `headerSpan` picks which of the two row templates applies — see\n * {@link AppShellHeaderSpan}. Both keep the same three columns, so the rails\n * line up either way.\n */\nexport const SidebarShell = ({ ref, className, headerSpan, children, ...props }: Props) => (\n <div\n ref={ref}\n data-app-shell-geometry=\"sidebar\"\n data-header-span={headerSpan}\n className={cn(\n 'tw:relative tw:grid tw:h-svh tw:w-full tw:bg-background',\n 'tw:grid-cols-[auto_1fr_auto] tw:grid-rows-[auto_1fr]',\n headerSpan === 'full'\n ? cn(\n 'tw:[grid-template-areas:\"header_header_header\"_\"sidebar_main_aside\"]',\n // `Sidebar`'s inner wrapper is `fixed inset-y-0` — it owns that for its\n // collapse/resize animation — so it anchors to the viewport and paints\n // over a full-width header. Promoting the rail slots to containing\n // blocks re-anchors those fixed children to the slot's own grid box.\n // Beats overriding `top`: no `!important` to out-specify `inset-y-0`,\n // and the shell never needs to know the header's height.\n 'tw:[&>[data-app-shell-slot=sidebar]]:[transform:translateZ(0)]',\n 'tw:[&>[data-app-shell-slot=aside]]:[transform:translateZ(0)]',\n // A containing block is also a stacking context, so the promotion traps\n // the rail's own `z-50` inside the slot. The left rail sits before `main`\n // in source order, so without a slot-level z-index an expand-on-hover rail\n // paints *under* main's positioned content instead of over it. Restate it\n // here — grid items take `z-index` without `position`. The right rail needs\n // one too: source order only beats `z-index: auto` content, so main's\n // sticky elements (table headers at `z-10`, PageLayout's sticky header at\n // `z-20`) would paint over an aside left at `auto`. `z-30` clears them all\n // outright — no source-order tiebreak — while staying under the left\n // rail's `z-50`, keeping an expanding left rail above a filled right one.\n 'tw:[&>[data-app-shell-slot=sidebar]]:z-50',\n 'tw:[&>[data-app-shell-slot=aside]]:z-30',\n // The promotion is also what lets `styles.css` clip a parked off-canvas\n // rail: it makes the slot that panel's containing block.\n )\n : 'tw:[grid-template-areas:\"sidebar_header_aside\"_\"sidebar_main_aside\"]',\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\n/**\n * Top-nav geometry: header row spans the full width, main + aside live below.\n * The `sidebar` grid area is intentionally absent — the\n * `[grid-area:sidebar]` slot collapses to `display: none` so consumers can\n * pass the same composition under either brand. Primary navigation moves\n * into `<AppShell.Header>` for top-nav-first compositions.\n *\n * Takes no `headerSpan`: this header already spans the full width, so `AppShell`\n * keeps the prop away from this shell rather than having it accept and ignore it.\n */\nexport const TopNavShell = ({ ref, className, children, ...props }: Props) => (\n <div\n ref={ref}\n data-app-shell-geometry=\"topnav\"\n className={cn(\n 'tw:grid tw:h-svh tw:w-full tw:bg-background',\n 'tw:grid-cols-[1fr_auto] tw:grid-rows-[auto_1fr]',\n 'tw:[grid-template-areas:\"header_header\"_\"main_aside\"]',\n // The sidebar slot has no place in this geometry — hide it without\n // forcing callers to conditionalise their JSX.\n 'tw:[&>[data-app-shell-slot=sidebar]]:hidden',\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n","import type { ComponentPropsWithoutRef, ComponentRef, Ref } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\n\nimport { useTheme } from '../../components/ThemeProvider';\nimport { cn } from '../../utils';\n\nimport { SidebarShell } from './SidebarShell';\nimport { TopNavShell } from './TopNavShell';\nimport type { AppShellHeaderSpan } from './types';\n\ntype RootProps = ComponentPropsWithoutRef<'div'> & {\n /**\n * How far the header row stretches. `content` (default) gives it the middle\n * column only, with both rails beside it; `full` spans all three columns and\n * drops the rails below it, so the brand mark aligns to the viewport edge.\n * No-op under the top-nav geometry, whose header is already full width.\n *\n * Reach for `full` when the header carries app-wide identity (brand mark,\n * project switcher, account menu) rather than page-level navigation.\n */\n headerSpan?: AppShellHeaderSpan;\n};\n\nconst Root = ({\n ref,\n className,\n // Defaulted here rather than in SidebarShell so the generated component API\n // records `content` instead of \"no default\".\n headerSpan = 'content',\n children,\n ...props\n}: RootProps & { ref?: Ref<ComponentRef<'div'>> }) => {\n const { currentTheme: brand } = useTheme();\n\n // Branch rather than pick a component and spread: `headerSpan` is meaningless\n // to the top-nav geometry, and forwarding it there would land a stray\n // `headerspan` attribute on the DOM node.\n if (brand.shell === 'topnav') {\n return (\n <TopNavShell ref={ref} className={className} {...props}>\n {children}\n </TopNavShell>\n );\n }\n\n return (\n <SidebarShell ref={ref} className={className} headerSpan={headerSpan} {...props}>\n {children}\n </SidebarShell>\n );\n};\n\ntype SlotProps = ComponentPropsWithoutRef<'div'> & {\n /** Render as the child element (Radix-Slot pattern), forwarding props onto it. */\n asChild?: boolean;\n};\n\ntype ChromeSlotProps = SlotProps & {\n /**\n * Drop the slot's own padding, background and border so a hosted chrome component\n * (`Navbar` in `Header`, `Sidebar side=\"right\"` in `Aside`) can render edge to edge.\n *\n * The slots paint themselves, which is right when you put content straight into them.\n * It is wrong when the child is already a full-bleed surface: the child ends up inset\n * inside the slot with the slot's background showing through as gutters at each end.\n * Use this instead of re-stating the overrides at the call site — hand-written\n * overrides also have to win a cascade fight, which is why they tend to grow an `!`.\n */\n flush?: boolean;\n};\n\nconst Header = ({\n ref,\n className,\n asChild,\n flush = false,\n children,\n ...props\n}: ChromeSlotProps & { ref?: Ref<ComponentRef<'header'>> }) => {\n const Comp = asChild ? Slot : 'header';\n return (\n <Comp\n ref={ref}\n data-app-shell-slot=\"header\"\n data-flush={flush || undefined}\n className={cn(\n 'tw:flex',\n flush\n ? 'tw:items-stretch tw:gap-0'\n : 'tw:items-center tw:gap-3 tw:border-b tw:border-border tw:bg-background tw:px-4',\n 'tw:[grid-area:header]',\n className,\n )}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n\nconst SidebarSlot = ({\n ref,\n className,\n asChild,\n children,\n ...props\n}: SlotProps & { ref?: Ref<ComponentRef<'div'>> }) => {\n const Comp = asChild ? Slot : 'div';\n return (\n <Comp\n ref={ref}\n data-app-shell-slot=\"sidebar\"\n // In a sidebar shell the children render in place. In a top-nav shell\n // the slot is hidden — the shell defines `display: none` for the\n // `sidebar` grid area in that geometry, so consumers can pass the\n // same JSX and let the shell decide visibility.\n className={cn('tw:flex tw:min-h-0 tw:flex-col', 'tw:[grid-area:sidebar]', className)}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n\nconst Main = ({\n ref,\n className,\n asChild,\n children,\n ...props\n}: SlotProps & { ref?: Ref<ComponentRef<'main'>> }) => {\n const Comp = asChild ? Slot : 'main';\n return (\n <Comp\n ref={ref}\n data-app-shell-slot=\"main\"\n className={cn(\n 'tw:flex tw:min-w-0 tw:min-h-0 tw:flex-1 tw:flex-col tw:overflow-auto',\n // Opinionated default page gutter so page content clears the header /\n // rails and looks right out of the box. `cn` is tailwind-merge, so an\n // app that owns its own gutter overrides it (e.g. `className=\"tw:p-0\"`).\n 'tw:p-6',\n 'tw:[grid-area:main]',\n className,\n )}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n\nconst Aside = ({\n ref,\n className,\n asChild,\n flush = false,\n children,\n ...props\n}: ChromeSlotProps & { ref?: Ref<ComponentRef<'aside'>> }) => {\n const Comp = asChild ? Slot : 'aside';\n return (\n <Comp\n ref={ref}\n data-app-shell-slot=\"aside\"\n data-flush={flush || undefined}\n className={cn(\n 'tw:flex tw:min-h-0 tw:shrink-0 tw:flex-col',\n // A hosted `Sidebar side=\"right\"` owns its own width, border, background and\n // scrolling — so the slot must not also set them, or the rail renders inset\n // inside a second painted surface.\n flush\n ? 'tw:w-auto tw:overflow-visible'\n : 'tw:w-72 tw:overflow-auto tw:border-l tw:border-border tw:bg-background',\n 'tw:[grid-area:aside]',\n className,\n )}\n {...props}\n >\n {children}\n </Comp>\n );\n};\n\n/**\n * App-shell layout primitive. Reads `useTheme().brand.shell` and dispatches to\n * a sidebar (left rail) or top-nav geometry. Consumers compose the same\n * `<AppShell.Header>` / `<AppShell.Sidebar>` / `<AppShell.Main>` /\n * `<AppShell.Aside>` slots — the shell decides where each slot lives based on\n * the active brand.\n *\n * **When to use:** the root layout of any app that wants to follow the active\n * brand's shell geometry. Host a `PageLayout` inside `<AppShell.Main>` for\n * the per-page content column. Pass `headerSpan=\"full\"` for a full-bleed header\n * row above both rails.\n * **When NOT to use:** standalone screens that aren't part of a navigated app\n * (sign-in, error pages). Render those without `AppShell`.\n * **Composition:** must be rendered inside a `<ThemeProvider>` — the geometry\n * is brand-driven. Pass the same content across brands; the shell handles\n * placement and shows/hides the `Sidebar` slot accordingly.\n *\n * @see AppShell.stories.tsx — flip the Storybook brand toolbar to see the\n * sidebar / top-nav geometry swap from a single composition.\n */\nexport const AppShell = Object.assign(Root, {\n /**\n * Top header row. Renders above `Main` in the sidebar shell; renders as the\n * top bar (with full-width navigation room) in the top-nav shell.\n */\n Header,\n /**\n * Left navigation rail. Rendered in the sidebar shell; hidden by the\n * top-nav shell so the same composition works under either brand — move\n * primary navigation into `Header` for top-nav-first compositions.\n */\n Sidebar: SidebarSlot,\n /**\n * Main content outlet. Applies an opinionated default page gutter (`tw:p-6`)\n * so content looks right out of the box; override the padding (e.g. `tw:p-0`)\n * when the app owns its own gutter.\n */\n Main,\n /** Optional right rail. Present in both shells. */\n Aside,\n});\n"],"mappings":";;;;;;;;;;;;;;;AAoBA,MAAa,gBAAgB,EAAE,KAAK,WAAW,YAAY,UAAU,GAAG,YACtE,oBAAC,OAAD;CACO;CACL,2BAAwB;CACxB,oBAAkB;CAClB,WAAW,GACT,2DACA,wDACA,eAAe,SACX,GACE,4EAOA,kEACA,gEAWA,6CACA,yCAGF,IACA,4EACJ,SACF;CACA,GAAI;CAEH;AACE,CAAA;;;;;;;;;;;;;AC5CP,MAAa,eAAe,EAAE,KAAK,WAAW,UAAU,GAAG,YACzD,oBAAC,OAAD;CACO;CACL,2BAAwB;CACxB,WAAW,GACT,+CACA,mDACA,6DAGA,+CACA,SACF;CACA,GAAI;CAEH;AACE,CAAA;;;ACTP,MAAMA,UAAQ,EACZ,KACA,WAGA,aAAa,WACb,UACA,GAAG,YACiD;CACpD,MAAM,EAAE,cAAc,UAAU,SAAS;CAKzC,IAAI,MAAM,UAAU,UAClB,OACE,oBAAC,aAAD;EAAkB;EAAgB;EAAW,GAAI;EAC9C;CACU,CAAA;CAIjB,OACE,oBAAC,cAAD;EAAmB;EAAgB;EAAuB;EAAY,GAAI;EACvE;CACW,CAAA;AAElB;AAqBA,MAAM,UAAU,EACd,KACA,WACA,SACA,QAAQ,OACR,UACA,GAAG,YAC0D;CAE7D,OACE,oBAFW,UAAU,OAAO,UAE5B;EACO;EACL,uBAAoB;EACpB,cAAY,SAAS,KAAA;EACrB,WAAW,GACT,WACA,QACI,8BACA,kFACJ,yBACA,SACF;EACA,GAAI;EAEH;CACG,CAAA;AAEV;AAEA,MAAM,eAAe,EACnB,KACA,WACA,SACA,UACA,GAAG,YACiD;CAEpD,OACE,oBAFW,UAAU,OAAO,OAE5B;EACO;EACL,uBAAoB;EAKpB,WAAW,GAAG,kCAAkC,0BAA0B,SAAS;EACnF,GAAI;EAEH;CACG,CAAA;AAEV;AAEA,MAAM,QAAQ,EACZ,KACA,WACA,SACA,UACA,GAAG,YACkD;CAErD,OACE,oBAFW,UAAU,OAAO,QAE5B;EACO;EACL,uBAAoB;EACpB,WAAW,GACT,wEAIA,UACA,uBACA,SACF;EACA,GAAI;EAEH;CACG,CAAA;AAEV;AAEA,MAAM,SAAS,EACb,KACA,WACA,SACA,QAAQ,OACR,UACA,GAAG,YACyD;CAE5D,OACE,oBAFW,UAAU,OAAO,SAE5B;EACO;EACL,uBAAoB;EACpB,cAAY,SAAS,KAAA;EACrB,WAAW,GACT,8CAIA,QACI,kCACA,0EACJ,wBACA,SACF;EACA,GAAI;EAEH;CACG,CAAA;AAEV;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAa,WAAW,OAAO,OAAOA,QAAM;;;;;CAK1C;;;;;;CAMA,SAAS;;;;;;CAMT;;CAEA;AACF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CodeEditor-DyaN-Ij2.js","names":["cmPlaceholder","placeholder"],"sources":["../src/components/CodeEditor/ButtonToolbar.tsx","../src/components/CodeEditor/modes/dbt.ts","../src/components/CodeEditor/modes/jsonnet.ts","../src/components/CodeEditor/helpers.ts","../src/components/CodeEditor/editorChrome.ts","../src/components/CodeEditor/search.ts","../src/components/CodeEditor/ToggleComponentHelp.tsx","../src/components/CodeEditor/tokenTheme.ts","../src/components/CodeEditor/tooltips.ts","../src/components/CodeEditor/variableCompletion.ts","../src/components/CodeEditor/CodeEditor.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { ClipboardButton } from '../../blocks/ClipboardButton';\n\n// Floats over the top-right corner of the editor it is rendered into — private to\n// `CodeEditor`, which is the `relative` ancestor it positions against. `right-3`\n// leaves room for the scrollbar track, whose width the browser owns and no token\n// here describes.\nexport const ButtonToolbar = ({ value, children }: { value?: string; children?: ReactNode }) => {\n if (!value && !children) return null;\n\n return (\n <div className=\"tw:absolute tw:right-3 tw:top-1 tw:z-10 tw:flex tw:gap-0.5 tw:overflow-visible tw:rounded tw:border tw:border-solid tw:border-border tw:!bg-background tw:p-px tw:shadow-sm\">\n {!!value && <ClipboardButton size=\"icon-xs\" variant=\"invisible\" text={value} />}\n {children}\n </div>\n );\n};\n","import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';\nimport { simpleMode } from '@codemirror/legacy-modes/mode/simple-mode';\n\n// A dbt step is `dbt <command> [<subcommand>] [arguments, flags and selectors]`,\n// and the vocabulary below is grouped by the slot it belongs to — both to colour\n// it and to decide what is worth offering where.\nconst COMMANDS = [\n 'run-operation',\n 'run',\n 'test',\n 'seed',\n 'snapshot',\n 'list',\n 'ls',\n 'compile',\n 'build',\n 'deps',\n 'docs',\n 'source',\n];\nconst SUBCOMMANDS: Record<string, string[]> = { docs: ['generate'], source: ['freshness'] };\nconst ARGUMENTS = ['--select', '--exclude', '--selector', '--defer', '--resource-type', '-s'];\n// The arguments whose value is a graph selector, and so the only ones a selector\n// method has anything to attach to.\nconst SELECTORS = ['--select', '--exclude', '-s'];\nconst METHODS = [\n 'path:',\n 'source:',\n 'tag:',\n 'package:',\n 'config:',\n 'test_type:',\n 'test_name:',\n 'state:',\n 'exposure:',\n 'metric:',\n 'result:',\n 'source_status:',\n 'column_name:',\n];\nconst FLAGS = [\n '--fail-fast',\n '--warn-error',\n '--favor-state',\n '--vars',\n '--models',\n '--threads',\n '--profiles-dir',\n '--profile',\n '--full-refresh',\n];\n\n// A subcommand only ever highlights together with its command, so `dbt docs` stays\n// unpainted until `generate` follows it.\nconst COMMAND_PHRASES = COMMANDS.flatMap((command) => {\n const subcommands = SUBCOMMANDS[command];\n\n return subcommands ? subcommands.map((subcommand) => `${command} ${subcommand}`) : [command];\n});\n\n// Alternation is first-match, so a word that prefixes another has to come first\n// (`run-operation` before `run`, `--profiles-dir` before `--profile`). Sorting by\n// length keeps that true however the lists above are written.\nconst alternation = (list: string[]) => [...list].sort((a, b) => b.length - a.length).join('|');\n\n// Every keyword follows whitespace, so the leading run is part of the match.\n// Commands and arguments end on a word boundary; methods and flags carry their\n// own terminator (`:`) or need none.\nconst word = (list: string[]) => new RegExp(`^\\\\s+(?:${alternation(list)})\\\\b`, 'i');\nconst prefix = (list: string[]) => new RegExp(`^\\\\s+(?:${alternation(list)})`, 'i');\n\n// The word being completed: letters, digits, `_`, `-` and the `:` a selector\n// method ends with. Whitespace stays out of it, so a two-word label like `docs\n// generate` cannot stretch the match back across the words before the cursor.\nconst WORD = /[\\w:-]*$/;\n\nconst asOptions = (list: string[], type: string): Completion[] =>\n list.map((label) => ({ label, type }));\n\n// `type` drives the popup icon, so each group carries the one that matches the\n// colour the mode paints it in.\nconst DBT: Completion[] = [{ label: 'dbt', type: 'keyword' }];\nconst COMMAND_OPTIONS = asOptions(COMMANDS, 'keyword');\nconst SUBCOMMAND_OPTIONS: Record<string, Completion[]> = Object.fromEntries(\n Object.entries(SUBCOMMANDS).map(([command, subcommands]) => [\n command,\n asOptions(subcommands, 'keyword'),\n ]),\n);\nconst ARGUMENT_OPTIONS = asOptions(ARGUMENTS, 'variable');\nconst FLAG_OPTIONS = asOptions(FLAGS, 'constant');\nconst METHOD_OPTIONS = asOptions(METHODS, 'property');\n\n// Which slice of the vocabulary the cursor's slot can hold, given the words\n// already finished ahead of it. Offering the whole vocabulary everywhere proposes\n// `dbt` mid-command and a selector method with no selector to attach to.\nconst optionsAfter = (words: string[]): Completion[] => {\n const [step, command, ...rest] = words;\n\n if (step === undefined) return DBT;\n if (step.toLowerCase() !== 'dbt') return [];\n if (command === undefined) return COMMAND_OPTIONS;\n\n const subcommands = SUBCOMMAND_OPTIONS[command.toLowerCase()];\n if (subcommands && rest.length === 0) return subcommands;\n\n // A selector argument takes any number of space-separated values, so what\n // decides the slot is the last argument, not whether a selector appeared at all:\n // `--select tag:a tag:b` keeps offering methods, `--select a --profile p` stops.\n const lastArgument = rest.filter((it) => it.startsWith('-')).at(-1);\n const selecting = lastArgument !== undefined && SELECTORS.includes(lastArgument.toLowerCase());\n\n return selecting\n ? [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS, ...METHOD_OPTIONS]\n : [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS];\n};\n\nconst complete = (context: CompletionContext): CompletionResult | null => {\n const typed = context.matchBefore(WORD);\n\n // `WORD` also matches the empty string, so without this the popup would open on\n // every space. Asking for completions explicitly still opens it there.\n if (!typed?.text && !context.explicit) return null;\n\n const from = typed?.from ?? context.pos;\n const line = context.state.doc.lineAt(from);\n const options = optionsAfter(\n line.text\n .slice(0, from - line.from)\n .split(/\\s+/)\n .filter(Boolean),\n );\n\n return options.length > 0 ? { from, options, validFor: WORD } : null;\n};\n\nexport const dbt = simpleMode({\n languageData: {\n // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.\n commentTokens: { line: '--', block: { open: '/*', close: '*/' } },\n autocomplete: complete,\n },\n start: [\n { regex: /\"(?:[^\\\\]|\\\\.)*?(?:\"|$)/, token: 'string' },\n // Word-bounded, so `dbtX` is not a dbt step whose first word happens to\n // colour — the same thing the completion source asks of it.\n { regex: /dbt\\b/, token: 'keyword', sol: true },\n { regex: word(COMMAND_PHRASES), token: 'keyword' },\n { regex: word(ARGUMENTS), token: 'variableName' },\n { regex: prefix(METHODS), token: 'propertyName' },\n { regex: prefix(FLAGS), token: 'attributeName' },\n { regex: /(?:@|\\*|,|\\+\\d+|\\d+\\+|\\+)/, token: 'operator' },\n { regex: /'.*'/, token: 'string' },\n { regex: /true|false/, token: 'atom' },\n ],\n});\n","import type { StreamParser } from '@codemirror/language';\n\n/**\n * Ported from google/codemirror-mode-jsonnet (Apache-2.0), the mode written by\n * the language's own authors, which was never taken past CodeMirror 5.\n * CodeMirror 5 style names are replaced by their CodeMirror 6 highlight tags:\n * `string-2` is `escape`, `error` is `invalid`.\n *\n * Every pattern is anchored and hoisted. `StringStream.match` slices the rest of\n * the line and, without `^`, scans all of it for a match it then discards unless\n * it started at the cursor — so an unanchored probe costs the whole remaining\n * line, and this tokenizer makes up to twenty of them per token.\n */\n\nconst COMMENT_END = /^\\*\\//;\nconst COMMENT_START = /^\\/\\/|^#/;\nconst C_COMMENT_START = /^\\/\\*/;\nconst TEXT_BLOCK = /^\\|\\|\\|/;\nconst TEXT_BLOCK_END = /^\\s*\\|\\|\\|/;\nconst RAW_DOUBLE = /^\"\"/;\nconst RAW_SINGLE = /^''/;\nconst CLOSE_DOUBLE = /^\"/;\nconst CLOSE_SINGLE = /^'/;\nconst ESCAPE = /^\\\\[\\\\\"'/bfnrt0]/;\nconst UNICODE_ESCAPE = /^\\\\u[0-9a-fA-F]{4}/;\nconst BACKSLASH = /^\\\\/;\nconst IMPORT = /^import(?:str)?\\s*(@?)([\"'])/;\nconst QUOTE = /^(@?)([\"'])/;\nconst ROOT = /^\\$/;\nconst NUMBER = /^(?:\\.\\d+|\\d+\\.?\\d*)(?:e[-+]?\\d+)?/i;\nconst OPERATOR = /^[-+/*=<>!&~^|$%]+/;\nconst IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]*/;\n\nconst KEYWORDS: Record<string, 'keyword' | 'atom'> = {\n local: 'keyword',\n self: 'keyword',\n super: 'keyword',\n assert: 'keyword',\n function: 'keyword',\n if: 'keyword',\n then: 'keyword',\n else: 'keyword',\n for: 'keyword',\n in: 'keyword',\n tailstrict: 'keyword',\n error: 'keyword',\n true: 'atom',\n false: 'atom',\n null: 'atom',\n};\n\ntype State = {\n cComment: boolean;\n textBlock: boolean;\n textBlockIndent: number | null;\n string: boolean;\n importString: boolean;\n stringSingle: boolean;\n stringRaw: boolean;\n};\n\nexport const jsonnet: StreamParser<State> = {\n name: 'jsonnet',\n\n // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.\n languageData: { commentTokens: { line: '//', block: { open: '/*', close: '*/' } } },\n\n startState: () => ({\n cComment: false,\n textBlock: false,\n textBlockIndent: null,\n string: false,\n importString: false,\n stringSingle: false,\n stringRaw: false,\n }),\n\n token: (stream, state) => {\n if (state.cComment) {\n if (stream.match(COMMENT_END)) {\n state.cComment = false;\n return 'comment';\n }\n stream.next();\n return 'comment';\n }\n\n // A `|||` block runs from its own first content line to the first line\n // indented less than that — so the closing `|||` has to be recognised\n // before the indent is measured, or a block closed at column 0 never ends.\n if (state.textBlock) {\n if (state.textBlockIndent == null) {\n if (stream.match(TEXT_BLOCK_END)) {\n state.textBlock = false;\n return 'string';\n }\n state.textBlockIndent = stream.indentation();\n }\n if (stream.indentation() >= state.textBlockIndent) {\n stream.skipToEnd();\n return 'string';\n }\n if (stream.match(TEXT_BLOCK_END)) {\n state.textBlock = false;\n return 'string';\n }\n stream.next();\n return 'invalid';\n }\n\n // Quoted and `@`-raw strings, single or double, plain or after an import.\n if (state.string || state.importString) {\n const style = state.string ? 'string' : 'meta';\n\n if (state.stringRaw) {\n if (stream.match(state.stringSingle ? RAW_SINGLE : RAW_DOUBLE)) return 'escape';\n } else {\n if (stream.match(ESCAPE)) return 'escape';\n if (stream.match(UNICODE_ESCAPE)) return 'escape';\n if (stream.match(BACKSLASH)) return 'invalid';\n }\n\n if (stream.match(state.stringSingle ? CLOSE_SINGLE : CLOSE_DOUBLE)) {\n state.string = false;\n state.importString = false;\n return style;\n }\n\n stream.next();\n return style;\n }\n\n if (stream.match(COMMENT_START)) {\n stream.skipToEnd();\n return 'comment';\n }\n if (stream.match(C_COMMENT_START)) {\n state.cComment = true;\n return 'comment';\n }\n\n // An import opens a string that is styled as meta rather than as content.\n const imported = stream.match(IMPORT);\n if (Array.isArray(imported)) {\n state.importString = true;\n state.stringRaw = imported[1] === '@';\n state.stringSingle = imported[2] === \"'\";\n return 'meta';\n }\n\n const quoted = stream.match(QUOTE);\n if (Array.isArray(quoted)) {\n state.string = true;\n state.stringRaw = quoted[1] === '@';\n state.stringSingle = quoted[2] === \"'\";\n return 'string';\n }\n\n if (stream.match(TEXT_BLOCK)) {\n state.textBlock = true;\n state.textBlockIndent = null;\n return 'string';\n }\n\n if (stream.match(ROOT)) return 'keyword';\n if (stream.match(NUMBER)) return 'number';\n if (stream.match(OPERATOR)) return 'operator';\n\n // Consumed whole so that a keyword's prefix (`locally`) is not styled.\n const identifier = stream.match(IDENTIFIER);\n if (Array.isArray(identifier)) return KEYWORDS[identifier[0]] ?? null;\n\n stream.next();\n return null;\n },\n};\n","import { javascript } from '@codemirror/lang-javascript';\nimport { json, jsonParseLinter } from '@codemirror/lang-json';\nimport { python } from '@codemirror/lang-python';\nimport { MSSQL, MySQL, PLSQL, PostgreSQL, StandardSQL } from '@codemirror/lang-sql';\nimport { StreamLanguage } from '@codemirror/language';\nimport { r } from '@codemirror/legacy-modes/mode/r';\nimport { shell } from '@codemirror/legacy-modes/mode/shell';\nimport { toml } from '@codemirror/legacy-modes/mode/toml';\nimport type { LintSource } from '@codemirror/lint';\nimport { linter } from '@codemirror/lint';\nimport { tags } from '@lezer/highlight';\nimport { githubLightInit } from '@uiw/codemirror-theme-github';\nimport type { BasicSetupOptions } from '@uiw/react-codemirror';\n\nimport { getSqlLanguageSupport } from '@keboola/codemirror-lang-sql';\nimport colors from '@keboola/tailwind-config/colors';\n\nimport { resolveToken } from '../../utils/themeTokens';\nimport type { ResolvedColorScheme } from '../ThemeProvider/types';\n\nimport { dbt } from './modes/dbt';\nimport { jsonnet } from './modes/jsonnet';\n\n// The MIME vocabulary callers pass. Kept as a const so the runtime whitelist and\n// the type stay one list — an annotated `LANGUAGE_MODE[]` copy elsewhere silently\n// drifts, since the type checker accepts a short one.\nexport const LANGUAGE_MODES = [\n 'application/json',\n 'text/plain',\n 'text/x-python',\n 'text/x-sql',\n 'text/x-mysql',\n 'text/x-pgsql',\n 'text/x-mssql',\n // Snowflake, under a historical name — these strings are a published prop contract.\n 'text/x-sfsql',\n 'text/x-bqsql',\n 'text/x-plsql',\n 'text/x-rsrc',\n 'text/x-sh',\n 'text/x-toml',\n 'text/jsonnet',\n 'text/x-dbt',\n 'text/javascript',\n 'text/typescript',\n] as const;\n\nexport type LANGUAGE_MODE = (typeof LANGUAGE_MODES)[number];\n\nexport const isLanguageMode = (mode: string): mode is LANGUAGE_MODE =>\n (LANGUAGE_MODES as readonly string[]).includes(mode);\n\n// `readOnly` reaches CodeMirror as `contenteditable`, so the two states are only\n// addressable through it. Exported because `fieldChrome` overrides the read-only\n// wash below by re-declaring the same key — which only works while the strings\n// match exactly.\nexport const READ_ONLY_EDITOR = '&.cm-editor:has(.cm-content[contenteditable=\"false\"])';\nexport const EDITABLE_EDITOR = '&.cm-editor:has(.cm-content[contenteditable=\"true\"])';\n\n// Chrome surfaces (selection, read-only wash) resolve from live `--*`\n// tokens so they re-skin with brand + dark mode; diff/syntax colors below stay\n// categorical (fixed across brands). Fallback channels mirror the light-mode\n// token values for SSR / no-provider parity.\nexport const buildBaseThemeStyles = () => ({\n '*': { lineHeight: '20px' },\n '*::selection': {\n backgroundColor: resolveToken('primary', '31 143 255'),\n color: `${resolveToken('primary-foreground', '255 255 255')} !important`,\n },\n [READ_ONLY_EDITOR]: {\n backgroundColor: resolveToken('secondary', '226 232 240'),\n },\n [`${READ_ONLY_EDITOR} .cm-gutters`]: {\n backgroundColor: resolveToken('border', '229 231 235'),\n },\n '&.cm-editor .cm-scroller': { overflowAnchor: 'none' },\n '&.cm-editor, &.cm-editor .cm-scroller': {\n minHeight: '100%',\n flexGrow: 1,\n alignItems: 'stretch !important',\n outline: 'none',\n },\n '.cm-gutter.cm-foldGutter': { display: 'none !important' },\n '.cm-gutter.cm-lineNumbers': { paddingLeft: '20px', paddingRight: '6px' },\n '.cm-gutters': { height: 'auto' },\n\n // merge (diff) view\n '&[class*=\"cm-merge-\"] .cm-deletedLine': { backgroundColor: colors.error[100] },\n '&[class*=\"cm-merge-\"] .cm-changedLine': { backgroundColor: colors.green[100] },\n '&[class*=\"cm-merge-\"] .cm-deletedLineGutter': { backgroundColor: colors.error[200] },\n '&[class*=\"cm-merge-\"] .cm-changedLineGutter': { backgroundColor: colors.green[200] },\n '&[class*=\"cm-merge-\"] .cm-deletedText': { background: colors.error[200] },\n '&[class*=\"cm-merge-\"] .cm-changedText': { background: colors.green[200] },\n '&[class*=\"cm-merge-\"]': {\n backgroundColor: `${colors.white} !important`,\n },\n '&[class*=\"cm-merge-\"] .cm-gutters': {\n backgroundColor: `${colors.white} !important`,\n },\n '.cm-changeGutter': { position: 'absolute', zIndex: -1, width: '100%', paddingLeft: 0 },\n '&[class*=\"cm-merge-\"] .cm-changedLine,&[class*=\"cm-merge-\"] .cm-line, &[class*=\"cm-merge-\"] .cm-deletedChunk':\n { paddingLeft: 0 },\n});\n\n// Dead whatever the editor does with them: `buildBaseThemeStyles` hides the fold\n// gutter outright, and `buildCustomTheme` paints the active line transparent.\nconst ALWAYS_OFF = {\n drawSelection: false,\n foldGutter: false,\n foldKeymap: false,\n highlightActiveLine: false,\n highlightActiveLineGutter: false,\n} as const;\n\n// `basicSetup` enables everything it is not told to skip, so a viewer would\n// otherwise install bracket closing and keybindings for commands a read-only\n// document rejects. Search stays — Mod-f is useful on a viewer. Same reasoning\n// as `shouldLintJson` below.\n//\n// `history` stays too, though a viewer can never add an entry: a caller that\n// flips `readOnly` mid-session reconfigures the view, and a reconfigure discards\n// state fields the new configuration doesn't have. Leaving it out saves nothing\n// and costs the editable session its undo stack.\n//\n// Autocompletion is absent here on purpose: `CodeEditor` installs its own\n// `autocompletion()` extension, which is appended after this object and would\n// re-add the plugin and its keymap. It gates that call on `readOnly` instead.\nexport const buildBasicSetup = (readOnly: boolean): BasicSetupOptions => ({\n ...ALWAYS_OFF,\n ...(readOnly\n ? {\n closeBrackets: false,\n closeBracketsKeymap: false,\n lintKeymap: false,\n indentOnInput: false,\n rectangularSelection: false,\n dropCursor: false,\n highlightSelectionMatches: false,\n }\n : null),\n});\n\n// Editor surface + gutter resolve from live `--*` tokens; the github\n// syntax palette stays categorical. Fallback channels mirror the light-mode\n// token values. `foreground` / `gutterForeground` pair the token-driven\n// surfaces with token-driven text so line content and line numbers stay\n// readable when the background goes dark (e.g. standalone, no surrounding\n// `tw:text-foreground`).\n//\n// `styles` corrects the stock github palette where a colour stops carrying\n// meaning (later entries win over the stock rule for the same tag), for every\n// language this theme paints — the SQL modes that motivated it (UT-5024) and\n// JSON, python, JS alike. The github theme paints every `name`-family tag\n// green, and in SQL nearly every token is a name — identifiers, function calls\n// and `$variables` all drowned in one colour, and a keyword that doubles as a\n// function (`create or REPLACE`) read as a value. Instead: plain identifiers,\n// quoted identifiers (`\"a column\"`) and brackets carry no colour (matching\n// github.com's own rendering; stock github also lumped brackets in with\n// comments), functions and special vars get their own hues, and amber is\n// unique to string literals — in JSON that shifts string values from navy to\n// amber, the one visible non-SQL change.\nexport const buildCustomTheme = (scheme: ResolvedColorScheme) => {\n const foreground = resolveToken('foreground', '30 41 59');\n const dark = scheme === 'dark';\n\n return githubLightInit({\n settings: {\n fontFamily: `'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New'`,\n background: resolveToken('background', '249 250 251'),\n foreground,\n gutterBackground: resolveToken('muted', '241 245 249'),\n gutterForeground: resolveToken('muted-foreground', '100 116 139'),\n gutterBorder: 'transparent',\n lineHighlight: 'transparent',\n selection: resolveToken('primary', '31 143 255'),\n },\n styles: [\n { tag: [tags.name, tags.special(tags.string), tags.bracket], color: foreground },\n { tag: tags.standard(tags.name), color: colors.purple[600] },\n { tag: tags.special(tags.name), color: colors.cyan[700] },\n // A light/dark pair, because one amber cannot clear AA on both grounds — and because the\n // editor is painted on two different surfaces per scheme: the theme's `background` setting is\n // the page background, but `variant=\"field\"` paints on `muted` instead, which the theme never\n // sees. All four combinations, darkest surface first:\n //\n // - light `800`: 6.89:1 on `muted`, 7.23:1 on `background` (`700` was 4.45:1 / 4.67:1 — the\n // field surface failed axe `color-contrast`, and plain passed by 0.17).\n // - dark `300`: 10.97:1 on `muted`, 13.53:1 on `background` (`800` is 1.99:1 / 2.45:1 there).\n //\n // Same shape as `buildDiffHighlightTheme` in `MergeEditor/decorations.ts`, for the same amber.\n { tag: tags.string, color: dark ? colors.warning[300] : colors.warning[800] },\n ],\n });\n};\n\nexport const getLanguageMode = (mode?: LANGUAGE_MODE) => {\n switch (mode) {\n case undefined:\n case 'application/json':\n return json();\n case 'text/x-python':\n return python();\n case 'text/x-sql':\n return getSqlLanguageSupport(StandardSQL);\n case 'text/x-mysql':\n return getSqlLanguageSupport(MySQL);\n case 'text/x-pgsql':\n return getSqlLanguageSupport(PostgreSQL);\n case 'text/x-mssql':\n return getSqlLanguageSupport(MSSQL);\n case 'text/x-sfsql':\n return getSqlLanguageSupport('snowflake');\n case 'text/x-bqsql':\n return getSqlLanguageSupport('bigquery');\n case 'text/x-plsql':\n return getSqlLanguageSupport(PLSQL);\n case 'text/x-rsrc':\n return StreamLanguage.define(r);\n case 'text/x-sh':\n return StreamLanguage.define(shell);\n case 'text/x-toml':\n return StreamLanguage.define(toml);\n case 'text/jsonnet':\n return StreamLanguage.define(jsonnet);\n case 'text/x-dbt':\n return StreamLanguage.define(dbt);\n case 'text/javascript':\n return javascript({ jsx: true });\n case 'text/typescript':\n return javascript({ jsx: true, typescript: true });\n // No language — `text/plain` lands here, and so does any mode added to\n // LANGUAGE_MODES without an arm above. Unstyled text is the safe degradation;\n // a `json()` default would colour unrelated content as if it were JSON.\n default:\n return [];\n }\n};\n\n// The JSON parse linter is only useful on an editable editor — a read-only one\n// can't act on the errors, so running it is wasted work and its underlines are\n// noise (e.g. non-strict JSON shown read-only in Kai chat).\nexport const shouldLintJson = (mode: LANGUAGE_MODE | undefined, readOnly: boolean): boolean =>\n mode === 'application/json' && !readOnly;\n\n/**\n * Wraps a lint source so a blank document produces no diagnostics.\n *\n * `jsonParseLinter` reports \"Unexpected end of input\" for empty content, which is right for a file and\n * wrong for an *optional* form field: it starts empty, and clearing it is how its value is removed.\n * Left unwrapped, every such field opens with a red gutter marker contradicting its own validation —\n * `CodeEditorField` puts six of them on one screen.\n *\n * Exported for its test: the wrapper is the behaviour worth pinning, and it needs no editor to exercise.\n */\nexport const skipBlankDocument =\n (source: LintSource): LintSource =>\n (view) =>\n view.state.doc.toString().trim() === '' ? [] : source(view);\n\n/**\n * The JSON linter, optionally blind to a blank document.\n *\n * - `allowBlankDocument` is opt-in, and only `CodeEditorField` opts in (from `!required`). Suppressing\n * the marker by default would break callers that treat empty as invalid *and* say so nowhere else:\n * `ex-generic/JsonConfiguration.tsx`, `flows/TaskParamsModalContent.tsx` and\n * `stream/PayloadTest.tsx` all gate their button on `isValidJsonConfig`, which is `false` for `''`,\n * with no `disabledReason` — so the gutter marker is the only thing explaining a dead button.\n * - Not derivable from `variant`: `ex-generic/FunctionControl.tsx` is `variant=\"field\"` and empty is\n * an error there too. Whether blank is valid is the *field's* contract, not the control's shape.\n */\nexport const buildJsonLinter = (allowBlankDocument: boolean) => {\n const source = jsonParseLinter();\n\n return linter(allowBlankDocument ? skipBlankDocument(source) : source);\n};\n","import colors from '@keboola/tailwind-config/colors';\n\nimport { resolveToken } from '../../utils/themeTokens';\n\nimport { EDITABLE_EDITOR, READ_ONLY_EDITOR } from './helpers';\n\n/**\n * The parts of an editor's outer chrome that differ between presets; how they\n * reach CodeMirror's selectors lives once in `buildChromeStyles`.\n */\nexport type EditorChrome = {\n surface: string;\n borderColor: string;\n readOnlySurface: string;\n readOnlyBorderColor: string;\n /** `null` for a preset with no hover affordance — form inputs have none. */\n hoverBorderColor: string | null;\n focusBorderColor: string;\n focusRing: string;\n radius: string;\n paddingY: string;\n /** `null` leaves CodeMirror's own 6px/2px line inset alone. */\n paddingX: { left: string; right: string } | null;\n};\n\n/**\n * Mirrors `InputGroup` at the sizing each design language gives a `TextInput`,\n * so an editor dropped into a form reads as one of its fields.\n *\n * The legacy preset reads the neutral ramp because the legacy `secondary`\n * variant does. No semantic token holds that grey, and the nearest one\n * (`--muted`) is a few points off — which is the \"almost, but not quite, the\n * input next to it\" mismatch this preset exists to remove.\n */\nexport const buildInputChrome = (isArgo: boolean): EditorChrome => ({\n surface: isArgo ? resolveToken('muted', '241 245 249') : colors.neutral[100],\n borderColor: isArgo ? resolveToken('input', '203 213 225') : colors.neutral[100],\n readOnlySurface: isArgo ? resolveToken('muted', '241 245 249') : colors.neutral[150],\n readOnlyBorderColor: isArgo ? resolveToken('input', '203 213 225') : colors.neutral[150],\n hoverBorderColor: null,\n focusBorderColor: isArgo\n ? resolveToken('primary', '37 99 235')\n : resolveToken('ring', '31 143 255'),\n focusRing: `0 0 0 4px ${resolveToken('ring', '31 143 255', isArgo ? 0.5 : 0.3)}`,\n radius: isArgo ? 'var(--radius-lg, 0.25rem)' : '0.25rem',\n // 2px border + 2×this + `.cm-content`'s own 4px + a 20px line, against the\n // height a one-line `TextInput` has: argo forces `sizing: 'medium'` (36px),\n // legacy leaves it at `default` (40px).\n paddingY: isArgo ? '3px' : '5px',\n // Tops `.cm-line`'s 6px/2px up to the 16px an input's text is inset by.\n paddingX: { left: '10px', right: '14px' },\n});\n\n/** The SQL workspace's notebook cell: a white canvas, not a form control. */\nexport const buildCanvasChrome = (): EditorChrome => ({\n surface: resolveToken('card', '255 255 255'),\n borderColor: 'transparent',\n readOnlySurface: resolveToken('muted', '241 245 249'),\n readOnlyBorderColor: 'transparent',\n hoverBorderColor: resolveToken('ring', '31 143 255'),\n focusBorderColor: resolveToken('ring', '31 143 255'),\n focusRing: `0 0 0 4px ${resolveToken('ring', '31 143 255', 0.3)}`,\n radius: '8px',\n paddingY: '8px',\n paddingX: null,\n});\n\n/**\n * Spread over `buildBaseThemeStyles()` — never used alone. The read-only keys\n * are the base's own, so they replace its wash instead of landing beside it.\n */\nexport const buildChromeStyles = (chrome: EditorChrome) => ({\n '&.cm-editor': {\n border: `solid 1px ${chrome.borderColor}`,\n borderRadius: chrome.radius,\n backgroundColor: chrome.surface,\n paddingTop: chrome.paddingY,\n paddingBottom: chrome.paddingY,\n },\n '&.cm-editor :is(.cm-gutters,.cm-scroller)': { backgroundColor: chrome.surface },\n\n ...(chrome.paddingX\n ? {\n // Only without a gutter: there the editor reads as a one-line input and\n // its text should start where a neighbouring `TextInput`'s does. With a\n // gutter, the gutter owns the left edge.\n '&.cm-editor:not(:has(.cm-gutters)) .cm-content': {\n paddingLeft: chrome.paddingX.left,\n paddingRight: chrome.paddingX.right,\n },\n }\n : null),\n\n ...(chrome.hoverBorderColor\n ? { [`${EDITABLE_EDITOR}:hover`]: { borderColor: chrome.hoverBorderColor } }\n : null),\n [`${EDITABLE_EDITOR}:focus-within`]: {\n borderColor: chrome.focusBorderColor,\n boxShadow: chrome.focusRing,\n },\n\n [READ_ONLY_EDITOR]: {\n backgroundColor: chrome.readOnlySurface,\n borderColor: chrome.readOnlyBorderColor,\n },\n [`${READ_ONLY_EDITOR} .cm-gutters`]: { backgroundColor: chrome.readOnlySurface },\n [`${READ_ONLY_EDITOR} .cm-scroller`]: { backgroundColor: chrome.readOnlySurface },\n});\n","import { StateEffect, StateField, type Text } from '@codemirror/state';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n ViewPlugin,\n type ViewUpdate,\n} from '@codemirror/view';\n\nimport colors from '@keboola/tailwind-config/colors';\n\nimport { escapeStringRegexp } from '../../utils/escapeStringRegexp';\n\n// Represents a single search match in the editor\ntype SearchMatch = {\n /** Start position in document */\n from: number;\n /** End position in document */\n to: number;\n /** Text content of the match */\n text: string;\n /** Local match index within this editor (0-based) */\n localIndex: number;\n};\n\n// Effect to update search state\nconst setSearchEffect = StateEffect.define<{\n query: string;\n selectedMatchIndex?: number;\n}>();\n\n// State to track current search matches\ntype SearchState = {\n query: string;\n selectedMatchIndex?: number;\n matches: SearchMatch[];\n decorations: DecorationSet;\n};\n\n// Find all matches in the document\nfunction findMatches(doc: Text, query: string): SearchMatch[] {\n if (!query) return [];\n\n const text = doc.toString();\n\n try {\n const regex = new RegExp(escapeStringRegexp(query), 'gi');\n\n return Array.from(text.matchAll(regex)).map((match, index) => {\n const from = match.index!;\n const to = from + match[0].length;\n\n return { from, to, text: match[0], localIndex: index };\n });\n } catch (e) {\n // Invalid regex - return no matches\n console.warn('Invalid search regex:', e);\n return [];\n }\n}\n\n// Create decorations for search matches\nfunction createDecorations(matches: SearchMatch[], selectedLocalIndex?: number): DecorationSet {\n const decorations = matches.map((match) => {\n const isSelected = match.localIndex === selectedLocalIndex;\n\n const decoration = Decoration.mark({\n class: isSelected ? 'cm-searchMatch-selected' : 'cm-searchMatch',\n });\n\n return decoration.range(match.from, match.to);\n });\n\n return Decoration.set(decorations, true);\n}\n\n// StateField to manage search state\nconst searchField = StateField.define<SearchState>({\n create() {\n return {\n query: '',\n selectedMatchIndex: undefined,\n matches: [],\n decorations: Decoration.none,\n };\n },\n\n update(state, tr) {\n let newState = state;\n\n // Handle search effect\n for (const effect of tr.effects) {\n if (!effect.is(setSearchEffect)) {\n continue;\n }\n\n const { query, selectedMatchIndex } = effect.value;\n\n // Find matches\n const matches = findMatches(tr.state.doc, query);\n\n // Create decorations\n const decorations = createDecorations(matches, selectedMatchIndex);\n\n newState = {\n query,\n selectedMatchIndex,\n matches,\n decorations,\n };\n }\n\n // Map decorations through document changes\n if (tr.docChanged && newState.query) {\n const matches = findMatches(tr.state.doc, newState.query);\n const decorations = createDecorations(matches, newState.selectedMatchIndex);\n\n newState = {\n ...newState,\n matches,\n decorations,\n };\n }\n\n return newState;\n },\n\n provide: (field) => EditorView.decorations.from(field, (state) => state.decorations),\n});\n\n// View plugin to handle scrolling to selected match\nconst searchViewPlugin = ViewPlugin.fromClass(\n class {\n private lastSelectedIndex?: number;\n\n update(update: ViewUpdate) {\n const state = update.state.field(searchField);\n\n // Scroll to selected match when it changes\n if (\n state.selectedMatchIndex !== undefined &&\n state.selectedMatchIndex !== this.lastSelectedIndex\n ) {\n const match = state.matches[state.selectedMatchIndex];\n\n if (match) {\n requestAnimationFrame(() => {\n update.view.dispatch({\n effects: EditorView.scrollIntoView(match.from, { y: 'center' }),\n });\n });\n }\n\n this.lastSelectedIndex = state.selectedMatchIndex;\n }\n\n // Reset if no selection\n if (state.selectedMatchIndex === undefined) {\n this.lastSelectedIndex = undefined;\n }\n }\n },\n);\n\nconst searchTheme = EditorView.baseTheme({\n '.cm-searchMatch': {\n backgroundColor: colors.blue[100],\n },\n '.cm-searchMatch > span': {\n color: `${colors.blue[600]} !important`,\n },\n '.cm-searchMatch-selected': {\n backgroundColor: colors.blue[600],\n },\n '.cm-searchMatch-selected > span': {\n color: `${colors.white} !important`,\n },\n});\n\nexport function searchExtension() {\n return [searchField, searchViewPlugin, searchTheme];\n}\n\nexport function updateSearch(view: EditorView, query: string, selectedMatchIndex?: number) {\n view.dispatch({ effects: setSearchEffect.of({ query, selectedMatchIndex }) });\n}\n","import { isMac } from '../../utils';\nimport { Kbd } from '../Kbd';\n\nexport const ToggleComponentHelp = () => (\n <div>\n Use <Kbd>{isMac ? 'Command+/' : 'Ctrl+/'}</Kbd> to toggle comments.\n </div>\n);\n","import { type Extension } from '@codemirror/state';\n\nimport type { ResolvedColorScheme } from '../ThemeProvider/types';\nimport { useThemeAttributes } from '../ThemeProvider/useThemeAttributes';\n\n// Cached across component instances, not just across renders. A CodeMirror theme\n// extension carries its own StyleModule, and mounting an EditorView appends its\n// rules to a document-level stylesheet — which invalidates style for the whole\n// document. Sharing one module per theme keeps the stylesheet a constant size no\n// matter how many editors mount.\nconst themeCache = new Map<string, Extension>();\n\n/**\n * Memoize a CodeMirror theme/extension built from `resolveToken`, shared across\n * every instance that passes the same `cacheKey` and rebuilt whenever the active\n * brand / light-dark mode changes. `build` reads live `--*` values off `<html>`,\n * so the active theme is an invisible dependency a deps array can't see.\n *\n * `build` receives the scheme those values were read under, for the theme values\n * that are a light/dark *pair* rather than a token lookup (a categorical diff\n * wash has no semantic token, but an opaque light pastel still has to become a\n * low-alpha tint under dark). It comes from the same read that produced the key,\n * so a builder cannot resolve one scheme's colours under the other one's key.\n *\n * `cacheKey` is the extension's full identity: anything the builder closes over\n * must be part of it (e.g. `` `merge-pane:${deleted}` ``), or instances built\n * from different inputs would share one theme.\n */\nexport const useThemedExtension = (\n cacheKey: string,\n build: (scheme: ResolvedColorScheme) => Extension,\n): Extension => {\n const { scheme, cacheKey: themeKey } = useThemeAttributes();\n const key = `${themeKey} ${cacheKey}`;\n\n // The module-level cache is the memo; reading and filling it during render is\n // idempotent and keyed only on values already stable for the render.\n let cached = themeCache.get(key);\n if (!cached) {\n cached = build(scheme);\n themeCache.set(key, cached);\n }\n\n return cached;\n};\n","import { useMemo } from 'react';\nimport { Compartment, type Extension } from '@codemirror/state';\nimport { tooltips, ViewPlugin } from '@codemirror/view';\n\n// A `position: fixed` box is laid out against the viewport — and so escapes\n// every scroll container above it — only while no ancestor claims the job of\n// being its containing block. This encodes the CSS rule for who claims it\n// rather than the subset this repo happens to use today; `contain` and\n// `will-change` take value lists, so those two are matched loosely.\n//\n// `content-visibility` is absent on purpose: it implies containment without\n// saying so through `contain`, and it is handled below as a clipper — which is\n// the stronger of the two properties for our purposes.\nconst establishesFixedContainingBlock = (style: CSSStyleDeclaration) =>\n style.transform !== 'none' ||\n style.translate !== 'none' ||\n style.rotate !== 'none' ||\n style.scale !== 'none' ||\n style.perspective !== 'none' ||\n style.filter !== 'none' ||\n style.backdropFilter !== 'none' ||\n /\\b(paint|layout|strict|content)\\b/.test(style.contain) ||\n /\\b(transform|perspective|filter|contain)\\b/.test(style.willChange);\n\n// Crops its content, so hosting the tooltip inside it would not help. Paint\n// containment — which `content-visibility: auto` turns on without ever showing\n// up in computed `contain` — crops even a fixed-position descendant, and so\n// does a mask.\nconst crops = (style: CSSStyleDeclaration) =>\n style.overflowX !== 'visible' ||\n style.overflowY !== 'visible' ||\n style.maskImage !== 'none' ||\n style.contentVisibility !== 'visible' ||\n /\\b(paint|strict|content)\\b/.test(style.contain);\n\n/**\n * Where a tooltip can hang without being cropped, or `null` for \"wherever\n * CodeMirror would put it anyway\".\n *\n * Two ancestors matter, and they are not the same ancestor. The **outermost\n * cropper** is the one to get above — landing anywhere below it leaves the\n * tooltip inside the box doing the cropping. The **containing block** is where\n * the search can stop, because from there upwards `position: fixed` is measured\n * against that element and nothing higher can crop it.\n *\n * `document.body` and `<html>` are not treated as croppers: a fixed box whose\n * containing block is the viewport is not clipped by their overflow, and\n * hosting outside `<body>` would drop the tooltip out of the app's stacking and\n * pointer-events scope for no gain.\n */\nconst findTooltipHost = (from: HTMLElement) => {\n let outermostCropper: HTMLElement | null = null;\n\n for (let node = from.parentElement; node && node !== document.body; node = node.parentElement) {\n const style = getComputedStyle(node);\n\n if (crops(style)) {\n outermostCropper = node;\n } else if (establishesFixedContainingBlock(style)) {\n return outermostCropper?.parentElement ?? node;\n }\n }\n\n return outermostCropper?.parentElement ?? null;\n};\n\n/**\n * `tooltips()`, re-hosted so the completion popup is never cropped.\n *\n * CodeMirror hangs tooltips inside the editor and lets `position: fixed` carry\n * them past its edges. That holds only while the viewport is their containing\n * block — a modal centred with a translate, a sheet sliding in, or a box under\n * paint containment takes that job, and then every scroller, mask and contained\n * box in between crops the popup instead. A tall editor hides the damage; a\n * one-line one shows a sliver of an unreadable list.\n *\n * The two shapes this has to survive in production are a `Modal`, whose body\n * scrolls and carries the argo fade mask, and kbc-ui's SQL editor, which wraps\n * every code block in `content-visibility: auto` to keep long scripts cheap.\n *\n * Hosting the layer above the outermost cropper clears all of that while keeping\n * the popup inside the modal's stacking, focus and pointer-events scope — which\n * `document.body` would not: the popup would sit behind the modal, and Radix\n * leaves the body `pointer-events: none` while a dialog is open.\n *\n * Both editors install this, and it is the only place either of them configures\n * a tooltip host. Keep it that way: CodeMirror's tooltip config takes the first\n * contributor that names a parent, so a second mechanism would not compose with\n * this one — it would silently win or lose on extension order.\n */\nconst tooltipsExtension = (): Extension => {\n // The resolved host lives in a compartment, not in an appended config: React\n // hands CodeMirror a new extension array whenever the editor's props move,\n // which dispatches a full reconfigure. That replaces appended config, while\n // compartment contents are carried over.\n const layer = new Compartment();\n\n return [\n layer.of(tooltips()),\n ViewPlugin.define((view) => {\n // Deferred on two counts: a plugin cannot dispatch while the view it\n // belongs to is still being built, and reading computed styles here would\n // force a style and layout flush in the middle of the commit that inserted\n // the editor. The lookup is one-shot — an ancestor that gains a transform\n // afterwards is not picked up.\n const scheduled = setTimeout(() => {\n if (!view.dom.isConnected) return;\n\n const parent = findTooltipHost(view.dom);\n if (parent) view.dispatch({ effects: layer.reconfigure(tooltips({ parent })) });\n });\n\n return { destroy: () => clearTimeout(scheduled) };\n }),\n ];\n};\n\n/**\n * The extension above, built once per editor. Rebuilding it would hand\n * CodeMirror a fresh compartment and plugin on every reconfigure, dropping the\n * host it had already resolved — so it is only ever reached through this hook.\n */\nexport const useTooltipsExtension = () => useMemo(tooltipsExtension, []);\n","import type { Completion, CompletionContext, CompletionSource } from '@codemirror/autocomplete';\n\nimport { useStableCallback } from '../../hooks/useStableCallback';\n\nexport type EditorVariable = { name: string; value?: string };\n\n// Keywords come by the hundred from the language, so a variable would otherwise rank\n// below every one of them that shares a prefix.\nconst BOOST = 2000;\n\n// One brace or two, because `closeBrackets` turns a typed `{` into `{}` and a caret\n// that has only opened the placeholder is still asking for a variable. One charset\n// for the name throughout: a second, narrower one would start the range mid-name on\n// anything it disagreed about, and a range that starts mid-name never matches.\nconst NAME = String.raw`[\\w-]*`;\nconst AT_CARET = new RegExp(String.raw`(?:\\{{1,2} ?)?${NAME}$`);\nconst NAME_AT_END = new RegExp(`${NAME}$`);\nconst OPENING = /\\{{1,2} ?$/;\nconst CLOSING = /^ ?\\}{1,2}/;\n\n/**\n * Completes a mustache-style `{{name}}` placeholder.\n */\nexport const completeVariables = (variables: EditorVariable[] = []): CompletionSource => {\n if (variables.length === 0) return () => null;\n\n const options: Completion[] = variables.map(({ name, value }) => ({\n // The bare name: `SqlEditor` filters prefix-only while `CodeEditor` filters\n // fuzzily, and this is the only spelling both accept whether or not the caret\n // has typed the braces. The braces are `displayLabel`, which is what renders.\n label: name,\n displayLabel: `{{${name}}}`,\n detail: value,\n type: 'variable',\n boost: BOOST,\n apply: (view, completion, from, to) => {\n const { doc } = view.state;\n const line = doc.lineAt(from);\n const insert = `{{${completion.label}}}`;\n\n // The range covers the name alone, so the braces around it are found rather\n // than assumed — `closeBrackets` may have added a closing one nobody typed.\n const opening = OPENING.exec(doc.sliceString(line.from, from));\n const closing = CLOSING.exec(doc.sliceString(to, line.to));\n const start = opening ? from - opening[0].length : from;\n const end = closing ? to + closing[0].length : to;\n\n view.dispatch({\n changes: { from: start, to: end, insert },\n selection: { anchor: start + insert.length },\n });\n },\n }));\n\n return (context: CompletionContext) => {\n const match = context.matchBefore(AT_CARET);\n\n if (!match?.text) return null;\n\n const [name = ''] = NAME_AT_END.exec(match.text) ?? [];\n\n return { from: match.to - name.length, options };\n };\n};\n\n/**\n * The completion source both editors install, with an identity that never moves.\n *\n * Both hold it inside the memo that keys their whole extension tree, and callers\n * build the list inline — a config row mapped to `{ name, value }` in a store\n * selector, so a fresh array arrives on every store push. Because CodeMirror asks\n * the source for options rather than reading them up front, holding it steady costs\n * nothing: a completion request always reaches the latest render's variables.\n */\nexport const useVariableCompletion = (variables: EditorVariable[] = []): CompletionSource =>\n useStableCallback(completeVariables(variables));\n","import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';\nimport type { KeyboardEvent, ReactNode } from 'react';\nimport type { CompletionSource } from '@codemirror/autocomplete';\nimport { autocompletion, completeAnyWord } from '@codemirror/autocomplete';\nimport { unifiedMergeView } from '@codemirror/merge';\nimport { EditorView, keymap, placeholder as cmPlaceholder } from '@codemirror/view';\nimport CodeMirror, {\n EditorState,\n type Extension,\n type ReactCodeMirrorRef,\n} from '@uiw/react-codemirror';\n\nimport { keyCodes } from '../../constants/keyCodes';\nimport { useStableCallback } from '../../hooks/useStableCallback';\nimport { cn } from '../../utils';\nimport { HelpBlock } from '../HelpBlock';\nimport { useArgoDesign } from '../ThemeProvider/context';\n\nimport { ButtonToolbar } from './ButtonToolbar';\nimport { buildChromeStyles, buildInputChrome } from './editorChrome';\nimport type { LANGUAGE_MODE } from './helpers';\nimport {\n buildBaseThemeStyles,\n buildBasicSetup,\n buildCustomTheme,\n buildJsonLinter,\n getLanguageMode,\n shouldLintJson,\n} from './helpers';\nimport { searchExtension, updateSearch } from './search';\nimport { ToggleComponentHelp } from './ToggleComponentHelp';\nimport { useThemedExtension } from './tokenTheme';\nimport { useTooltipsExtension } from './tooltips';\nimport { type EditorVariable, useVariableCompletion } from './variableCompletion';\n\ntype Props = {\n value: string;\n previousValue?: string;\n /**\n * `'field'` draws the chrome an `InputGroup` draws — surface, border, radius,\n * focus ring, read-only wash — for an editor that is one control among others\n * in a form. It sizes to its content, so don't pin its height.\n *\n * `'plain'` (the default) is the full-bleed surface of an editor that *is* the\n * panel: a modal body, a chat block, a fixed-height viewer already framed by\n * whatever contains it.\n */\n variant?: 'plain' | 'field';\n mode?: LANGUAGE_MODE;\n placeholder?: string;\n /** Names the editable region for screen readers — the editor has no visible label of its own. */\n ariaLabel?: string;\n /**\n * Names the editable region from an existing element, for when the label is already on screen.\n * Prefer this over `ariaLabel` inside a form — `CodeEditorField` passes the field's own label id.\n */\n ariaLabelledBy?: string;\n /** Links the editable region to help / error text. Space-delimited idref list. */\n ariaDescribedBy?: string;\n /** Marks the editable region invalid. Visual error styling is the caller's (`variant=\"field\"`). */\n ariaInvalid?: boolean;\n ariaRequired?: boolean;\n /**\n * Treats a blank document as valid instead of a parse error (JSON modes only).\n *\n * - Off by default: for a standalone editor \"Unexpected end of input\" is correct, and at several\n * call sites the gutter marker is the only thing explaining a Save button that\n * `isValidJsonConfig('') === false` has already disabled.\n * - `CodeEditorField` turns it on for a field that is not `required`, where an empty document is\n * how the value is removed.\n */\n allowBlankDocument?: boolean;\n /**\n * Fires when focus leaves the editable region — what a form connector needs to mark its field\n * blurred, which is the gate errors are revealed on.\n *\n * - Bound as a CodeMirror DOM handler on the content node, not on the wrapper: the wrapper is not\n * what gets focused.\n * - Installed only when passed, so an editor without it keeps the extension set it had.\n */\n onBlur?: () => void;\n /**\n * Highlights every occurrence and scrolls the selected one into view. The find\n * UI is the caller's — pass the query it holds, and omit both props entirely to\n * leave the search extension uninstalled.\n */\n searchQuery?: string;\n searchMatchIndex?: number;\n readOnly?: boolean;\n /**\n * Refuses edits while leaving the editor looking and behaving as it did — for a\n * transient lock such as an in-flight save, where a keystroke landing mid-request\n * would be overwritten by the response. `readOnly` is the wrong prop for that:\n * it turns the editor into a viewer, greying the surface and taking the lint\n * marks and completions with it.\n */\n inputLocked?: boolean;\n /**\n * A flat list of completions, offered everywhere in the document. One word per\n * label: CodeMirror derives the pattern for the word being completed from the\n * labels' characters, so a space in one widens it across whitespace and the\n * editor offers nothing past the first word of a line. A phrase belongs in\n * `completionSource`.\n *\n * Compared by identity, like `completionSource` — hand the editor a stable array.\n */\n autocompletions?: string[];\n /**\n * Completions that depend on where the cursor is — a column list offered only\n * after its table, say. Wins over both `autocompletions` and `completeAny`,\n * which stay the right props for a list that is the same everywhere in the\n * document and for having no list at all. Like them, it opens on typing.\n *\n * Compared by identity: build it in a `useMemo` or the editor rebuilds its whole\n * extension tree on every render.\n */\n completionSource?: CompletionSource;\n /**\n * Configuration variables, completed into `{{name}}`. Independent of\n * `completionSource`: both are offered, so a caller keeps its own completions and\n * gets variables spelled the way the rest of the platform writes them.\n */\n variables?: EditorVariable[];\n extraKeys?: Record<string, () => void>;\n withToggleCommentHint?: boolean;\n withAutofocus?: boolean;\n withLineNumbers?: boolean;\n withLineWrapping?: boolean;\n withCollapseUnchanged?: boolean;\n withCopyButton?: boolean;\n completeAny?: boolean;\n help?: ReactNode;\n helpPostfix?: ReactNode;\n /**\n * Extra actions for the toolbar that floats over the editor's top-right corner,\n * beside the copy button. The toolbar is a 28px chip, so pass `size=\"icon-xs\"`\n * buttons — a default-sized one grows the chip and de-aligns the copy button.\n */\n renderAdditionalButtons?: (value?: string) => ReactNode;\n className?: string;\n} & (\n | { readOnly: true; onChange?: never }\n // `boolean` rather than `false`: a field the user's permissions may lock still\n // needs its handler for the case where they can edit.\n | { readOnly?: boolean; onChange: (value: string) => void }\n);\n\nconst emptyObject = {};\n\nexport const CodeEditor = ({\n value,\n previousValue,\n onChange,\n variant = 'plain',\n mode = 'application/json',\n placeholder = '',\n ariaLabel,\n ariaLabelledBy,\n ariaDescribedBy,\n ariaInvalid,\n ariaRequired,\n allowBlankDocument = false,\n onBlur,\n searchQuery,\n searchMatchIndex,\n readOnly = false,\n inputLocked = false,\n autocompletions,\n completionSource,\n variables,\n extraKeys = emptyObject,\n withToggleCommentHint = false,\n withAutofocus = false,\n withLineNumbers = true,\n withLineWrapping = true,\n withCollapseUnchanged = false,\n withCopyButton = false,\n completeAny = false,\n help = null,\n helpPostfix = null,\n renderAdditionalButtons,\n className,\n}: Props) => {\n // CodeMirror rebuilds and re-resolves the whole extension tree whenever the\n // change handler's identity moves, and callers pass inline arrows.\n const handleChange = useStableCallback((next: string) => onChange?.(next));\n const handleBlur = useStableCallback(() => onBlur?.());\n\n // Themes re-resolve their `--*` tokens on brand / light-dark change. The\n // syntax palette is keyed without a component prefix so `SqlEditor` — which\n // builds it from the same `buildCustomTheme` — shares this one module.\n // Presence, not truthiness: a caller that searches always passes the prop, so\n // the extension set stays stable while the query changes.\n const withSearch = searchQuery !== undefined;\n // Same presence-not-truthiness reasoning as `withSearch`: gate the handler extension on the prop\n // being passed at all, so every existing caller keeps the extension set it had.\n const withBlur = onBlur !== undefined;\n const editorRef = useRef<ReactCodeMirrorRef>(null);\n\n // One object so the extension list has a single dependency instead of five, and `null` when nothing\n // is set so the extension is left out entirely rather than added empty.\n const contentAria = useMemo(() => {\n const attributes: Record<string, string> = {};\n if (ariaLabel !== undefined) attributes['aria-label'] = ariaLabel;\n if (ariaLabelledBy !== undefined) attributes['aria-labelledby'] = ariaLabelledBy;\n if (ariaDescribedBy !== undefined) attributes['aria-describedby'] = ariaDescribedBy;\n // Stringified because `contentAttributes` writes DOM attributes, where `aria-invalid=\"false\"` and\n // an absent attribute mean the same thing but `false` would be dropped by a truthiness check.\n if (ariaInvalid !== undefined) attributes['aria-invalid'] = String(ariaInvalid);\n if (ariaRequired !== undefined) attributes['aria-required'] = String(ariaRequired);\n return Object.keys(attributes).length > 0 ? attributes : null;\n }, [ariaLabel, ariaLabelledBy, ariaDescribedBy, ariaInvalid, ariaRequired]);\n\n useEffect(() => {\n const view = editorRef.current?.view;\n if (view && withSearch) updateSearch(view, searchQuery, searchMatchIndex);\n }, [withSearch, searchQuery, searchMatchIndex]);\n\n // A view created while a query is already set — a remount, a tab switch —\n // starts with no highlights unless the search is applied as it is built.\n const handleCreateEditor = useStableCallback((view: EditorView) => {\n if (searchQuery) updateSearch(view, searchQuery, searchMatchIndex);\n });\n\n // Same reasoning as `onChange` above, one level out: callers build this object\n // inline, so keying the extensions on it would reconfigure the editor on every\n // parent render. Only the set of bound keys can change what the keymap *is* —\n // the handlers behind them are read when the key is actually pressed.\n const extraKeysRef = useRef(extraKeys);\n useLayoutEffect(() => {\n extraKeysRef.current = extraKeys;\n });\n\n const boundKeysSignature = Object.keys(extraKeys).join('\\n');\n const boundKeys = useMemo(\n () => boundKeysSignature.split('\\n').filter(Boolean),\n [boundKeysSignature],\n );\n\n const tooltipLayer = useTooltipsExtension();\n\n // `languageData.of` takes a function CodeMirror calls per completion request, so\n // the source is built here rather than inside it — otherwise every keystroke that\n // opens the popup rebuilds an option per variable.\n const variableCompletion = useVariableCompletion(variables);\n\n const customTheme = useThemedExtension('editor:syntax', buildCustomTheme);\n\n // The brand decides which `InputGroup` the field chrome has to match, so it is\n // part of the theme's identity — `useThemedExtension` caches per key across\n // every instance, and the theme signal it keys on carries only `<html>`.\n const isArgo = useArgoDesign();\n const isField = variant === 'field';\n const baseTheme = useThemedExtension(\n isField ? `code-editor:field:${isArgo ? 'argo' : 'legacy'}` : 'code-editor:chrome',\n () =>\n EditorView.theme({\n ...buildBaseThemeStyles(),\n ...(isField ? buildChromeStyles(buildInputChrome(isArgo)) : null),\n }),\n );\n\n const commonExtensions: Extension[] = useMemo(() => {\n const callerCompletions =\n completionSource ??\n (completeAny ? completeAnyWord : autocompletions?.length ? autocompletions : null);\n\n // An empty list is left out: CodeMirror wraps a list in `completeFromList`, which\n // answers an empty result rather than none, so the editor would run a source that\n // can never match on every keystroke.\n const completionEntries = [\n ...(callerCompletions ? [{ autocomplete: callerCompletions }] : []),\n { autocomplete: variableCompletion },\n ];\n\n return [\n getLanguageMode(mode),\n shouldLintJson(mode, readOnly) ? buildJsonLinter(allowBlankDocument) : [],\n withLineWrapping ? EditorView.lineWrapping : [],\n EditorState.languageData.of(() => completionEntries),\n keymap.of(\n boundKeys.map((key) => ({\n key,\n run: () => {\n extraKeysRef.current[key]?.();\n return true;\n },\n })),\n ),\n readOnly\n ? []\n : [\n // CodeMirror's own default. Gating it on the props hid completions the\n // *language* supplies — dbt's vocabulary, Snowflake's keywords — behind\n // a shortcut, and macOS leaves no usable one. With nothing to offer, no\n // popup opens anyway.\n autocompletion(),\n ],\n // Every a11y attribute goes onto the *content* node, not the wrapper: CodeMirror's\n // `div[role=\"textbox\"]` is what gets focused, so it is the only element AT will read them from.\n contentAria ? EditorView.contentAttributes.of(contentAria) : [],\n withBlur ? EditorView.domEventHandlers({ blur: handleBlur }) : [],\n withSearch ? searchExtension() : [],\n tooltipLayer,\n baseTheme,\n ];\n }, [\n autocompletions,\n completionSource,\n variableCompletion,\n completeAny,\n boundKeys,\n mode,\n readOnly,\n allowBlankDocument,\n withLineWrapping,\n baseTheme,\n contentAria,\n withBlur,\n handleBlur,\n withSearch,\n tooltipLayer,\n ]);\n\n const extensions = useMemo(() => {\n return [\n ...commonExtensions,\n cmPlaceholder(placeholder),\n EditorView.editable.of(!readOnly),\n // The lock is this facet and nothing else. `contenteditable` is what the\n // read-only wash keys off, and `basicSetup` is what holds the undo history,\n // so leaving both alone is what makes the lock invisible.\n EditorState.readOnly.of(readOnly || inputLocked),\n previousValue\n ? unifiedMergeView({\n original: previousValue,\n mergeControls: false,\n highlightChanges: false,\n collapseUnchanged: withCollapseUnchanged ? {} : undefined,\n })\n : [],\n ];\n }, [commonExtensions, placeholder, readOnly, inputLocked, previousValue, withCollapseUnchanged]);\n\n const config = useMemo(() => {\n return {\n ...buildBasicSetup(readOnly),\n lineNumbers: withLineNumbers,\n // Mod-f opens CodeMirror's own panel, which would run a second query and a\n // second match count over the same document beside the caller's input.\n ...(withSearch ? { searchKeymap: false } : null),\n };\n }, [withLineNumbers, readOnly, withSearch]);\n\n return (\n // oxlint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n data-variant={variant}\n className={cn(\n // Scoped to the box CodeMirror renders into rather than to every child, so\n // the toolbar below does not have to undo all three in `!important`.\n 'tw:relative tw:flex tw:min-h-0 tw:flex-col tw:[&_.cm-mergeViewEditor]:overflow-visible tw:[&_.cm-mergeViewEditors]:h-full tw:[&_.cm-mergeView]:h-full tw:[&_>.cm-theme]:h-full',\n // A field's `.cm-editor` is rounded, so the square box behind it would show\n // at the corners, and `overflow-auto` would crop the focus ring — a shadow\n // painted outside the editor's own box.\n isField\n ? 'tw:[&_>.cm-theme]:overflow-visible tw:[&_>.cm-theme]:bg-transparent'\n : 'tw:[&_>.cm-theme]:overflow-auto tw:[&_>.cm-theme]:bg-background',\n className,\n )}\n onKeyDown={(event: KeyboardEvent) => {\n if (event.key === keyCodes.ESCAPE) {\n event.stopPropagation();\n }\n }}\n >\n <ButtonToolbar value={withCopyButton ? value : undefined}>\n {renderAdditionalButtons?.(value)}\n </ButtonToolbar>\n <CodeMirror\n ref={editorRef}\n onCreateEditor={handleCreateEditor}\n theme={customTheme}\n value={value}\n onChange={handleChange}\n extensions={extensions}\n autoFocus={withAutofocus}\n basicSetup={config}\n />\n {!readOnly && (withToggleCommentHint || help || helpPostfix) && (\n <HelpBlock className=\"tw:mt-2 tw:flex tw:flex-wrap tw:gap-1\">\n {help}\n {withToggleCommentHint ? <ToggleComponentHelp /> : null}\n {helpPostfix}\n </HelpBlock>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Combobox-Dgm6Z4ib.js","names":["BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","BaseCombobox","Combobox","BaseCombobox"],"sources":["../src/components/Combobox/utils.ts","../src/components/Combobox/ComboboxChips.tsx","../src/components/Combobox/ComboboxContent.tsx","../src/components/Combobox/ComboboxEmpty.tsx","../src/components/Combobox/ComboboxInput.tsx","../src/components/Combobox/ComboboxInputGroup.tsx","../src/components/Combobox/ComboboxItemIndicator.tsx","../src/components/Combobox/ComboboxItem.tsx","../src/components/Combobox/ComboboxList.tsx","../src/components/Combobox/ComboboxRoot.tsx","../src/components/Combobox/ComboboxSeparator.tsx","../src/components/Combobox/Group/ComboboxGroup.tsx","../src/components/Combobox/Group/ComboboxGroupLabel.tsx","../src/components/Combobox/Group/ComboboxCollection.tsx","../src/components/Combobox/Combobox.tsx"],"sourcesContent":["import type { CreatableItem, Group, InternalItems, LabeledItem, SelectAllItem } from './types';\n\nconst isPlainObject = (item: unknown): item is Record<string, unknown> =>\n item !== null && typeof item === 'object';\n\nconst isNumber = (item: unknown): item is number => typeof item === 'number';\nconst isString = (item: unknown): item is string => typeof item === 'string';\n\nexport const isLabeledItem = (item: unknown): item is LabeledItem =>\n isPlainObject(item) && Reflect.has(item, 'label') && Reflect.has(item, 'value');\n\nconst isInternalItem = (item: unknown): item is InternalItems =>\n isLabeledItem(item) && '__marker' in item;\n\nexport const isSelectAllItem = (item: unknown): item is SelectAllItem =>\n isInternalItem(item) && item.__marker === 'selectAll';\n\nexport const isCreatableItem = (item: unknown): item is CreatableItem => {\n return isInternalItem(item) && item.__marker === 'creatable';\n};\n\nexport const isGroupItem = <Item>(itemOrGroup: Item | Group<Item>): itemOrGroup is Group<Item> =>\n itemOrGroup !== null && typeof itemOrGroup === 'object' && Reflect.has(itemOrGroup, 'items');\n\nexport const isGroupItems = <Item, GroupShape extends Group<Item> = Group<Item>>(\n items: readonly (Item | GroupShape)[],\n): items is GroupShape[] => {\n if (!Array.isArray(items)) return false;\n if (items.length === 0) return false; // Base UI treats an empty items array as non-grouped, so we must too for consistency\n return isGroupItem(items[0]); // Base UI only checks the first item to determine if it's a group or not, so we do the same for consistency\n};\n\nexport const defaultItemToLabel = <Item>(item: Item) => {\n if (isNumber(item) || isString(item)) return item;\n if (!isLabeledItem(item))\n throw new Error(\n 'Combobox: Item does not have a `label` field. Pass `itemToLabel` for custom item shapes.',\n );\n\n return item.label;\n};\n\n/** Display string for an item — mirrors base-ui's own default logic. */\nexport const toLabel = (item: unknown): string => {\n if (isString(item)) return item;\n if (isLabeledItem(item)) {\n if (item.label) return item.label;\n if (item.value) return item.value;\n }\n return String(item);\n};\n\n/** Equality key for an item — prefers .value for stable identity. */\nexport const toValueKey = (item: unknown): string => {\n if (isString(item)) return item;\n if (isLabeledItem(item)) {\n if (item.value) return item.value;\n if (item.label) return item.label;\n }\n return String(item);\n};\n\nexport const defaultItemToIcon = <Item>(item: Item) =>\n isLabeledItem(item) ? item.icon : undefined;\n\nexport const defaultItemToDisabled = <Item>(item: Item) =>\n isLabeledItem(item) ? (item.disabled ?? false) : false;\n\nexport const defaultGroupToLabel = () => undefined;\n\n// Internal markers ------------------------------------------------------------\n// Both `selectAll` and `creatable` are LabeledItem-shaped sentinels that we\n// inject into the items list passed to Base UI. They carry a `__marker`\n// discriminator so consumer code (and user-supplied callbacks) can't collide\n// with them by accident.\n\nexport const selectAllItem: SelectAllItem = {\n __marker: 'selectAll',\n value: '__select_all__',\n label: 'Select All',\n};\n\nexport const createCreatableItem = (query: string): CreatableItem => ({\n __marker: 'creatable',\n value: query,\n label: query,\n});\n\nexport const defaultToCreateValue = <Value>(\n query: string,\n value: Value | undefined,\n queryToCreateValue?: (query: string) => Value,\n): Value => {\n if (queryToCreateValue) return queryToCreateValue(query);\n if (value === undefined) return query as Value;\n if (isString(value)) return query as Value;\n if (isLabeledItem(value)) return { value: query, label: query } as Value;\n throw new Error(\n 'Combobox: Cannot infer item shape for `allowCreate`. Pass `queryToCreateValue` for custom item shapes.',\n );\n};\n\nexport const defaultQueryToCreateLabel = (query: string) => `Create \"${query}\"`;\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { X } from '../../icons';\nimport { Badge } from '../Badge';\n\nimport { defaultItemToLabel } from './utils';\n\ntype BadgeColor = ComponentProps<typeof Badge>['color'];\ntype BadgeVariant = ComponentProps<typeof Badge>['variant'];\n\ntype Props<Value> = {\n maxVisible?: number;\n itemToChipLabel?: (item: Value) => ReactNode;\n itemToChipColor?: (item: Value) => BadgeColor;\n variant?: BadgeVariant;\n};\n\nexport const ComboboxChips = <Value,>({\n maxVisible = 3,\n itemToChipLabel = defaultItemToLabel,\n itemToChipColor,\n variant = 'pill',\n}: Props<Value>) => (\n <BaseCombobox.Value>\n {(values: Value[]) => {\n if (!values.length) return null;\n\n const visible = values.slice(0, maxVisible);\n const overflow = values.slice(maxVisible);\n\n return (\n <>\n {visible.map((value: Value, index) => (\n <BaseCombobox.Chip\n // oxlint-disable-next-line react/no-array-index-key\n key={index}\n render={\n <Badge.Root\n color={itemToChipColor?.(value)}\n className=\"tw:max-w-40\"\n variant={variant}\n />\n }\n >\n <Badge.Label>{itemToChipLabel(value)}</Badge.Label>\n <Badge.Addon variant=\"inline\" align=\"inline-end\">\n <BaseCombobox.ChipRemove\n render={\n <Badge.Button aria-label=\"Remove value\">\n <X className=\"tw:size-3\" />\n </Badge.Button>\n }\n />\n </Badge.Addon>\n </BaseCombobox.Chip>\n ))}\n\n {overflow.length > 0 && (\n <Badge.Root variant=\"pill\">\n <Badge.Label>+{overflow.length}</Badge.Label>\n </Badge.Root>\n )}\n </>\n );\n }}\n </BaseCombobox.Value>\n);\n","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../utils';\nimport { useArgoDesign } from '../ThemeProvider/context';\n\ntype PortalProps = ComponentProps<typeof BaseCombobox.Portal>;\ntype PositionerProps = ComponentProps<typeof BaseCombobox.Positioner>;\ntype PopupProps = Omit<ComponentProps<typeof BaseCombobox.Popup>, 'className'> & {\n className?: string;\n};\n\ntype Variant = 'default' | 'argo';\n\ntype Props = PopupProps &\n Pick<PositionerProps, 'side' | 'align' | 'sideOffset' | 'alignOffset' | 'anchor'> &\n Pick<PortalProps, 'container'>;\n\nexport const ComboboxContent = ({\n ref,\n align = 'start',\n side = 'bottom',\n sideOffset = 4,\n alignOffset,\n anchor,\n container,\n className,\n children,\n ...popupProps\n}: Props) => {\n const effectiveVariant: Variant = useArgoDesign() ? 'argo' : 'default';\n return (\n <BaseCombobox.Portal container={container}>\n <BaseCombobox.Positioner\n align={align}\n side={side}\n sideOffset={sideOffset}\n alignOffset={alignOffset}\n anchor={anchor}\n className=\"tw:isolate tw:z-[1055] tailwindcss-preflight\"\n >\n <BaseCombobox.Popup\n ref={ref}\n data-chips={!!anchor}\n data-variant={effectiveVariant}\n className={cn(\n 'tw:!pointer-events-auto',\n 'tw:group/combobox-content',\n 'tw:relative',\n 'tw:flex tw:flex-col tw:overflow-hidden',\n\n // sizing\n 'tw:max-h-[var(--available-height)]',\n 'tw:w-[var(--anchor-width)]',\n 'tw:max-w-[var(--available-width)]',\n 'tw:origin-[var(--transform-origin)]',\n 'tw:data-[chips=true]:min-w-[var(--anchor-width)]',\n\n // appearance\n 'tw:rounded-lg',\n 'tw:data-[variant=default]:rounded',\n\n 'tw:bg-popover',\n 'tw:text-popover-foreground',\n 'tw:shadow-md',\n 'tw:ring-1',\n 'tw:ring-foreground/10',\n 'tw:duration-100',\n\n // open animation\n 'data-open:animate-in',\n 'data-open:fade-in-0',\n 'data-open:zoom-in-95',\n\n // closed animation\n 'data-closed:animate-out',\n 'data-closed:fade-out-0',\n 'data-closed:zoom-out-95',\n\n // position animations\n 'tw:data-[side=bottom]:slide-in-from-top-2',\n 'tw:data-[side=top]:slide-in-from-bottom-2',\n 'tw:data-[side=left]:slide-in-from-right-2',\n 'tw:data-[side=right]:slide-in-from-left-2',\n 'tw:data-[side=inline-start]:slide-in-from-right-2',\n 'tw:data-[side=inline-end]:slide-in-from-left-2',\n className,\n )}\n {...popupProps}\n >\n {children}\n </BaseCombobox.Popup>\n </BaseCombobox.Positioner>\n </BaseCombobox.Portal>\n );\n};\n","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../utils';\n\ntype Props = Omit<ComponentProps<typeof BaseCombobox.Empty>, 'className'> & {\n className?: string;\n};\n\nexport const ComboboxEmpty = ({ ref, className, ...props }: Props) => (\n <BaseCombobox.Empty\n ref={ref}\n className={cn(\n 'tw:hidden',\n 'tw:group-data-[empty]/combobox-content:flex',\n 'tw:justify-center',\n 'tw:items-center',\n 'tw:text-center',\n 'tw:px-2',\n 'tw:text-muted-foreground',\n 'tw:py-6',\n className,\n )}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { InputGroup } from '../InputGroup';\n\ntype Props = Omit<ComponentProps<typeof BaseCombobox.Input>, 'render'>;\n\nexport const ComboboxInput = ({ ref, ...props }: Props) => (\n <BaseCombobox.Input {...props} ref={ref} render={<InputGroup.Input />} />\n);\n","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { InputGroup } from '../InputGroup';\n\ntype InputGroupProps = Pick<\n ComponentProps<typeof InputGroup>,\n 'variant' | 'focusVariant' | 'sizing' | 'state'\n>;\n\ntype Props = InputGroupProps &\n Omit<ComponentProps<typeof BaseCombobox.InputGroup>, 'render' | 'className'> & {\n className?: string;\n };\n\nexport const ComboboxInputGroup = ({\n ref,\n state,\n variant,\n sizing,\n focusVariant,\n className,\n ...props\n}: Props) => (\n <BaseCombobox.InputGroup\n {...props}\n ref={ref}\n render={\n <InputGroup\n state={state}\n variant={variant}\n focusVariant={focusVariant}\n sizing={sizing}\n className={className}\n />\n }\n />\n);\n","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { Check } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Variant = 'check' | 'checkbox';\n\ntype Props = Omit<ComponentProps<typeof BaseCombobox.ItemIndicator>, 'className' | 'children'> & {\n className?: string;\n variant?: Variant;\n};\n\nexport const ComboboxItemIndicator = ({ ref, className, variant = 'check', ...props }: Props) => {\n if (variant === 'checkbox') {\n return (\n <BaseCombobox.ItemIndicator\n ref={ref}\n keepMounted\n className={cn(\n 'tw:group/combobox-item-indicator',\n\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:size-4',\n 'tw:shrink-0',\n\n 'tw:rounded',\n 'tw:border',\n 'tw:border-input',\n 'tw:bg-background',\n\n 'tw:data-[selected]:bg-primary',\n 'tw:data-[selected]:border-primary',\n className,\n )}\n {...props}\n >\n <Check\n className={cn(\n 'tw:hidden',\n 'tw:size-3',\n 'tw:stroke-[4px]',\n 'tw:!text-primary-foreground',\n 'tw:group-data-[selected]/combobox-item-indicator:block',\n )}\n />\n </BaseCombobox.ItemIndicator>\n );\n }\n\n return (\n <BaseCombobox.ItemIndicator\n {...props}\n ref={ref}\n className={cn(\n 'tw:pointer-events-none',\n 'tw:absolute',\n 'tw:right-2',\n\n 'tw:group-data-[variant=default]/combobox-content:right-4',\n // `render={<Check />}` makes the icon the indicator element itself (not a descendant), so a\n // `[&_svg]` rule never matches it — size it directly or Lucide renders at its 24px default.\n 'tw:size-4',\n 'tw:group-data-[highlighted]/combobox-item:text-accent-foreground',\n 'tw:group-data-[variant=default]/combobox-content:group-data-[highlighted]/combobox-item:text-foreground',\n className,\n )}\n render={<Check />}\n />\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../utils';\n\nimport { ComboboxItemIndicator } from './ComboboxItemIndicator';\n\ntype Props = Omit<ComponentProps<typeof BaseCombobox.Item>, 'className'> & {\n className?: string;\n icon?: ReactNode;\n indicator?: ComponentProps<typeof ComboboxItemIndicator>['variant'];\n};\n\nexport const ComboboxItem = ({\n ref,\n className,\n children,\n icon,\n indicator: variant = 'check',\n ...props\n}: Props) => (\n <BaseCombobox.Item\n {...props}\n ref={ref}\n data-slot=\"combobox-item\"\n className={cn(\n 'tw:group/combobox-item',\n // layout\n 'tw:relative',\n 'tw:flex',\n 'tw:flex-1',\n 'tw:items-center',\n 'tw:gap-2',\n\n // spacing\n 'tw:py-2',\n 'tw:px-2',\n 'tw:group-data-[variant=default]/combobox-content:px-4',\n 'tw:rounded-lg',\n 'tw:group-data-[variant=default]/combobox-content:rounded-none',\n\n // typography\n 'tw:text-sm',\n 'tw:select-none',\n 'tw:cursor-default',\n 'tw:outline-hidden',\n\n // highlighted (keyboard / hover)\n 'tw:data-[highlighted]:bg-accent',\n 'tw:group-data-[variant=default]/combobox-content:data-[highlighted]:bg-neutral-100',\n 'tw:data-[highlighted]:text-accent-foreground',\n 'tw:group-data-[variant=default]/combobox-content:data-[highlighted]:text-foreground',\n\n // disabled\n 'tw:data-disabled:pointer-events-none',\n 'tw:data-disabled:opacity-50',\n\n // child svg defaults\n 'tw:[&_svg]:pointer-events-none',\n 'tw:[&_svg]:shrink-0',\n 'tw:[&_svg]:text-muted-foreground',\n \"tw:[&_svg:not([class*='size-'])]:size-4\",\n className,\n )}\n >\n {<ComboboxItemIndicator variant={variant} />}\n {icon}\n <span className=\"tw:truncate\">{children}</span>\n </BaseCombobox.Item>\n);\n","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../utils';\n\ntype Props = Omit<ComponentProps<typeof BaseCombobox.List>, 'className'> & {\n className?: string;\n};\n\nexport const ComboboxList = ({ ref, className, ...props }: Props) => (\n <BaseCombobox.List\n ref={ref}\n className={cn(\n 'tw:no-scrollbar',\n 'tw:scroll-py-1',\n 'tw:overflow-y-auto',\n 'tw:overscroll-contain',\n 'tw:min-h-0',\n 'tw:flex-1',\n\n 'tw:p-2',\n 'tw:data-[empty]:p-0',\n 'tw:group-data-[variant=default]/combobox-content:p-0',\n className,\n )}\n {...props}\n />\n);\n","import { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nexport const ComboboxRoot = <Value, Multiple extends boolean | undefined = false>(\n props: BaseCombobox.Root.Props<Value, Multiple>,\n) => <BaseCombobox.Root {...props} />;\n","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../utils';\n\ntype Props = Omit<ComponentProps<typeof BaseCombobox.Separator>, 'className'> & {\n className?: string;\n};\n\nexport const ComboboxSeparator = ({ ref, className, ...props }: Props) => (\n <BaseCombobox.Separator\n ref={ref}\n className={cn('tw:mx-2 tw:my-1 tw:h-px tw:bg-border', className)}\n {...props}\n />\n);\n","import type { ComponentProps } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../../utils';\n\ntype Props = Omit<ComponentProps<typeof BaseCombobox.Group>, 'className'> & {\n className?: string;\n};\n\nexport const ComboboxGroup = ({ ref, className, children, ...props }: Props) => (\n <BaseCombobox.Group\n ref={ref}\n className={cn('tw:flex tw:flex-col tw:gap-0.5', className)}\n {...props}\n >\n {children}\n </BaseCombobox.Group>\n);\n","import { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { cn } from '../../../utils';\n\ntype Props = Omit<BaseCombobox.GroupLabel.Props, 'className'> & {\n className?: string;\n};\n\nexport const ComboboxGroupLabel = ({ ref, className, ...props }: Props) => (\n <BaseCombobox.GroupLabel\n {...props}\n ref={ref}\n className={cn(\n // Base (argo variant) — soft gray section label.\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:text-xs',\n 'tw:font-medium',\n 'tw:leading-none',\n 'tw:text-muted-foreground',\n\n 'tw:group-data-[variant=default]/combobox-content:uppercase',\n 'tw:group-data-[variant=default]/combobox-content:font-semibold',\n 'tw:group-data-[variant=default]/combobox-content:tracking-wider',\n 'tw:group-data-[variant=default]/combobox-content:text-[11px]',\n 'tw:group-data-[variant=default]/combobox-content:text-black',\n 'tw:group-data-[variant=default]/combobox-content:pt-2',\n 'tw:group-data-[variant=default]/combobox-content:px-4',\n\n className,\n )}\n />\n);\n","import { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\ntype Props = BaseCombobox.Collection.Props;\n\nexport const ComboboxCollection = ({ ...props }: Props) => (\n <BaseCombobox.Collection data-slot=\"combobox-collection\" {...props} />\n);\n","import {\n type ComponentProps,\n type CSSProperties,\n type ReactNode,\n useEffect,\n useRef,\n useState,\n} from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\nimport { useVirtualizer } from '@tanstack/react-virtual';\n\nimport { ChevronDown, Plus, X } from '../../icons';\nimport { InputGroup } from '../InputGroup';\n\nimport { ComboboxChips } from './ComboboxChips';\nimport { ComboboxContent } from './ComboboxContent';\nimport { ComboboxEmpty } from './ComboboxEmpty';\nimport { ComboboxInput } from './ComboboxInput';\nimport { ComboboxInputGroup } from './ComboboxInputGroup';\nimport { ComboboxItem } from './ComboboxItem';\nimport { ComboboxList } from './ComboboxList';\nimport { ComboboxRoot } from './ComboboxRoot';\nimport { ComboboxSeparator } from './ComboboxSeparator';\nimport { ComboboxCollection, ComboboxGroup, ComboboxGroupLabel } from './Group';\nimport type { Group } from './types';\nimport {\n createCreatableItem,\n defaultGroupToLabel,\n defaultItemToDisabled,\n defaultItemToIcon,\n defaultItemToLabel,\n defaultQueryToCreateLabel,\n defaultToCreateValue,\n isCreatableItem,\n isGroupItem,\n isGroupItems,\n toLabel,\n toValueKey,\n} from './utils';\n\n// Above this many (ungrouped) items, the list is windowed with `@tanstack/react-virtual` so only\n// the visible rows hit the DOM. Base UI keeps keyboard nav + filtering working against the full\n// `items` set (via `virtualized`), so search is unaffected.\nconst VIRTUALIZE_THRESHOLD = 30;\nconst ESTIMATED_ROW_HEIGHT = 40;\nconst ESTIMATED_LIST_HEIGHT = 320;\n\ntype ComboboxProps<Value> = BaseCombobox.Root.Props<Value, false>;\ntype ComboboxInputProps = ComponentProps<typeof ComboboxInput>;\ntype ComboboxInputGroupProps = ComponentProps<typeof ComboboxInputGroup>;\ntype ComboboxItemProps = ComponentProps<typeof ComboboxItem>;\n\ntype Indicator = NonNullable<ComboboxItemProps['indicator']>;\n\ntype PublicComboboxInputProps = Pick<ComboboxInputProps, 'placeholder' | 'id'> &\n Pick<ComboboxInputGroupProps, 'variant' | 'focusVariant' | 'sizing' | 'state' | 'className'>;\n\ntype PublicComboboxProps<Value> = Pick<\n ComboboxProps<Value>,\n | 'disabled'\n | 'inputRef'\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'itemToStringLabel'\n | 'itemToStringValue'\n | 'filter'\n | 'onOpenChangeComplete'\n | 'isItemEqualToValue'\n>;\n\ntype CreatableProps<Value> = {\n allowCreate?: boolean;\n queryToCreateLabel?: (query: string) => ReactNode;\n queryToCreateValue?: (query: string) => Value;\n /**\n * Gate on the typed query for `allowCreate`.\n *\n * - Returning `false` hides the create row, so the empty state shows instead.\n * - Only called for a non-empty query that matches no existing item.\n * - Reach for it when a free-form value has a format (an email address, a URL, an identifier).\n */\n canCreate?: (query: string) => boolean;\n};\n\ntype Props<Value, GroupShape extends Group<Value> = Group<Value>> = PublicComboboxInputProps &\n PublicComboboxProps<Value> &\n CreatableProps<Value> & {\n items?: readonly (Value | GroupShape)[];\n\n // root specific\n allowClear?: boolean;\n empty?: ReactNode;\n indicator?: Indicator;\n prefix?: ReactNode;\n /**\n * Window the list with a virtualizer so large option sets stay fast. Opt-in — defaults to\n * `false` to keep behavior unchanged for existing call sites (every option stays in the DOM).\n * Pass `'auto'` to virtualize only ungrouped lists longer than {@link VIRTUALIZE_THRESHOLD},\n * or `true` to force it. Grouped lists are never virtualized.\n */\n virtualized?: boolean | 'auto';\n\n // item specific\n /** `query` is the current search text — pass it to `MarkedText` to highlight the match. */\n itemToLabel?: (item: Value, query: string) => ReactNode;\n itemToIcon?: (item: Value) => ReactNode;\n itemToDisabled?: (item: Value) => boolean;\n\n // group specific\n groupToLabel?: (group: GroupShape) => ReactNode;\n };\n\nexport const Combobox = <Value, GroupShape extends Group<Value> = Group<Value>>({\n // root props\n items: _itemsProp,\n value,\n defaultValue,\n onValueChange,\n itemToStringLabel: itemToStringLabelProp,\n itemToStringValue,\n disabled,\n filter,\n inputRef,\n onOpenChangeComplete,\n isItemEqualToValue: isItemEqualToValueProp,\n\n // input props\n variant,\n sizing,\n focusVariant,\n state,\n placeholder,\n allowClear,\n id,\n className,\n\n // own props\n empty = 'No items',\n indicator,\n prefix,\n virtualized = false,\n\n // creatable\n allowCreate,\n queryToCreateValue,\n queryToCreateLabel = defaultQueryToCreateLabel,\n canCreate,\n\n // own item props\n itemToDisabled = defaultItemToDisabled,\n itemToLabel = defaultItemToLabel,\n itemToIcon = defaultItemToIcon,\n groupToLabel = defaultGroupToLabel,\n}: Props<Value, GroupShape>) => {\n const closeReasonRef = useRef<'outside-click' | 'item-press' | 'creatable-item-press' | 'none'>(\n 'none',\n );\n const [inputValue, setInputValue] = useState(() => {\n const initial = value !== undefined ? value : defaultValue;\n if (initial == null) return '';\n return itemToStringLabelProp?.(initial) ?? toLabel(initial);\n });\n\n // Bumped on every selection so the sync effect below re-runs even when the owner leaves `value`\n // untouched.\n const [selections, setSelections] = useState(0);\n\n // Snap the input back to the controlled value's label.\n //\n // - Runs on a new `value` and after every selection, so a selection the owner does not adopt\n // cannot leave the input showing something the value does not say.\n // - `value` pinned to `null` is the \"adder\" shape: each pick is consumed by the owner and the\n // input clears, ready for the next one.\n // - Uncontrolled comboboxes (`value === undefined`) keep Base UI's own input handling.\n useEffect(() => {\n if (value === undefined) return;\n const label = value === null ? '' : (itemToStringLabelProp?.(value) ?? toLabel(value));\n setInputValue((prev) => (prev === label ? prev : label));\n }, [value, selections]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const selectedLabel =\n value == null ? undefined : (itemToStringLabelProp?.(value) ?? toLabel(value));\n // While the input still shows the current selection's label (nothing typed since the popup\n // opened), treat it as an empty query so the whole list stays browsable. Otherwise the combobox\n // filters down to just the selected item and you can't switch to a different, unrelated one\n // without clearing first.\n const isShowingSelection = selectedLabel !== undefined && inputValue === selectedLabel;\n const query = (isShowingSelection ? '' : inputValue).trim();\n const queryLower = query.toLowerCase();\n\n const itemsProp = _itemsProp ?? [];\n const sampleItem = itemsProp.flatMap((item) => (isGroupItem(item) ? item.items : [item]))[0];\n\n const [createdItems, setCreatedItems] = useState<Value[]>([]);\n\n const allItems = (() => {\n if (createdItems.length === 0) return itemsProp as (Value | GroupShape)[];\n if (isGroupItems(itemsProp))\n return [...itemsProp, { items: createdItems } as unknown as GroupShape];\n return [...itemsProp, ...createdItems];\n })();\n\n const items = (() => {\n if (!allowCreate || disabled) return allItems;\n if (!query) return allItems;\n const exactMatch = allItems\n .flatMap((item) => (isGroupItem(item) ? item.items : [item]))\n .some(\n (item) => (itemToStringLabelProp?.(item) ?? toLabel(item)).toLowerCase() === queryLower,\n );\n if (exactMatch) return allItems;\n if (canCreate && !canCreate(query)) return allItems;\n\n const creatable = isGroupItems(itemsProp)\n ? [{ items: [createCreatableItem(query)] }]\n : [createCreatableItem(query)];\n\n return [...allItems, ...creatable];\n })();\n\n const itemToStringLabel: ComboboxProps<Value>['itemToStringLabel'] = (value) => {\n if (isCreatableItem(value)) return value.value;\n return itemToStringLabelProp?.(value) ?? toLabel(value);\n };\n\n const wrappedFilter: ComboboxProps<Value>['filter'] = isShowingSelection\n ? () => true\n : !allowCreate || !filter\n ? filter\n : (item, ...args) => isCreatableItem(item) || filter(item, ...args);\n\n const wrappedItemToStringValue: ComboboxProps<Value>['itemToStringValue'] =\n !allowCreate || !itemToStringValue\n ? itemToStringValue\n : (item) => (isCreatableItem(item) ? item.value : itemToStringValue(item));\n\n const isItemEqualToValue: ComboboxProps<Value>['isItemEqualToValue'] = (a, b) => {\n if (isCreatableItem(a) || isCreatableItem(b)) return toValueKey(a) === toValueKey(b);\n return isItemEqualToValueProp?.(a, b) ?? Object.is(a, b);\n };\n\n const handleInputValueChange: NonNullable<ComboboxProps<Value>['onInputValueChange']> = (\n value,\n { reason },\n ) => {\n if (\n ['input-clear', 'none'].includes(reason) &&\n ['item-press', 'creatable-item-press'].includes(closeReasonRef.current)\n ) {\n closeReasonRef.current = 'none';\n return;\n }\n\n if (reason === 'none' && closeReasonRef.current == 'outside-click') {\n closeReasonRef.current = 'none';\n setInputValue(value);\n return;\n }\n\n setInputValue(value);\n };\n\n const handleOnOpenChangeComplete: NonNullable<ComboboxProps<Value>['onOpenChangeComplete']> = (\n open,\n ) => {\n onOpenChangeComplete?.(open);\n if (open) return;\n if (closeReasonRef.current !== 'none') return;\n closeReasonRef.current = 'outside-click';\n };\n\n const handleOnValueChange: ComboboxProps<Value>['onValueChange'] = (next, event) => {\n setSelections((count) => count + 1);\n\n if (isCreatableItem(next)) {\n const newValue = defaultToCreateValue(next.value, sampleItem, queryToCreateValue) as Value;\n closeReasonRef.current = 'creatable-item-press';\n setCreatedItems((prev) => [...prev, newValue]);\n onValueChange?.(newValue, event);\n return;\n }\n\n closeReasonRef.current = 'item-press';\n onValueChange?.(next, event);\n };\n\n // State-backed (not a ref) so a re-render fires when the popup mounts/remounts — Base UI unmounts\n // the list on close, and the virtualizer must re-observe the fresh element on each reopen or it\n // measures a stale/detached node and paints nothing.\n const [listElement, setListElement] = useState<HTMLDivElement | null>(null);\n // Base the decision on `allItems` (the real options) rather than `items`, which also holds the\n // transient creatable row — otherwise virtualization could toggle on/off as the user types.\n const isGrouped = isGroupItems(allItems);\n const shouldVirtualize =\n !isGrouped &&\n (virtualized === true || (virtualized === 'auto' && allItems.length > VIRTUALIZE_THRESHOLD));\n\n // In virtualized mode we pre-filter here and disable Base UI's filter with `null` (see the Root\n // `filter` prop — `undefined` would keep Base UI's default `contains`, which re-filters our items\n // with a different predicate and wrongly drives the empty state + keyboard nav). The creatable\n // row is always kept.\n const matchesQuery = (item: Value) => {\n if (isCreatableItem(item)) return true;\n if (!query) return true;\n if (filter) return !!filter(item, query, (value) => itemToStringLabel(value) ?? toLabel(value));\n return (itemToStringLabel(item) ?? toLabel(item)).toLowerCase().includes(queryLower);\n };\n\n const virtualItems = shouldVirtualize ? (items as Value[]).filter(matchesQuery) : [];\n\n const virtualizer = useVirtualizer({\n count: virtualItems.length,\n getScrollElement: () => listElement,\n estimateSize: () => ESTIMATED_ROW_HEIGHT,\n overscan: 12,\n enabled: shouldVirtualize,\n // Seed a viewport height so rows paint on the first frame. Without it the list measures 0 until\n // the ResizeObserver fires (a frame later), which renders an empty popup on open.\n initialRect: { width: 0, height: ESTIMATED_LIST_HEIGHT },\n });\n\n const renderItem = (item: Value, index?: number) => {\n if (isCreatableItem(item)) {\n return (\n <Combobox.Item index={index} value={item} icon={<Plus />}>\n {queryToCreateLabel(item.value)}\n </Combobox.Item>\n );\n }\n\n return (\n <Combobox.Item\n index={index}\n value={item}\n indicator={indicator}\n icon={itemToIcon(item)}\n disabled={itemToDisabled(item)}\n >\n {itemToLabel(item, query)}\n </Combobox.Item>\n );\n };\n\n const rowStyle = (offset: number): CSSProperties => ({\n position: 'absolute',\n top: 0,\n left: 0,\n width: '100%',\n transform: `translateY(${offset}px)`,\n });\n\n return (\n <BaseCombobox.Root<Value, false>\n items={shouldVirtualize ? virtualItems : items}\n // Base UI highlights nothing until ArrowDown, so Enter after typing would drop the query\n // silently — no selection, and the popup closes. Highlighting the first match makes Enter\n // commit it, including the creatable row when `allowCreate` is on.\n autoHighlight\n value={value}\n defaultValue={defaultValue}\n filter={shouldVirtualize ? null : wrappedFilter}\n onValueChange={handleOnValueChange}\n itemToStringLabel={itemToStringLabel}\n isItemEqualToValue={isItemEqualToValue}\n itemToStringValue={wrappedItemToStringValue}\n onOpenChangeComplete={handleOnOpenChangeComplete}\n disabled={disabled}\n inputRef={inputRef}\n inputValue={inputValue}\n onInputValueChange={handleInputValueChange}\n virtualized={shouldVirtualize}\n onItemHighlighted={(_, details) => {\n if (shouldVirtualize && details.reason === 'keyboard') {\n virtualizer.scrollToIndex(details.index);\n }\n }}\n >\n <ComboboxInputGroup\n variant={variant}\n sizing={sizing}\n state={state}\n focusVariant={focusVariant}\n className={className}\n >\n {prefix && <InputGroup.Addon align=\"inline-start\">{prefix}</InputGroup.Addon>}\n <ComboboxInput id={id} placeholder={placeholder} disabled={disabled} />\n <InputGroup.Addon align=\"inline-end\">\n {allowClear && (\n <InputGroup.Button asChild aria-label=\"Clear\" disabled={disabled}>\n <BaseCombobox.Clear>\n <X className=\"tw:size-4\" />\n </BaseCombobox.Clear>\n </InputGroup.Button>\n )}\n <InputGroup.Button disabled={disabled} asChild aria-label=\"Open combobox\">\n <BaseCombobox.Trigger>\n <ChevronDown className=\"tw:size-4\" />\n </BaseCombobox.Trigger>\n </InputGroup.Button>\n </InputGroup.Addon>\n </ComboboxInputGroup>\n <ComboboxContent>\n <ComboboxEmpty>{empty}</ComboboxEmpty>\n {shouldVirtualize ? (\n <ComboboxList ref={setListElement}>\n <div\n style={{\n position: 'relative',\n width: '100%',\n height: `${virtualizer.getTotalSize()}px`,\n }}\n >\n {virtualizer.getVirtualItems().map((row) => {\n const item = virtualItems[row.index];\n if (item === undefined) return null;\n return (\n <div\n key={row.key}\n data-index={row.index}\n ref={virtualizer.measureElement}\n style={rowStyle(row.start)}\n >\n {renderItem(item, row.index)}\n </div>\n );\n })}\n </div>\n </ComboboxList>\n ) : (\n <ComboboxList>\n {(itemOrGroup: Value | GroupShape) => {\n if (isCreatableItem(itemOrGroup))\n return (\n <Combobox.Item value={itemOrGroup} icon={<Plus />}>\n {queryToCreateLabel(itemOrGroup.value)}\n </Combobox.Item>\n );\n\n if (isGroupItem(itemOrGroup)) {\n const maybeCreatable = itemOrGroup.items[0];\n\n if (isCreatableItem(maybeCreatable)) {\n return (\n <Combobox.Item value={maybeCreatable} icon={<Plus />}>\n {queryToCreateLabel(maybeCreatable.value)}\n </Combobox.Item>\n );\n }\n\n const groupLabel = groupToLabel(itemOrGroup);\n\n return (\n <Combobox.Group items={itemOrGroup.items}>\n {groupLabel && <Combobox.GroupLabel>{groupLabel}</Combobox.GroupLabel>}\n {/* Don't forward `renderItem` by reference — the collection passes its\n group-local index, which ComboboxItem uses verbatim and breaks keyboard\n nav. Drop it so the item falls back to its own global list index. */}\n <Combobox.GroupList>{(item: Value) => renderItem(item)}</Combobox.GroupList>\n </Combobox.Group>\n );\n }\n\n return renderItem(itemOrGroup);\n }}\n </ComboboxList>\n )}\n </ComboboxContent>\n </BaseCombobox.Root>\n );\n};\n\n// Base\nCombobox.Root = ComboboxRoot;\nCombobox.InputGroup = ComboboxInputGroup;\nCombobox.Input = ComboboxInput;\nCombobox.Content = ComboboxContent;\nCombobox.List = ComboboxList;\nCombobox.Item = ComboboxItem;\nCombobox.Empty = ComboboxEmpty;\nCombobox.Value = BaseCombobox.Value;\nCombobox.Separator = ComboboxSeparator;\n\n// Group\nCombobox.Group = ComboboxGroup;\nCombobox.GroupLabel = ComboboxGroupLabel;\nCombobox.GroupList = ComboboxCollection;\n\n// Chips\nCombobox.Chips = ComboboxChips;\n"],"mappings":"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d;GACS;GACD;GACM;GACC;GACL;GACR,WAAU;GAEV,UAAA,oBAACA,SAAa,OAAd;IACO;IACL,cAAY,CAAC,CAAC;IACd,gBAAc;IACd,WAAW,GACT,2BACA,6BACA,eACA,0CAGA,sCACA,8BACA,qCACA,uCACA,oDAGA,iBACA,qCAEA,iBACA,8BACA,gBACA,aACA,yBACA,mBAGA,wBACA,uBACA,wBAGA,2BACA,0BACA,2BAGA,6CACA,6CACA,6CACA,6CACA,qDACA,kDACA,SACF;IACA,GAAI;IAEH;GACiB,CAAA;EACG,CAAA;CACN,CAAA;AAEzB;;;ACtFA,MAAa,iBAAiB,EAAE,KAAK,WAAW,GAAG,YACjD,oBAACC,SAAa,OAAd;CACO;CACL,WAAW,GACT,aACA,+CACA,qBACA,mBACA,kBACA,WACA,4BACA,WACA,SACF;CACA,GAAI;AACL,CAAA;;;ACjBH,MAAa,iBAAiB,EAAE,KAAK,GAAG,YACtC,oBAACC,SAAa,OAAd;CAAoB,GAAI;CAAY;CAAK,QAAQ,oBAAC,WAAW,OAAZ,CAAmB,CAAA;AAAI,CAAA;;;ACO1E,MAAa,sBAAsB,EACjC,KACA,OACA,SACA,QACA,cACA,WACA,GAAG,YAEH,oBAACC,SAAa,YAAd;CACE,GAAI;CACC;CACL,QACE,oBAAC,YAAD;EACS;EACE;EACK;EACN;EACG;CACZ,CAAA;AAEJ,CAAA;;;ACvBH,MAAa,yBAAyB,EAAE,KAAK,WAAW,UAAU,SAAS,GAAG,YAAmB;CAC/F,IAAI,YAAY,YACd,OACE,oBAACC,SAAa,eAAd;EACO;EACL,aAAA;EACA,WAAW,GACT,oCAEA,kBACA,mBACA,qBACA,aACA,eAEA,cACA,aACA,mBACA,oBAEA,iCACA,qCACA,SACF;EACA,GAAI;EAEJ,UAAA,oBAAC,OAAD,EACE,WAAW,GACT,aACA,aACA,mBACA,+BACA,wDACF,EACD,CAAA;CACyB,CAAA;CAIhC,OACE,oBAACA,SAAa,eAAd;EACE,GAAI;EACC;EACL,WAAW,GACT,0BACA,eACA,cAEA,4DAGA,aACA,oEACA,2GACA,SACF;EACA,QAAQ,oBAAC,OAA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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"DiagramSkeleton-lwBS2YBa.js","names":[],"sources":["../src/blocks/MermaidDiagram/DiagramSkeleton.tsx"],"sourcesContent":["import { Skeleton } from '../../components/Skeleton/Skeleton';\n\n// Lives apart from MermaidDiagram so callers can show it while that component's\n// chunk is still loading, without importing beautiful-mermaid to do it.\nexport const DiagramSkeleton = () => (\n <div className=\"tw:my-3 tw:overflow-hidden tw:rounded-md tw:border tw:border-border tw:bg-muted tw:p-6\">\n <Skeleton className=\"tw:h-40\" />\n </div>\n);\n"],"mappings":";;;AAIA,MAAa,wBACX,oBAAC,OAAD;CAAK,WAAU;CACb,UAAA,oBAAC,UAAD,EAAU,WAAU,UAAW,CAAA;AAC5B,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"MermaidDiagram-ChL3WIQT.js","names":[],"sources":["../src/blocks/MermaidDiagram/mermaidTheme.ts","../src/blocks/MermaidDiagram/svgTransforms.ts","../src/blocks/MermaidDiagram/MermaidDiagram.tsx"],"sourcesContent":["import type { RenderOptions } from 'beautiful-mermaid';\nimport type { MermaidConfig } from 'mermaid';\n\nimport type { ResolvedColorScheme } from '../../components/ThemeProvider/types';\nimport { createTokenResolver } from '../../utils/themeTokens';\n\nconst DIAGRAM_FONT = 'Inter, system-ui, sans-serif';\n\n/**\n * Fallback channels for the tokens the diagram palette reads, mirroring the\n * `:root` / `[data-theme='dark']` blocks of `styles.css`.\n *\n * `resolveToken` only reaches these when the live custom property is missing —\n * SSR, or a unit test that loads no CSS. In the browser the computed value wins,\n * which is what makes a customer brand re-skin the diagram for free.\n */\nconst FALLBACK_CHANNELS = {\n card: { light: '255 255 255', dark: '34 34 40' },\n 'card-foreground': { light: '30 41 59', dark: '229 230 236' },\n foreground: { light: '30 41 59', dark: '229 230 236' },\n muted: { light: '241 245 249', dark: '38 38 45' },\n 'muted-foreground': { light: '100 116 139', dark: '141 144 153' },\n border: { light: '229 231 235', dark: '52 53 62' },\n primary: { light: '37 99 235', dark: '31 143 255' },\n accent: { light: '224 242 254', dark: '30 58 95' },\n 'accent-foreground': { light: '13 65 127', dark: '147 197 253' },\n warning: { light: '138 82 16', dark: '255 190 92' },\n success: { light: '24 122 76', dark: '62 207 127' },\n destructive: { light: '220 38 38', dark: '229 72 77' },\n} as const;\n\ntype TokenName = keyof typeof FALLBACK_CHANNELS;\n\n/**\n * Binds a token lookup to one `getComputedStyle` snapshot for the whole palette.\n * Built per call, never hoisted: the values move with the scheme and the brand.\n */\nconst tokenReader = (scheme: ResolvedColorScheme) => {\n const resolve = createTokenResolver();\n return (name: TokenName, alpha?: number): string =>\n resolve(name, FALLBACK_CHANNELS[name][scheme], alpha);\n};\n\n/**\n * Palette for `beautiful-mermaid`'s synchronous renderer. It sets these as CSS\n * variables on the `<svg>` and derives everything else it needs from `bg` + `fg`\n * with `color-mix()` — which is why leaving them at the library defaults painted\n * a near-white node fill (#f8f8f8, mixed from a white `bg`) on a dark page.\n *\n * `transparent` keeps the page background showing through, so `bg` only feeds\n * those derivations; the node fill is pinned explicitly via `surface`.\n */\nexport const fastRenderOptions = (scheme: ResolvedColorScheme): RenderOptions => {\n const token = tokenReader(scheme);\n\n return {\n bg: token('card'),\n fg: token('foreground'),\n line: token('border'),\n accent: token('primary'),\n muted: token('muted-foreground'),\n surface: token('muted'),\n border: token('border'),\n transparent: true,\n font: DIAGRAM_FONT,\n };\n};\n\n/**\n * Config for the async `mermaid` renderer (the fallback for dialects the fast\n * renderer can't parse, and for icon-pack diagrams).\n *\n * Built on the `base` theme so every colour comes from `themeVariables` rather\n * than mermaid's own light/dark palettes. Node chrome maps to the `accent` pair\n * (a tinted surface with a legible foreground in both schemes), containers to\n * `card`, and the gantt/note states to the status tokens — consumed as a low\n * alpha tint plus a solid mark, per the brand-neutrality contract, since the\n * status tokens themselves are text-legible colours rather than fills.\n */\nexport const mermaidConfig = (scheme: ResolvedColorScheme): MermaidConfig => {\n const token = tokenReader(scheme);\n\n const surface = token('accent');\n const onSurface = token('accent-foreground');\n const container = token('card');\n const onContainer = token('card-foreground');\n const line = token('border');\n const stroke = token('primary');\n const text = token('foreground');\n\n return {\n startOnLoad: false,\n securityLevel: 'strict',\n theme: 'base',\n themeVariables: {\n darkMode: scheme === 'dark',\n background: container,\n primaryColor: surface,\n primaryTextColor: onSurface,\n primaryBorderColor: stroke,\n secondaryColor: container,\n secondaryTextColor: onContainer,\n secondaryBorderColor: line,\n tertiaryColor: token('warning', 0.15),\n tertiaryTextColor: token('warning'),\n tertiaryBorderColor: token('warning'),\n lineColor: line,\n textColor: text,\n mainBkg: surface,\n nodeBorder: stroke,\n clusterBkg: container,\n clusterBorder: line,\n titleColor: text,\n edgeLabelBackground: container,\n nodeTextColor: onSurface,\n actorBorder: stroke,\n actorBkg: surface,\n actorTextColor: onSurface,\n actorLineColor: line,\n signalColor: text,\n signalTextColor: text,\n labelBoxBkgColor: surface,\n labelBoxBorderColor: stroke,\n labelTextColor: onSurface,\n loopTextColor: text,\n noteBorderColor: token('warning'),\n noteBkgColor: token('warning', 0.15),\n noteTextColor: text,\n sectionBkgColor: surface,\n altSectionBkgColor: container,\n sectionBkgColor2: token('muted'),\n taskBorderColor: stroke,\n taskBkgColor: surface,\n taskTextColor: onSurface,\n taskTextDarkColor: text,\n taskTextLightColor: text,\n activeTaskBorderColor: stroke,\n activeTaskBkgColor: token('primary', 0.25),\n doneTaskBorderColor: token('success'),\n doneTaskBkgColor: token('success', 0.15),\n critBorderColor: token('destructive'),\n critBkgColor: token('destructive', 0.15),\n fontFamily: DIAGRAM_FONT,\n fontSize: '14px',\n },\n };\n};\n","// Pure post-processing of mermaid's SVG output, before it reaches ZoomableSvg's\n// DOMPurify pass. Extracted for unit testing.\n\nconst HTML_TAG = /<[^>]+>/g;\nconst FOREIGN_OBJECT = /(<foreignObject\\b[^>]*>)([\\s\\S]*?)(<\\/foreignObject>)/g;\n// The root <svg> open tag, anchored to the start of the string.\nconst ROOT_SVG_TAG = /^(\\s*<svg\\b)([^>]*)(>)/i;\n\n/**\n * Mermaid renders node labels — including icon-shape (`@{ icon: … }`) labels — as\n * HTML (`<div><span><p>…</p></span></div>`) inside an SVG `<foreignObject>`. The\n * ZoomableSvg DOMPurify pass runs the SVG namespace profile, which strips every\n * XHTML-namespaced element under an `<svg>` root, so those wrapped labels vanish\n * (icon rendered, text gone). DOMPurify keeps *bare text* directly inside a\n * `<foreignObject>`, so collapse each label's HTML to its text content. Mermaid\n * has already sanitized that text under `securityLevel: 'strict'`, and dropping\n * the wrapper tags is strictly safer than keeping them.\n *\n * Entities are left encoded (`&amp;`, `&lt;`, …): as text-node content inside the\n * `<foreignObject>` the browser renders them correctly, and decoding them here\n * would risk turning `&lt;`/`&gt;` back into real angle brackets that could form\n * markup in the sanitized SVG.\n */\nexport const flattenForeignObjectLabels = (svg: string): string =>\n svg.replace(FOREIGN_OBJECT, (_match, open: string, inner: string, close: string) => {\n const text = inner.replace(HTML_TAG, ' ').replace(/\\s+/g, ' ').trim();\n return `${open}${text}${close}`;\n });\n\n/**\n * Make the diagram fluid: strip the root `<svg>`'s fixed width/height/style and\n * set `width=\"100%\"` plus a `max-width` from the viewBox width so it never\n * overflows its container.\n *\n * Only the ROOT `<svg>` tag is rewritten (anchored to string start). Icon-shape\n * nodes embed their own inner `<svg>` icons with fixed width/height; an earlier\n * unanchored regex matched the first `<svg …height…>` anywhere, so when the root\n * tag carried no height (mermaid emits `width=\"100%\"` alone) it stripped the\n * FIRST icon's height instead — detaching and mis-sizing that icon.\n *\n * The existing `style` attribute is preserved (only an existing `max-width` is\n * replaced): beautiful-mermaid carries theme CSS vars (`--bg`, `--fg`) there that\n * its inner `<style>` block derives node/text colors from — dropping the whole\n * attribute made every derived color resolve to black.\n */\nconst STYLE_ATTR = /\\s+style=\"([^\"]*)\"/i;\n\nexport const makeResponsive = (svgString: string): string => {\n const viewBoxMatch = svgString.match(/viewBox=\"[^\"]*\\s([\\d.]+)\\s[\\d.]+\"/);\n const vbWidth = viewBoxMatch ? Math.round(Number(viewBoxMatch[1])) : undefined;\n\n return svgString.replace(ROOT_SVG_TAG, (_match, open: string, attrs: string, close: string) => {\n const existingStyle = attrs.match(STYLE_ATTR)?.[1] ?? '';\n const styleDecls = existingStyle\n .replace(/max-width:\\s*[^;\"]*;?\\s*/gi, '')\n .replace(/\\s+/g, ' ')\n .trim()\n .replace(/;$/, '');\n\n let nextAttrs = attrs\n .replace(/\\s+width=\"[^\"]*\"/i, '')\n .replace(/\\s+height=\"[^\"]*\"/i, '')\n .replace(STYLE_ATTR, '');\n\n nextAttrs += ' width=\"100%\"';\n\n const styleParts = [styleDecls, vbWidth ? `max-width: ${vbWidth}px` : '']\n .filter(Boolean)\n .join('; ');\n if (styleParts) nextAttrs += ` style=\"${styleParts}\"`;\n\n return `${open}${nextAttrs}${close}`;\n });\n};\n\n/**\n * Whether an SVG has drawn content, i.e. a non-degenerate viewBox.\n *\n * - beautiful-mermaid does not throw on every syntax it cannot lay out: an\n * `erDiagram` entity whose quoted name contains a space (`\"sample (Copy)\"`)\n * returns a well-formed SVG with `viewBox=\"0 0 0 0\"` and an empty `<defs>`.\n * - Such output is truthy, so it would be cached and rendered as an empty box,\n * and the async mermaid renderer — which parses the same code fine — would\n * never run.\n * - A missing viewBox counts as drawn: mermaid's own output is sized via\n * width/height attributes on some diagram types.\n * - Only the ROOT `<svg>` is inspected. Icon-shape nodes embed their own inner\n * `<svg>` / `<symbol>`, so an unanchored search reads a nested viewBox when the\n * root carries none — discarding a diagram that had in fact been drawn. Same\n * trap `makeResponsive` documents above.\n * - Either quote style is accepted, and whitespace around the `=`. Both current\n * renderers emit `viewBox=\"…\"` exactly, so this is future-proofing rather than a\n * live case: a miss reads as \"no viewBox\", i.e. drawn, silently restoring the\n * empty-diagram bug.\n */\nconst ROOT_VIEWBOX =\n /^\\s*<svg\\b[^>]*\\sviewBox\\s*=\\s*([\"'])\\s*[\\d.eE+-]+\\s+[\\d.eE+-]+\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)\\s*\\1/i;\n\nexport const hasDrawnContent = (svg: string): boolean => {\n const viewBox = svg.match(ROOT_VIEWBOX);\n if (!viewBox) return true;\n return Number(viewBox[2]) > 0 && Number(viewBox[3]) > 0;\n};\n","import { useEffect, useId, useRef, useState } from 'react';\nimport type { ReactNode } from 'react';\nimport { renderMermaidSVG } from 'beautiful-mermaid';\nimport type mermaid from 'mermaid';\n\nimport type { ResolvedColorScheme } from '../../components/ThemeProvider/types';\nimport { useThemeAttributes } from '../../components/ThemeProvider/useThemeAttributes';\nimport { ZoomableSvg } from '../../components/ZoomableSvg';\nimport { cn } from '../../utils';\n\nimport { DiagramSkeleton } from './DiagramSkeleton';\nimport { fastRenderOptions, mermaidConfig } from './mermaidTheme';\nimport { flattenForeignObjectLabels, hasDrawnContent, makeResponsive } from './svgTransforms';\n\ntype MermaidModule = { default: typeof mermaid };\n\nlet mermaidPromise: Promise<MermaidModule> | null = null;\n\n// Iconify icon pack registered with mermaid so `@{ icon: \"lucide:name\" }` node\n// shapes and `architecture-beta service <id>(lucide:name)` render — keeping\n// diagram glyphs consistent with the Lucide icons used across the rest of the UI.\n// The pack JSON resolves from a workspace dependency (no CDN fetch) via a dynamic\n// import, so it lands in its own lazy chunk and icons render offline / under a\n// strict CSP without weighing down the initial bundle.\nconst registerLucideIconPack = (m: typeof mermaid): void => {\n m.registerIconPacks([\n {\n name: 'lucide',\n loader: () => import('@iconify-json/lucide/icons.json').then((mod) => mod.default),\n },\n ]);\n};\n\nconst getMermaid = (): Promise<MermaidModule> => {\n if (!mermaidPromise) {\n mermaidPromise = import('mermaid')\n .then((m) => {\n registerLucideIconPack(m.default);\n return m;\n })\n .catch((err) => {\n mermaidPromise = null;\n throw err;\n });\n }\n return mermaidPromise;\n};\n\nconst stripFontImports = (svg: string): string =>\n svg.replace(/@import\\s+url\\([^)]*fonts\\.googleapis\\.com[^)]*\\);?\\s*/g, '');\n\n// beautiful-mermaid's synchronous renderer has no icon-pack support, so a diagram\n// using icon syntax must skip the fast path and take the async mermaid render\n// (which registers the pack). Matches:\n// - the flowchart / treeView icon shape `@{ icon: \"pack:name\" }`\n// - `architecture-beta` / `treeView` refs `icon|service|group <id>(pack:name)`\n// (the id between keyword and `(` is optional)\n// - legacy FontAwesome refs `fa:fa-*` / `fab:` embedded in node text\nconst hasIconSyntax = (code: string): boolean =>\n /@\\{[^}]*\\bicon\\s*:/.test(code) ||\n /\\b(?:icon|service|group)\\b[^\\n(]*\\(\\s*[\\w-]+:/.test(code) ||\n /\\bfa[bslr]?:fa-/.test(code);\n\nconst tryFastRender = (code: string, scheme: ResolvedColorScheme): string | null => {\n if (hasIconSyntax(code)) return null;\n try {\n const svg = stripFontImports(renderMermaidSVG(code, fastRenderOptions(scheme)));\n // A zero-sized result is a silent layout failure, not a diagram — take the\n // async fallback rather than caching an empty box. See `hasDrawnContent`.\n return hasDrawnContent(svg) ? svg : null;\n } catch (err) {\n // beautiful-mermaid can't parse every mermaid dialect; the async mermaid\n // renderer is the fallback. Log at debug so regressions are diagnosable\n // without noising up the console on the expected unsupported-syntax path.\n console.debug('[MermaidDiagram] fast render unavailable, using async fallback:', err);\n return null;\n }\n};\n\n/**\n * Whether a mermaid parse error means \"ran out of input\" rather than \"bad syntax\".\n *\n * - Mermaid's jison parsers report the end of input as token `1`, so a source\n * truncated mid-diagram — every intermediate frame of a streaming answer —\n * fails with `hash.token === 1`.\n * - Genuinely invalid syntax fails on a real token (`'ONLY_ONE'`, …) instead.\n * - Only a lower bound: some truncations do land on a real token and read as\n * invalid. Those fall through to the `<pre>` fallback for one frame and clear\n * when the next chunk arrives, which is the pre-existing behaviour.\n */\nconst isTruncatedDiagram = (err: unknown): boolean =>\n typeof err === 'object' && err !== null && 'hash' in err\n ? (err as { hash?: { token?: unknown } }).hash?.token === 1\n : false;\n\nconst RENDER_DEBOUNCE_MS = 300;\n\n// How long a truncated diagram is held as \"still arriving\" before it is shown as\n// source. Comfortably longer than the gap between streamed chunks, short enough\n// that an abandoned stream resolves while the reader is still looking at it.\nconst TRUNCATION_GRACE_MS = 2_000;\n\n// Module-level SVG cache — persists across component remounts (e.g. tab switches\n// that cause React to remount the tree). The colours are baked into the markup,\n// so the key is the code *plus* the theme key (scheme + brand): the same diagram\n// is a different SVG under a different colour scheme or brand.\nconst svgCache = new Map<string, string>();\n\nconst diagramCacheKey = (code: string, themeKey: string): string => `${themeKey}\\n${code}`;\n\n// Resolve an SVG synchronously: cache hit first, otherwise a fast synchronous\n// render. Caches the result and returns it, or null when neither is available\n// (the caller then falls back to the async mermaid render).\nconst resolveSyncSvg = (\n code: string,\n cacheKey: string,\n scheme: ResolvedColorScheme,\n): string | null => {\n const cached = svgCache.get(cacheKey);\n if (cached) return cached;\n const fast = tryFastRender(code, scheme);\n if (fast) svgCache.set(cacheKey, fast);\n return fast;\n};\n\ntype Props = {\n /** Mermaid diagram source code. Supports flowchart, sequence, class, state, ER,\n * pie, gantt, and mindmap. Gantt `dateFormat HH:mm` (time-only) is not supported\n * by mermaid's dayjs parser — use `dateFormat YYYY-MM-DD HH:mm` with `axisFormat %H:%M` instead. */\n code: string;\n /** Extra toolbar controls (e.g. an `ExportMenu`), forwarded to `ZoomableSvg`.\n * Receives the sanitized SVG. Omit to keep the default toolbar. */\n renderActions?: (safeSvg: string) => ReactNode;\n};\n\nexport const MermaidDiagram = ({ code, renderActions }: Props) => {\n const id = useId();\n // Re-renders whenever the active colour scheme or brand changes, so the\n // diagram is re-rendered in the new palette instead of staying a light island\n // on a dark page. The scheme comes out of the same read as the key, so the\n // palette can never be resolved under one scheme and cached under the other —\n // see `useThemeAttributes` for why the theme context is a step ahead of the\n // CSS variables it stands for.\n const { scheme, cacheKey: themeKey } = useThemeAttributes();\n const cacheKey = diagramCacheKey(code, themeKey);\n\n const [svg, setSvg] = useState<string | null>(() => resolveSyncSvg(code, cacheKey, scheme));\n const [renderFailed, setRenderFailed] = useState(false);\n const [truncated, setTruncated] = useState(false);\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const renderIdRef = useRef(0);\n\n // Synchronously reset stale state when the code or the theme changes, to avoid\n // a one-frame flash of the previous diagram.\n const [prevKey, setPrevKey] = useState(cacheKey);\n if (cacheKey !== prevKey) {\n setPrevKey(cacheKey);\n setSvg(resolveSyncSvg(code, cacheKey, scheme));\n setRenderFailed(false);\n setTruncated(false);\n }\n\n useEffect(() => {\n // Synchronous results (cache hit / fast render) are already applied and\n // cached by the useState initializer (mount) and the render-phase reset\n // (code / theme change). Only the async fallback needs an effect.\n if (svgCache.has(cacheKey)) return;\n\n const currentRenderId = ++renderIdRef.current;\n\n if (debounceRef.current) {\n clearTimeout(debounceRef.current);\n }\n\n debounceRef.current = setTimeout(() => {\n getMermaid()\n .then(async (mermaidModule) => {\n if (renderIdRef.current !== currentRenderId) return;\n const rendererId = `mermaid-${id.replaceAll(':', '')}`;\n const container = document.createElement('div');\n container.style.visibility = 'hidden';\n container.style.position = 'absolute';\n container.style.top = '-9999px';\n container.style.width = '900px';\n document.body.appendChild(container);\n // Re-applied per render rather than once at import: `initialize` is the\n // only way to change mermaid's palette, and the palette follows the\n // active scheme/brand.\n mermaidModule.default.initialize(mermaidConfig(scheme));\n try {\n const result = await mermaidModule.default.render(rendererId, code, container);\n if (renderIdRef.current === currentRenderId && result) {\n const svgOutput = flattenForeignObjectLabels(result.svg);\n svgCache.set(cacheKey, svgOutput);\n setSvg(svgOutput);\n setRenderFailed(false);\n setTruncated(false);\n }\n } finally {\n container.remove();\n }\n })\n .catch((err: unknown) => {\n if (renderIdRef.current !== currentRenderId) return;\n setSvg(null);\n // A diagram arriving a chunk at a time is invalid at almost every\n // intermediate length, so a truncation is treated as \"not ready\" and\n // holds the skeleton instead of the raw-code `<pre>`. It is held for a\n // bounded wait, not indefinitely: a stream that dies mid-entity — or a\n // diagram a user simply left unterminated — never gets a next chunk, and\n // a skeleton that stays forever is worse than showing the source. The\n // timer is cleared by the effect teardown, so any further chunk cancels\n // it and re-renders.\n if (isTruncatedDiagram(err)) {\n console.debug('[MermaidDiagram] incomplete diagram, awaiting more input:', err);\n setTruncated(true);\n return;\n }\n console.error('[MermaidDiagram] fallback failed:', err);\n setRenderFailed(true);\n });\n }, RENDER_DEBOUNCE_MS);\n\n const timer = debounceRef.current;\n const renderId = renderIdRef;\n return () => {\n renderId.current++;\n if (timer) {\n clearTimeout(timer);\n }\n };\n }, [cacheKey, code, id, scheme]);\n\n // A truncated diagram is held as \"still arriving\" for a bounded wait, not\n // indefinitely: a stream that dies mid-entity — or a diagram a user left\n // unterminated — never sends another chunk, and a skeleton that stays forever\n // is worse than showing the source. Any further chunk changes `code`, which\n // resets `truncated` and tears this timer down.\n useEffect(() => {\n if (!truncated) return;\n const timer = setTimeout(() => setRenderFailed(true), TRUNCATION_GRACE_MS);\n return () => clearTimeout(timer);\n }, [truncated, cacheKey]);\n\n const processedSvg = svg ? makeResponsive(svg) : null;\n\n if (renderFailed) {\n return (\n <pre\n className={cn(\n 'tw:my-3 tw:overflow-auto tw:whitespace-pre-wrap tw:break-all',\n 'tw:py-3 tw:px-4',\n 'tw:bg-muted',\n 'tw:rounded-md tw:text-muted-foreground',\n 'tw:text-sm tw:font-mono',\n )}\n >\n <code>{code}</code>\n </pre>\n );\n }\n\n if (processedSvg) {\n return (\n <ZoomableSvg\n key={code}\n html={processedSvg}\n copyText={`\\`\\`\\`mermaid\\n${code}\\n\\`\\`\\``}\n className=\"tw:my-3\"\n allowForeignObject\n renderActions={renderActions}\n />\n );\n }\n\n return <DiagramSkeleton />;\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Select-Is0VkePH.js","names":["SelectItemComponent"],"sources":["../src/components/Select/SelectContent.tsx","../src/components/Select/SelectGroup.tsx","../src/components/Select/SelectItem.tsx","../src/components/Select/SelectLabel.tsx","../src/components/Select/SelectRoot.tsx","../src/components/Select/SelectSeparator.tsx","../src/components/Select/SelectTrigger.tsx","../src/components/Select/Select.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\n\nimport { ChevronDown, ChevronUp } from '../../icons';\nimport { cn } from '../../utils';\nimport { useArgoDesign } from '../ThemeProvider/context';\n\nconst scrollButtonStyles = cn(\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:rounded-sm',\n 'tw:p-1',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-5',\n);\n\ntype Variant = 'default' | 'argo';\n\n/**\n * Props for `Select.Content`. `container` portals the listbox into a custom element (useful inside modals).\n */\ntype Props = ComponentProps<typeof SelectPrimitive.Content> & {\n container?: HTMLElement | null;\n};\n\n/**\n * Listbox container for `Select`. Portals items into a popover sized to the trigger.\n * Normally rendered implicitly by `Select`; use directly only when composing custom item layouts via\n * the `Select.Root` / `Select.Trigger` / `Select.Content` compound parts.\n */\nexport const SelectContent = ({\n ref,\n className,\n children,\n container,\n position = 'popper',\n sideOffset = 4,\n ...props\n}: Props) => {\n const effectiveVariant: Variant = useArgoDesign() ? 'argo' : 'default';\n return (\n <SelectPrimitive.Portal container={container}>\n <SelectPrimitive.Content\n {...props}\n ref={ref}\n position={position}\n sideOffset={sideOffset}\n data-variant={effectiveVariant}\n className={cn(\n 'tailwindcss-preflight',\n 'tw:group/select-content',\n // Floating tier above Modal (1051): Tooltip 1060 / Combobox·Popover·Select 1055 / Modal 1051 / DropdownMenu.SubContent 1041 / FullScreenModal 1039\n 'tw:z-[1055]',\n\n // layout\n 'tw:flex tw:flex-col',\n 'tw:p-1',\n 'tw:data-[variant=default]:p-0',\n 'tw:overflow-hidden',\n 'tw:origin-(--radix-select-content-transform-origin)',\n\n // sizing\n 'tw:max-h-[var(--radix-select-content-available-height)]',\n 'tw:min-w-[var(--radix-select-trigger-width)]',\n\n // appearance\n 'tw:bg-popover',\n 'tw:text-popover-foreground',\n 'tw:shadow-md',\n 'tw:ring-1',\n 'tw:ring-foreground/10',\n 'tw:rounded-lg',\n 'tw:data-[variant=default]:rounded',\n\n // open animation\n 'tw:data-[state=open]:animate-in',\n 'tw:data-[state=open]:fade-in-0',\n 'tw:data-[state=open]:zoom-in-95',\n\n // closed animation\n 'tw:data-[state=closed]:animate-out',\n 'tw:data-[state=closed]:fade-out-0',\n 'tw:data-[state=closed]:zoom-out-95',\n\n // position animations\n 'tw:data-[side=bottom]:slide-in-from-top-2',\n 'tw:data-[side=left]:slide-in-from-right-2',\n 'tw:data-[side=right]:slide-in-from-left-2',\n 'tw:data-[side=top]:slide-in-from-bottom-2',\n className,\n )}\n >\n <SelectPrimitive.ScrollUpButton className={scrollButtonStyles}>\n <ChevronUp />\n </SelectPrimitive.ScrollUpButton>\n\n <SelectPrimitive.Viewport\n className={cn({\n 'tw:h-[var(--radix-select-trigger-height)] tw:w-full tw:min-w-[var(--radix-select-trigger-width)]':\n position === 'popper',\n })}\n >\n {children}\n </SelectPrimitive.Viewport>\n\n <SelectPrimitive.ScrollDownButton className={scrollButtonStyles}>\n <ChevronDown />\n </SelectPrimitive.ScrollDownButton>\n </SelectPrimitive.Content>\n </SelectPrimitive.Portal>\n );\n};\n","import type { ComponentProps } from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<typeof SelectPrimitive.Group>;\n\nexport const SelectGroup = ({ className, ...props }: Props) => (\n <SelectPrimitive.Group {...props} className={cn('tw:flex tw:flex-col tw:gap-0.5', className)} />\n);\n","import type { ComponentProps, ReactNode } from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\n\nimport { Check } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<typeof SelectPrimitive.Item> & {\n icon?: ReactNode;\n};\n\nexport const SelectItem = ({ ref, className, children, icon, ...props }: Props) => (\n <SelectPrimitive.Item\n {...props}\n ref={ref}\n className={cn(\n 'tw:group/select-item',\n\n // layout\n 'tw:relative',\n 'tw:flex',\n 'tw:flex-1',\n 'tw:items-center',\n 'tw:gap-2',\n\n // spacing — default variant uses tighter radius and wider horizontal padding\n 'tw:py-2',\n 'tw:px-2',\n 'tw:group-data-[variant=default]/select-content:px-4',\n 'tw:rounded-lg',\n 'tw:group-data-[variant=default]/select-content:rounded-none',\n\n // typography\n 'tw:text-sm',\n 'tw:select-none',\n 'tw:cursor-default',\n 'tw:outline-hidden',\n\n // highlighted (keyboard / hover)\n 'tw:focus:outline-hidden',\n 'tw:data-[highlighted]:bg-accent',\n 'tw:group-data-[variant=default]/select-content:data-[highlighted]:bg-neutral-100',\n 'tw:data-[highlighted]:text-accent-foreground',\n 'tw:group-data-[variant=default]/select-content:data-[highlighted]:text-foreground',\n\n // disabled\n 'tw:data-[disabled]:pointer-events-none',\n 'tw:data-[disabled]:opacity-50',\n\n // child svg defaults\n 'tw:[&_svg]:pointer-events-none',\n 'tw:[&_svg]:shrink-0',\n 'tw:[&_svg]:text-muted-foreground',\n \"tw:[&_svg:not([class*='tw:size-'])]:size-4\",\n className,\n )}\n >\n {icon}\n <span className=\"tw:flex-1 tw:truncate\">\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </span>\n <SelectPrimitive.ItemIndicator className=\"tw:pointer-events-none\">\n <Check className=\"tw:size-4\" />\n </SelectPrimitive.ItemIndicator>\n </SelectPrimitive.Item>\n);\n","import type { ComponentProps } from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<typeof SelectPrimitive.Label>;\n\nexport const SelectLabel = ({ className, ...props }: Props) => (\n <SelectPrimitive.Label\n {...props}\n className={cn(\n // Base (argo variant) — soft gray section label\n 'tw:px-2',\n 'tw:py-1.5',\n 'tw:text-xs',\n 'tw:font-medium',\n 'tw:leading-none',\n 'tw:text-muted-foreground',\n\n // Default variant — uppercase tracked label, matches Combobox default\n 'tw:group-data-[variant=default]/select-content:uppercase',\n 'tw:group-data-[variant=default]/select-content:font-semibold',\n 'tw:group-data-[variant=default]/select-content:tracking-wider',\n 'tw:group-data-[variant=default]/select-content:text-[11px]',\n 'tw:group-data-[variant=default]/select-content:text-black',\n 'tw:group-data-[variant=default]/select-content:pt-2',\n 'tw:group-data-[variant=default]/select-content:px-4',\n\n className,\n )}\n />\n);\n","import type { ReactNode } from 'react';\nimport { Root } from '@radix-ui/react-select';\n\n// Mirror Radix's `SelectProps` as an explicit list. We can't infer via\n// `ComponentProps<typeof Root>` or reuse Radix's `SelectProps` directly: both\n// transitively reference the un-exported `SelectSharedProps` interface, and\n// TS4023 fires when DTS emits anything that consumes it (e.g. `useAppForm`).\n// Keep this in sync with `@radix-ui/react-select`'s `SelectProps` shape.\nexport type SelectRootProps = {\n // SelectSharedProps\n children?: ReactNode;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?(open: boolean): void;\n dir?: 'ltr' | 'rtl';\n name?: string;\n autoComplete?: string;\n disabled?: boolean;\n required?: boolean;\n form?: string;\n // SelectProps\n value?: string;\n defaultValue?: string;\n onValueChange?(value: string): void;\n};\n\nexport const SelectRoot = (props: SelectRootProps) => <Root {...props} />;\n","import type { ComponentProps } from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<typeof SelectPrimitive.Separator>;\n\nexport const SelectSeparator = ({ className, ...props }: Props) => (\n <SelectPrimitive.Separator\n {...props}\n className={cn('tw:mx-2 tw:my-1 tw:h-px tw:bg-border', className)}\n />\n);\n","import type { ComponentProps } from 'react';\nimport * as SelectPrimitive from '@radix-ui/react-select';\nimport { type VariantProps } from 'class-variance-authority';\n\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\nimport { Button } from '../Button';\nimport { overlayTriggerVariants } from '../OverlayTrigger/styles';\nimport { useArgoDesign } from '../ThemeProvider/context';\n\ntype Props = ComponentProps<typeof SelectPrimitive.Trigger> &\n Omit<VariantProps<typeof overlayTriggerVariants>, 'variant'> & {\n variant?: Exclude<VariantProps<typeof overlayTriggerVariants>['variant'], 'argo'> | 'inline';\n } & Pick<ComponentProps<typeof SelectPrimitive.Value>, 'placeholder'>;\n\nexport const SelectTrigger = ({\n ref,\n className,\n variant,\n state,\n sizing,\n placeholder,\n ...props\n}: Props) => {\n const isArgoDesign = useArgoDesign();\n const effectiveVariant = (() => {\n if (variant === 'inline') return 'inline';\n if (isArgoDesign) return 'argo';\n return variant;\n })();\n const isInlineVariant = effectiveVariant === 'inline';\n\n if (isInlineVariant)\n return (\n <SelectPrimitive.Trigger {...props} ref={ref} className={cn(className)} asChild>\n <Button variant=\"inline\">\n <SelectPrimitive.Value placeholder={placeholder} />\n <SelectPrimitive.Icon asChild>\n <ChevronDown />\n </SelectPrimitive.Icon>\n </Button>\n </SelectPrimitive.Trigger>\n );\n\n return (\n <SelectPrimitive.Trigger\n {...props}\n ref={ref}\n className={cn(\n overlayTriggerVariants({ variant: effectiveVariant, state, sizing }),\n className,\n )}\n >\n <SelectPrimitive.Value placeholder={placeholder} />\n <SelectPrimitive.Icon asChild>\n <ChevronDown className=\"tw:size-4 tw:text-muted-foreground\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n};\n","import { useId } from 'react';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { SelectContent } from './SelectContent';\nimport { SelectGroup } from './SelectGroup';\nimport { SelectItem as SelectItemComponent } from './SelectItem';\nimport { SelectLabel } from './SelectLabel';\nimport { SelectRoot, type SelectRootProps } from './SelectRoot';\nimport { SelectSeparator } from './SelectSeparator';\nimport { SelectTrigger } from './SelectTrigger';\n\nexport type SelectItem = {\n value: string;\n label: ReactNode;\n icon?: ReactNode;\n disabled?: boolean;\n};\n\nexport type SelectItemGroup = {\n label?: ReactNode;\n items: readonly SelectItem[];\n};\n\nconst isGroup = (itemOrGroup: SelectItem | SelectItemGroup): itemOrGroup is SelectItemGroup =>\n 'items' in itemOrGroup;\n\ntype TriggerProps = ComponentProps<typeof SelectTrigger>;\n\ntype Props = Pick<\n SelectRootProps,\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'disabled'\n | 'name'\n | 'required'\n | 'open'\n | 'defaultOpen'\n | 'onOpenChange'\n | 'dir'\n | 'autoComplete'\n | 'form'\n> &\n Pick<\n TriggerProps,\n | 'variant'\n | 'state'\n | 'sizing'\n | 'placeholder'\n | 'id'\n | 'className'\n | 'onBlur'\n | 'aria-describedby'\n | 'aria-invalid'\n | 'aria-required'\n > & {\n items?: readonly (SelectItem | SelectItemGroup)[];\n };\n\n/**\n * Single selection from a short enumerated list. Built on Radix Select.\n *\n * **When to use:** picking one value from ~10 or fewer options where search adds no value (status,\n * region, role). Pass a flat `items` array or grouped arrays with optional labels for headings.\n * **When NOT to use:** for longer lists with search use `Combobox`; for multi-select use `MultiCombobox`.\n * **Composition:** wrap in `FormGroup` for label + help text, or use `useAppForm` + `field.SelectField`\n * for forms with validation. Use the compound parts (`Select.Root`, `Select.Trigger`, `Select.Content`,\n * `Select.Item`) for custom item layouts; the top-level `Select` covers the common cases.\n */\nexport const Select = ({\n // root\n value,\n defaultValue,\n onValueChange,\n disabled,\n name,\n required,\n open,\n defaultOpen,\n onOpenChange,\n dir,\n autoComplete,\n form,\n // trigger\n variant,\n state,\n sizing,\n placeholder,\n id,\n className,\n onBlur,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n // items\n items = [],\n}: Props) => {\n const groupKeyId = useId();\n\n const renderItem = (item: SelectItem) => (\n <SelectItemComponent\n key={item.value}\n value={item.value}\n icon={item.icon}\n disabled={item.disabled}\n >\n {item.label}\n </SelectItemComponent>\n );\n\n return (\n <SelectRoot\n value={value}\n defaultValue={defaultValue}\n onValueChange={onValueChange}\n disabled={disabled}\n name={name}\n required={required}\n open={open}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n dir={dir}\n autoComplete={autoComplete}\n form={form}\n >\n <SelectTrigger\n variant={variant}\n state={state}\n sizing={sizing}\n placeholder={placeholder}\n id={id}\n className={className}\n onBlur={onBlur}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n aria-required={ariaRequired}\n />\n <SelectContent>\n {items.map((itemOrGroup, index) => {\n if (isGroup(itemOrGroup)) {\n return (\n <SelectGroup key={`${groupKeyId}-group-${index}`}>\n {itemOrGroup.label && <SelectLabel>{itemOrGroup.label}</SelectLabel>}\n {itemOrGroup.items.map(renderItem)}\n </SelectGroup>\n );\n }\n\n return renderItem(itemOrGroup);\n })}\n </SelectContent>\n </SelectRoot>\n );\n};\n\nSelect.Root = SelectRoot;\nSelect.Trigger = SelectTrigger;\nSelect.Content = SelectContent;\nSelect.Item = SelectItemComponent;\nSelect.Group = SelectGroup;\nSelect.Label = SelectLabel;\nSelect.Separator = SelectSeparator;\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"context-KxxeMHbR.js","names":[],"sources":["../src/components/ThemeProvider/utils.ts","../src/components/ThemeProvider/defaults.ts","../src/components/ThemeProvider/context.tsx"],"sourcesContent":["import type { Brand } from '@keboola/brand-registry';\n\nimport type { Theme } from './types';\n\nexport const createTheme = (brand: Brand): Theme => ({\n id: brand.id,\n name: brand.name,\n shell: brand.shell,\n logo: brand.logo,\n});\n\nexport type CssVars = {\n set: (name: string, value: string | undefined) => void;\n expose: () => Record<string, string>;\n};\n\nexport const createCssVars = (): CssVars => {\n const vars: Record<string, string> = {};\n return {\n set: (name, value) => {\n if (value !== undefined) vars[name] = value;\n },\n expose: () => ({ ...vars }),\n };\n};\n","import type { Brand } from '@keboola/brand-registry';\nimport { keboolaLegacySidebar, keboolaLegacyTopnav } from '@keboola/brand-registry';\n\nimport type { ResolvedColorScheme } from './types';\nimport { createTheme } from './utils';\n\nexport const keboolaLegacyIds = [keboolaLegacySidebar.id, keboolaLegacyTopnav.id];\nexport const DEFAULT_COLOR_SCHEME: ResolvedColorScheme = 'light';\n\n// Sentinel active-brand id that maps to no registry brand. It resolves to\n// `defaultBrand` below, whose empty theme injects nothing — so the design-system\n// stylesheet defaults (`:root` / `[data-theme='dark']`) provide every token.\nexport const DEFAULT_BRAND_ID = 'design-system';\n\n// The \"no brand\" fallback: an empty theme → no CSS vars injected → the\n// stylesheet defaults win. Its shell/name still drive AppShell + switcher label.\nexport const defaultBrand: Brand = {\n id: DEFAULT_BRAND_ID,\n name: 'Design System',\n shell: 'sidebar',\n theme: {},\n};\nexport const defaultTheme = createTheme(defaultBrand);\n\nexport const DEFAULT_BRANDS: Brand[] = [];\n","import { createContext, use } from 'react';\n\nimport { DEFAULT_COLOR_SCHEME, defaultTheme } from './defaults';\nimport type { Theme } from './types';\nimport type { useBrandState } from './useBrandState';\nimport type { useColorSchemeState } from './useColorSchemeState';\n\nexport type ThemeContextValue = ReturnType<typeof useColorSchemeState> &\n ReturnType<typeof useBrandState> & {\n themes: Theme[];\n currentTheme: Theme;\n };\n\nconst noop = () => void 0;\n\nconst defaultContext: ThemeContextValue = {\n scheme: DEFAULT_COLOR_SCHEME,\n resolvedScheme: DEFAULT_COLOR_SCHEME,\n setScheme: noop,\n brandId: defaultTheme.id,\n setBrand: noop,\n\n themes: [defaultTheme],\n currentTheme: defaultTheme,\n};\n\nexport const ThemeContext = createContext(defaultContext);\n\nexport const useTheme = () => use(ThemeContext);\n\n/**\n * TEMPORARY — kbc-ui-internal only.\n *\n * Flags whether the subtree renders the argo design language. Defaults to argo\n * (`true`) — the modern default; legacy chrome is the exception. It exists\n * solely to bridge kbc-ui while its chrome is migrated off the legacy design\n * language: kbc-ui provides `false` for legacy brands/surfaces (see its\n * `AppThemeProvider`) and reads it via `useArgoDesign`. `ThemeProvider` does\n * not set it — argo is decoupled from the brand. Once every kbc-ui surface has\n * been migrated, this context and its hook can be deleted.\n */\nexport const ArgoDesignContext = createContext<boolean>(true);\n\nexport const useArgoDesign = () => use(ArgoDesignContext);\n"],"mappings":";;;AAIA,MAAa,eAAe,WAAyB;CACnD,IAAI,MAAM;CACV,MAAM,MAAM;CACZ,OAAO,MAAM;CACb,MAAM,MAAM;AACd;AAOA,MAAa,sBAA+B;CAC1C,MAAM,OAA+B,CAAC;CACtC,OAAO;EACL,MAAM,MAAM,UAAU;GACpB,IAAI,UAAU,KAAA,GAAW,KAAK,QAAQ;EACxC;EACA,eAAe,EAAE,GAAG,KAAK;CAC3B;AACF;;;AClBA,MAAa,mBAAmB,CAAC,qBAAqB,IAAI,oBAAoB,EAAE;AAChF,MAAa,uBAA4C;AAKzD,MAAa,mBAAmB;AAIhC,MAAa,eAAsB;CACjC,IAAI;CACJ,MAAM;CACN,OAAO;CACP,OAAO,CAAC;AACV;AACA,MAAa,eAAe,YAAY,YAAY;AAEpD,MAAa,iBAA0B,CAAC;;;ACXxC,MAAM,aAAa,KAAK;AAExB,MAAM,iBAAoC;CACxC,QAAQ;CACR,gBAAgB;CAChB,WAAW;CACX,SAAS,aAAa;CACtB,UAAU;CAEV,QAAQ,CAAC,YAAY;CACrB,cAAc;AAChB;AAEA,MAAa,eAAe,cAAc,cAAc;AAExD,MAAa,iBAAiB,IAAI,YAAY;;;;;;;;;;;;AAa9C,MAAa,oBAAoB,cAAuB,IAAI;AAE5D,MAAa,sBAAsB,IAAI,iBAAiB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"styles-DSUP_-9Z.js","names":[],"sources":["../src/components/OverlayTrigger/styles.ts"],"sourcesContent":["import { cva } from 'class-variance-authority';\n\n/**\n * Chrome for a control that looks like an input but opens an overlay on click. Shared by\n * `SelectTrigger` and `DateRangePicker`'s trigger so both sit at the same height and colour when\n * they stand next to each other in a filter row.\n */\nexport const overlayTriggerVariants = cva(\n [\n 'tailwindcss-preflight',\n 'tw:group',\n 'tw:box-border',\n\n // layout\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:justify-between',\n 'tw:gap-2',\n 'tw:w-full',\n 'tw:text-left',\n\n // base appearance\n 'tw:rounded',\n 'tw:border',\n 'tw:border-solid',\n 'tw:border-neutral-200',\n 'tw:text-neutral-800',\n // Scoped transition (no `outline`) — prevents the UA focus-outline color\n // from interpolating through its dark default during state changes.\n 'tw:transition-[color,background-color,border-color,box-shadow]',\n\n // focus base — ring width here, color comes from state variant\n 'tw:!outline-hidden',\n 'tw:focus:ring-4',\n 'tw:data-[state=open]:ring-4',\n\n // disabled\n 'tw:disabled:cursor-not-allowed',\n 'tw:aria-disabled:cursor-not-allowed',\n\n // placeholder (Radix sets data-placeholder on the trigger when no value)\n 'tw:data-[placeholder]:text-muted-foreground',\n\n // child svg defaults\n 'tw:[&_svg]:shrink-0',\n 'tw:[&_svg]:pointer-events-none',\n ],\n {\n defaultVariants: {\n variant: 'primary',\n state: 'default',\n sizing: 'medium',\n },\n compoundVariants: [\n {\n variant: 'secondary',\n state: 'error',\n className: ['tw:bg-error-100'],\n },\n {\n variant: 'secondary',\n state: 'warning',\n className: ['tw:bg-warning-100'],\n },\n // --- argo ---\n {\n variant: 'argo',\n state: 'default',\n className: [\n 'tw:focus:border-primary',\n 'tw:focus:ring-ring/50',\n 'tw:data-[state=open]:border-primary',\n 'tw:data-[state=open]:ring-ring/50',\n ],\n },\n {\n variant: 'argo',\n state: 'error',\n className: [\n 'tw:border-destructive',\n 'tw:focus:border-destructive',\n 'tw:focus:ring-destructive/20',\n 'tw:data-[state=open]:border-destructive',\n 'tw:data-[state=open]:ring-destructive/20',\n ],\n },\n ],\n variants: {\n variant: {\n primary: [\n 'tw:bg-white',\n 'tw:disabled:opacity-40',\n 'tw:aria-disabled:opacity-40',\n // aria-invalid on the trigger surfaces the error chrome without a `state` prop — the\n // accessible path (mirrors the `state=\"error\"` legacy tokens). The extra attribute\n // selector outranks the default focus/open state, so it wins without `!important`.\n 'tw:aria-[invalid=true]:border-error-500',\n 'tw:aria-[invalid=true]:focus:border-error-500',\n 'tw:aria-[invalid=true]:focus:ring-error-200',\n 'tw:aria-[invalid=true]:data-[state=open]:border-error-500',\n 'tw:aria-[invalid=true]:data-[state=open]:ring-error-200',\n ],\n secondary: [\n 'tw:bg-neutral-100',\n 'tw:border-neutral-100',\n 'tw:disabled:opacity-40',\n 'tw:aria-disabled:opacity-40',\n 'tw:aria-[invalid=true]:border-error-500',\n 'tw:aria-[invalid=true]:focus:border-error-500',\n 'tw:aria-[invalid=true]:focus:ring-error-200',\n 'tw:aria-[invalid=true]:data-[state=open]:border-error-500',\n 'tw:aria-[invalid=true]:data-[state=open]:ring-error-200',\n ],\n argo: [\n // muted filled input surface — gray, distinct from white containers; not the app-background token\n 'tw:bg-muted',\n 'tw:border-input',\n // token-driven radius so the trigger tracks --radius-lg like sibling inputs (InputGroup/Combobox/Button)\n 'tw:rounded-[var(--radius-lg,0.25rem)]',\n 'tw:text-foreground',\n 'tw:disabled:opacity-50',\n 'tw:aria-disabled:opacity-50',\n // aria-invalid on the trigger surfaces the error chrome without a `state` prop — the\n // accessible path (uses the themeable `destructive` status token).\n 'tw:aria-[invalid=true]:border-destructive',\n 'tw:aria-[invalid=true]:focus:border-destructive',\n 'tw:aria-[invalid=true]:focus:ring-destructive/20',\n 'tw:aria-[invalid=true]:data-[state=open]:border-destructive',\n 'tw:aria-[invalid=true]:data-[state=open]:ring-destructive/20',\n ],\n },\n sizing: {\n // border-inclusive heights: 40 / 36 / 32 px (small matches Button small)\n default: ['tw:px-4', 'tw:py-2.5', 'tw:text-sm/[18px]', 'tw:h-10', 'tw:min-h-10'],\n medium: ['tw:px-4', 'tw:py-2', 'tw:text-sm/[18px]', 'tw:h-9', 'tw:min-h-9'],\n small: ['tw:px-4', 'tw:py-2', 'tw:text-sm/[16px]', 'tw:h-8', 'tw:min-h-8'],\n },\n state: {\n default: [\n 'tw:focus:border-ring',\n 'tw:focus:ring-ring/30',\n 'tw:data-[state=open]:border-ring',\n 'tw:data-[state=open]:ring-ring/30',\n ],\n error: [\n 'tw:border-error-500',\n 'tw:focus:border-error-500',\n 'tw:focus:ring-error-200',\n 'tw:data-[state=open]:border-error-500',\n 'tw:data-[state=open]:ring-error-200',\n ],\n warning: [\n 'tw:border-warning-500',\n 'tw:focus:border-warning-500',\n 'tw:focus:ring-warning-200',\n 'tw:data-[state=open]:border-warning-500',\n 'tw:data-[state=open]:ring-warning-200',\n ],\n },\n },\n },\n);\n"],"mappings":";;;;;;;AAOA,MAAa,yBAAyB,IACpC;CACE;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CAGA;CAGA;CACA;CACA;CAGA;CACA;CAGA;CAGA;CACA;AACF,GACA;CACE,iBAAiB;EACf,SAAS;EACT,OAAO;EACP,QAAQ;CACV;CACA,kBAAkB;EAChB;GACE,SAAS;GACT,OAAO;GACP,WAAW,CAAC,iBAAiB;EAC/B;EACA;GACE,SAAS;GACT,OAAO;GACP,WAAW,CAAC,mBAAmB;EACjC;EAEA;GACE,SAAS;GACT,OAAO;GACP,WAAW;IACT;IACA;IACA;IACA;GACF;EACF;EACA;GACE,SAAS;GACT,OAAO;GACP,WAAW;IACT;IACA;IACA;IACA;IACA;GACF;EACF;CACF;CACA,UAAU;EACR,SAAS;GACP,SAAS;IACP;IACA;IACA;IAIA;IACA;IACA;IACA;IACA;GACF;GACA,WAAW;IACT;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GACA,MAAM;IAEJ;IACA;IAEA;IACA;IACA;IACA;IAGA;IACA;IACA;IACA;IACA;GACF;EACF;EACA,QAAQ;GAEN,SAAS;IAAC;IAAW;IAAa;IAAqB;IAAW;GAAa;GAC/E,QAAQ;IAAC;IAAW;IAAW;IAAqB;IAAU;GAAY;GAC1E,OAAO;IAAC;IAAW;IAAW;IAAqB;IAAU;GAAY;EAC3E;EACA,OAAO;GACL,SAAS;IACP;IACA;IACA;IACA;GACF;GACA,OAAO;IACL;IACA;IACA;IACA;IACA;GACF;GACA,SAAS;IACP;IACA;IACA;IACA;IACA;GACF;EACF;CACF;AACF,CACF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"toast-CjkURw0M.js","names":["sonnerToast","toast","sonnerToast"],"sources":["../src/components/Toast/ToastAction.tsx","../src/components/Toast/ToastDescription.tsx","../src/components/Toast/ToastDismiss.tsx","../src/components/Toast/ToastDuration.tsx","../src/components/Toast/ToastTitle.tsx","../src/components/Toast/ToastRoot.tsx","../src/components/Toast/toast.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'>;\n\nexport const ToastAction = ({ ref, className, ...rest }: Props) => (\n <button\n {...rest}\n ref={ref}\n data-slot=\"toast-action\"\n type=\"button\"\n className={cn(\n // layout\n 'tw:col-start-3',\n 'tw:row-start-1',\n 'tw:flex',\n 'tw:items-center',\n 'tw:justify-center',\n\n // font\n 'tw:text-xs',\n 'tw:font-medium',\n 'tw:text-primary',\n\n // sizing\n 'tw:px-2',\n 'tw:h-6',\n\n // styles\n 'tw:bg-primary-foreground',\n 'tw:rounded',\n className,\n )}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const ToastDescription = ({ ref, className, children, ...rest }: Props) => (\n <div\n ref={ref}\n data-slot=\"toast-description\"\n className={cn(\n 'tw:col-start-2',\n 'tw:font-normal',\n 'tw:break-words',\n 'tw:text-white',\n 'tw:group-data-[variant=default]/toast:text-muted-foreground',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n);\n","import type { ComponentProps } from 'react';\n\nimport { X } from '../../icons';\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'button'>;\n\nexport const ToastDismiss = ({ ref, className, ...rest }: Props) => (\n <button\n ref={ref}\n data-slot=\"toast-dismiss\"\n className={cn(\n 'tw:flex',\n 'tw:justify-center',\n 'tw:col-start-4',\n 'tw:row-start-1',\n 'tailwindcss-preflight',\n 'tw:[&_svg]:aspect-square',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-4',\n 'tw:[&_svg]:m-1',\n\n 'tw:text-white',\n 'tw:group-data-[variant=default]/toast:[&_svg]:text-popover-foreground',\n 'tw:group-data-[variant=default]/toast:group-data-[argo=true]/toast:[&_svg]:text-foreground',\n className,\n )}\n type=\"button\"\n {...rest}\n >\n <X />\n <span className=\"tw:sr-only\">Dismiss</span>\n </button>\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype ToastDurationProps = ComponentProps<'span'> & {\n duration: number;\n};\n\nexport const ToastDuration = ({ ref, duration, className, style, ...rest }: ToastDurationProps) => (\n <span\n {...rest}\n ref={ref}\n className={cn(\n 'tw:bg-white/30',\n 'tw:group-data-[variant=default]/toast:bg-popover-foreground/20',\n 'tw:group-data-[variant=default]/toast:group-data-[argo=true]/toast:bg-foreground/20',\n 'tw:rounded-bl-lg',\n 'tw:mx-px',\n\n // positioning\n 'tw:absolute',\n 'tw:bottom-0',\n 'tw:left-0',\n\n // sizing\n 'tw:h-1',\n\n // animation\n 'tw:animate-toast-progress',\n 'tw:group-hover/toast:[animation-play-state:paused]',\n className,\n )}\n style={{\n animationDuration: `${duration}ms`,\n ...style,\n }}\n />\n);\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\ntype Props = ComponentProps<'div'>;\n\nexport const ToastTitle = ({ ref, className, children, ...rest }: Props) => (\n <div\n ref={ref}\n data-slot=\"toast-title\"\n className={cn(\n 'tw:col-start-2',\n 'tw:text-sm',\n 'tw:leading-6',\n 'tw:min-h-6',\n 'tw:self-center',\n 'tw:text-white',\n 'tw:group-data-[variant=default]/toast:text-popover-foreground',\n 'tw:group-data-[variant=default]/toast:group-data-[argo=true]/toast:text-foreground',\n\n 'tw:break-words',\n 'tw:font-medium',\n className,\n )}\n {...rest}\n >\n {children}\n </div>\n);\n","import type { MouseEventHandler, ReactNode } from 'react';\nimport type { VariantProps } from 'class-variance-authority';\nimport { cva } from 'class-variance-authority';\nimport { type Action, toast as sonnerToast } from 'sonner';\n\nimport { AlertCircle, AlertTriangle, CircleCheck, Info, Loader2 } from '../../icons';\nimport { cn } from '../../utils';\nimport { useArgoDesign } from '../ThemeProvider/context';\n\nimport { ToastAction } from './ToastAction';\nimport { ToastDescription } from './ToastDescription';\nimport { ToastDismiss } from './ToastDismiss';\nimport { ToastDuration } from './ToastDuration';\nimport { ToastTitle } from './ToastTitle';\n\nconst variants = cva(\n [\n 'tailwindcss-preflight',\n 'tw:group/toast',\n 'tw:relative',\n\n // layout\n 'tw:grid',\n 'tw:grid-cols-[0_1fr_auto_auto]',\n 'tw:items-start',\n 'tw:has-[[data-slot=toast-description]]:grid-rows-[auto_auto]',\n 'tw:has-[[data-slot=toast-icon]]:grid-cols-[auto_1fr_auto_auto]',\n 'tw:[&_[data-slot=toast-icon]]:mr-2',\n 'tw:[&_[data-slot=toast-title]]:mr-2.5',\n 'tw:[&_[data-slot=toast-description]]:mr-2.5',\n 'tw:[&_[data-slot=toast-action]]:mr-2',\n 'tw:[&_[data-slot=toast-description]]:col-end-3',\n 'tw:gap-y-0',\n\n // styles\n 'tw:p-4',\n 'tw:rounded-lg',\n 'tw:shadow-md',\n ],\n {\n defaultVariants: {\n variant: 'info',\n },\n variants: {\n variant: {\n default: 'tw:border tw:border-border tw:bg-popover',\n error: 'tw:bg-error-550',\n info: 'tw:bg-blue-600',\n success: 'tw:bg-green-700',\n warning: 'tw:bg-warning-550',\n },\n },\n },\n);\n\ntype Variants = VariantProps<typeof variants>;\ntype Variant = NonNullable<Variants['variant']>;\ntype VariantIcon = Exclude<Variant, 'default'>;\n\ntype Props = {\n id: string | number;\n title: ReactNode;\n icon?: ReactNode;\n description?: ReactNode;\n action?: Action;\n loading?: boolean;\n duration?: number;\n // offset?: number;\n} & Variants;\n\nconst DEFAULT_VARIANT_ICON: Record<VariantIcon, ReactNode> = {\n error: <AlertTriangle />,\n info: <Info />,\n success: <CircleCheck />,\n warning: <AlertCircle />,\n};\n\nexport const ToastRoot = ({\n id,\n title,\n description,\n action,\n duration = Infinity,\n variant = 'info',\n loading = false,\n icon: iconProp,\n}: Props) => {\n const renderArgo = useArgoDesign();\n\n const icon: ReactNode = (() => {\n if (loading) return <Loader2 className=\"tw:animate-spin\" />;\n if (iconProp) return iconProp;\n if (variant === 'default' || variant === null) return null;\n return DEFAULT_VARIANT_ICON[variant];\n })();\n\n const handleActionClick: MouseEventHandler<HTMLButtonElement> = (event) => {\n sonnerToast.dismiss(id);\n action?.onClick(event);\n };\n\n return (\n <div\n data-variant={variant}\n data-argo={renderArgo}\n className={cn(\n variants({ variant }),\n 'tw:data-[variant=default]:data-[argo=true]:bg-background',\n )}\n >\n {icon && (\n <span\n data-slot=\"toast-icon\"\n className={cn(\n 'tw:inline-flex',\n 'tw:items-center',\n 'tw:justify-center',\n 'tw:self-center',\n 'tw:aspect-square',\n 'tw:size-5',\n 'tw:shrink-0',\n 'tw:[&_svg:not([class*=\"tw:size-\"])]:size-5',\n 'tw:text-white',\n 'tw:group-data-[variant=default]/toast:text-popover-foreground',\n 'tw:group-data-[variant=default]/toast:group-data-[argo=true]/toast:text-foreground',\n )}\n >\n {icon}\n </span>\n )}\n\n <ToastTitle>{title}</ToastTitle>\n {description && <ToastDescription>{description}</ToastDescription>}\n {action && (\n <ToastAction style={action?.actionButtonStyle} onClick={handleActionClick}>\n {action.label}\n </ToastAction>\n )}\n <ToastDismiss onClick={() => sonnerToast.dismiss(id)} />\n {duration !== Infinity && <ToastDuration duration={duration} />}\n </div>\n );\n};\n","import type { ComponentProps, ReactNode } from 'react';\nimport { type ExternalToast, toast as sonnerToast } from 'sonner';\n\nimport { cn } from '../../utils';\n\nimport { ToastRoot } from './ToastRoot';\n\ntype ToastProps = ComponentProps<typeof ToastRoot>;\ntype Title = ToastProps['title'] | ((opts: { dismiss: () => void }) => ReactNode);\n\nexport type ToastOptions = { id?: string | number; title: Title } & Omit<\n ToastProps,\n 'id' | 'title'\n> &\n Pick<\n ExternalToast,\n 'onAutoClose' | 'onDismiss' | 'testId' | 'toasterId' | 'dismissible' | 'position'\n >;\ntype DerivedToastOptions = Omit<ToastOptions, 'title' | 'variant'>;\n\nexport const toast = ({\n onAutoClose,\n onDismiss,\n testId,\n toasterId,\n dismissible = true,\n position,\n title: titleProp,\n ...toast\n}: ToastOptions) => {\n const duration = (() => {\n if (typeof toast.duration === 'number') return toast.duration;\n if (toast.variant === 'error' || toast.variant === 'warning') return Infinity;\n return toast.duration ?? 5000;\n })();\n\n const renderCustomToast: Parameters<typeof sonnerToast.custom>[0] = (id) => {\n const title =\n typeof titleProp === 'function'\n ? titleProp({ dismiss: () => sonnerToast.dismiss(id) })\n : titleProp;\n\n return <ToastRoot {...toast} id={id} title={title} duration={duration} />;\n };\n\n return sonnerToast.custom(renderCustomToast, {\n // toast generated by sonner will always have an id, but we want to allow users to specify their own id if they want to\n // can not pass undefined, as it will break dismiss\n ...(toast.id != null ? { id: toast.id } : {}),\n unstyled: true,\n position,\n onAutoClose,\n onDismiss,\n testId,\n toasterId,\n dismissible,\n duration,\n // override default focus-visible styles to match our design\n className: cn('tw:rounded-lg', 'tw:focus-visible:!ring-4', 'tw:focus-visible:!ring-ring/50'),\n });\n};\n\ntoast.success = (title: Title, options?: DerivedToastOptions) =>\n toast({\n ...options,\n title,\n variant: 'success',\n });\n\ntoast.error = (title: Title, options?: DerivedToastOptions) =>\n toast({\n ...options,\n title,\n variant: 'error',\n duration: options?.duration ?? Infinity,\n });\n\ntoast.warning = (title: Title, options?: DerivedToastOptions) =>\n toast({\n ...options,\n title,\n variant: 'warning',\n duration: options?.duration ?? Infinity,\n });\n\ntoast.info = (title: Title, options?: DerivedToastOptions) =>\n toast({\n ...options,\n title,\n variant: 'info',\n });\n\ntoast.dismiss = (toastId?: ToastOptions['id']) => sonnerToast.dismiss(toastId);\ntoast.dismissAll = () => sonnerToast.dismiss();\n"],"mappings":"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"}