@keboola/design 11.6.1 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. package/AGENTS.md +50 -9
  2. package/CHANGELOG.md +241 -0
  3. package/COMPONENT-API.md +337 -288
  4. package/README.md +12 -2
  5. package/dist/{AIKit-CQxVwyAk.js → AIKit-BD4r7ff-.js} +807 -199
  6. package/dist/AIKit-BD4r7ff-.js.map +1 -0
  7. package/dist/{Alert-C4Y9IwMI.js → Alert-UI-CIs-1.js} +16 -16
  8. package/dist/Alert-UI-CIs-1.js.map +1 -0
  9. package/dist/{AlertModal-BGJdaRRj.js → AlertModal-Th2khjPi.js} +5 -5
  10. package/dist/AlertModal-Th2khjPi.js.map +1 -0
  11. package/dist/{AppShell-DRgJxpXW.js → AppShell-WSQabK8r.js} +15 -52
  12. package/dist/AppShell-WSQabK8r.js.map +1 -0
  13. package/dist/{AutoSaveTextarea-BeuWuszr.js → AutoSaveTextarea-C5iIr2Ts.js} +2 -2
  14. package/dist/{AutoSaveTextarea-BeuWuszr.js.map → AutoSaveTextarea-C5iIr2Ts.js.map} +1 -1
  15. package/dist/{Badge-o5jURtpB.js → Badge-DIjhwPvh.js} +4 -9
  16. package/dist/Badge-DIjhwPvh.js.map +1 -0
  17. package/dist/{BrandEditor-CS9P4r2p.js → BrandEditor-BU23Vl8V.js} +7 -7
  18. package/dist/{BrandEditor-CS9P4r2p.js.map → BrandEditor-BU23Vl8V.js.map} +1 -1
  19. package/dist/{BrandLogo-CoKBk4MI.js → BrandLogo-CKpVSZb6.js} +4 -4
  20. package/dist/BrandLogo-CKpVSZb6.js.map +1 -0
  21. package/dist/{Breadcrumb-D1id7YXd.js → Breadcrumb-p9HtMLCc.js} +8 -14
  22. package/dist/Breadcrumb-p9HtMLCc.js.map +1 -0
  23. package/dist/{Button-DsRrU5F1.js → Button-Ca4Q3VJU.js} +31 -13
  24. package/dist/Button-Ca4Q3VJU.js.map +1 -0
  25. package/dist/{Calendar-cG5NIJ4O.js → Calendar-DFtmZzbF.js} +99 -99
  26. package/dist/Calendar-DFtmZzbF.js.map +1 -0
  27. package/dist/{Card-Dyo7055Q.js → Card-Cr9MBNHu.js} +4 -4
  28. package/dist/Card-Cr9MBNHu.js.map +1 -0
  29. package/dist/{Checkbox-Bqr6zXcW.js → Checkbox-8yIIgY7g.js} +4 -4
  30. package/dist/Checkbox-8yIIgY7g.js.map +1 -0
  31. package/dist/{Clipboard-C2YBRfD8.js → Clipboard-_xf6hMDD.js} +2 -2
  32. package/dist/{Clipboard-C2YBRfD8.js.map → Clipboard-_xf6hMDD.js.map} +1 -1
  33. package/dist/{ClipboardButton-CrljClL1.js → ClipboardButton-DHa1trtI.js} +4 -4
  34. package/dist/{ClipboardButton-CrljClL1.js.map → ClipboardButton-DHa1trtI.js.map} +1 -1
  35. package/dist/{CodeEditor-C9AS8Ch0.js → CodeEditor-BSo-oLFG.js} +55 -165
  36. package/dist/CodeEditor-BSo-oLFG.js.map +1 -0
  37. package/dist/{ColorInput-Dg87lKcR.js → ColorInput-DSMqrs2-.js} +12 -27
  38. package/dist/ColorInput-DSMqrs2-.js.map +1 -0
  39. package/dist/{ColorModeSwitch-CsWLiTBX.js → ColorModeSwitch-D7EuWyJz.js} +7 -17
  40. package/dist/ColorModeSwitch-D7EuWyJz.js.map +1 -0
  41. package/dist/Combobox-CxRAYOBt.js +1069 -0
  42. package/dist/Combobox-CxRAYOBt.js.map +1 -0
  43. package/dist/{Command-CqxoI_De.js → Command-BU_cVurn.js} +4 -4
  44. package/dist/{Command-CqxoI_De.js.map → Command-BU_cVurn.js.map} +1 -1
  45. package/dist/{CopyField-Rx9HPTbJ.js → CopyField-6_c-NdLO.js} +17 -53
  46. package/dist/{CopyField-Rx9HPTbJ.js.map → CopyField-6_c-NdLO.js.map} +1 -1
  47. package/dist/{DateInput-DpifECUQ.js → DateInput-DyEErfJf.js} +6 -6
  48. package/dist/{DateInput-DpifECUQ.js.map → DateInput-DyEErfJf.js.map} +1 -1
  49. package/dist/{DatePicker-nA8YdE84.js → DatePicker-CtSa9b3V.js} +3 -3
  50. package/dist/{DatePicker-nA8YdE84.js.map → DatePicker-CtSa9b3V.js.map} +1 -1
  51. package/dist/{DateRangeInput-9MIw7P6L.js → DateRangeInput-Dg7-VUd9.js} +10 -14
  52. package/dist/DateRangeInput-Dg7-VUd9.js.map +1 -0
  53. package/dist/{DateRangePicker-DjSUFjh4.js → DateRangePicker-BoPnh4aH.js} +9 -13
  54. package/dist/DateRangePicker-BoPnh4aH.js.map +1 -0
  55. package/dist/DiffView-ppTIzh2h.js.map +1 -1
  56. package/dist/{DropdownMenu-CASr-jgl.js → DropdownMenu-gRM-A8qU.js} +11 -6
  57. package/dist/DropdownMenu-gRM-A8qU.js.map +1 -0
  58. package/dist/{FieldItem-DtPTzNef.js → FieldItem-2wMXQ0Qw.js} +12 -25
  59. package/dist/FieldItem-2wMXQ0Qw.js.map +1 -0
  60. package/dist/{FieldItem-vhIJW4pj.d.ts → FieldItem-CPN1xjN5.d.ts} +11 -25
  61. package/dist/{FileUpload-DYQCTGjU.js → FileUpload-C83tXuE2.js} +11 -16
  62. package/dist/{FileUpload-DYQCTGjU.js.map → FileUpload-C83tXuE2.js.map} +1 -1
  63. package/dist/{Form-DAaatlBk.js → Form-95rVLfX8.js} +15 -23
  64. package/dist/{Form-DAaatlBk.js.map → Form-95rVLfX8.js.map} +1 -1
  65. package/dist/{FormGroup-Bl8JmnzJ.js → FormGroup-CmNiAtU6.js} +11 -17
  66. package/dist/FormGroup-CmNiAtU6.js.map +1 -0
  67. package/dist/{FullScreenModal-CN9nAs72.js → FullScreenModal-CD7mYeTz.js} +15 -29
  68. package/dist/FullScreenModal-CD7mYeTz.js.map +1 -0
  69. package/dist/{HoverCard-B9ZMJxjn.js → HoverCard-B8OKu9XZ.js} +2 -2
  70. package/dist/{HoverCard-B9ZMJxjn.js.map → HoverCard-B8OKu9XZ.js.map} +1 -1
  71. package/dist/{InputGroup-DcZRlVnN.js → InputGroup-B4QOPxHl.js} +12 -13
  72. package/dist/InputGroup-B4QOPxHl.js.map +1 -0
  73. package/dist/{Kbd-D1Azcc4g.js → Kbd-J4n1J6i4.js} +23 -13
  74. package/dist/Kbd-J4n1J6i4.js.map +1 -0
  75. package/dist/{MarkedText-DNGEUVWc.js → MarkedText-DlmlJO0u.js} +2 -2
  76. package/dist/{MarkedText-DNGEUVWc.js.map → MarkedText-DlmlJO0u.js.map} +1 -1
  77. package/dist/{MermaidDiagram-CujFxVzk.js → MermaidDiagram-BQvz6bhv.js} +16 -34
  78. package/dist/MermaidDiagram-BQvz6bhv.js.map +1 -0
  79. package/dist/{Modal-Coj-H02o.js → Modal-Driyqs_N.js} +17 -34
  80. package/dist/Modal-Driyqs_N.js.map +1 -0
  81. package/dist/{ModalTitle-C76ke2eo.js → ModalTitle-BxopkIoQ.js} +3 -3
  82. package/dist/ModalTitle-BxopkIoQ.js.map +1 -0
  83. package/dist/{MultiActionButtonGroup-CNNoBQbv.js → MultiActionButtonGroup-BPnmzBtw.js} +3 -3
  84. package/dist/{MultiActionButtonGroup-CNNoBQbv.js.map → MultiActionButtonGroup-BPnmzBtw.js.map} +1 -1
  85. package/dist/{Navbar-Liy1TPI7.js → Navbar-B_DNpv5s.js} +9 -13
  86. package/dist/{Navbar-Liy1TPI7.js.map → Navbar-B_DNpv5s.js.map} +1 -1
  87. package/dist/{OtpInput-CbbymqYs.js → OtpInput-I8B8Vjdl.js} +2 -2
  88. package/dist/{OtpInput-CbbymqYs.js.map → OtpInput-I8B8Vjdl.js.map} +1 -1
  89. package/dist/{PageHeader-Q3IpCnQd.js → PageHeader-CgfyXpf1.js} +13 -26
  90. package/dist/PageHeader-CgfyXpf1.js.map +1 -0
  91. package/dist/{PageLayout-DSVM-ASz.js → PageLayout-DiAAILuS.js} +12 -20
  92. package/dist/PageLayout-DiAAILuS.js.map +1 -0
  93. package/dist/{PageToolbar-BKVJiDAL.js → PageToolbar-DOAtAnfL.js} +12 -42
  94. package/dist/PageToolbar-DOAtAnfL.js.map +1 -0
  95. package/dist/{Pagination-C_b7Xhey.js → Pagination-LaSg-5cl.js} +3 -3
  96. package/dist/{Pagination-C_b7Xhey.js.map → Pagination-LaSg-5cl.js.map} +1 -1
  97. package/dist/{Popconfirm-5pBzT_HQ.js → Popconfirm-SLz0zodk.js} +3 -3
  98. package/dist/{Popconfirm-5pBzT_HQ.js.map → Popconfirm-SLz0zodk.js.map} +1 -1
  99. package/dist/{Popover-BEbQrC_P.js → Popover-CEk915I1.js} +4 -3
  100. package/dist/Popover-CEk915I1.js.map +1 -0
  101. package/dist/{RadioGroup-CUBsuP7r.js → RadioGroup-CBPRLRN0.js} +4 -4
  102. package/dist/{RadioGroup-CUBsuP7r.js.map → RadioGroup-CBPRLRN0.js.map} +1 -1
  103. package/dist/{Search-DVpJuzr9.js → Search-DmkQo716.js} +3 -3
  104. package/dist/{Search-DVpJuzr9.js.map → Search-DmkQo716.js.map} +1 -1
  105. package/dist/{SearchInput-Q85p8Ews.js → SearchInput-CEfQDNl3.js} +8 -13
  106. package/dist/SearchInput-CEfQDNl3.js.map +1 -0
  107. package/dist/{SectionNav-mpmSM3OC.js → SectionNav-B_qf0AXi.js} +10 -42
  108. package/dist/SectionNav-B_qf0AXi.js.map +1 -0
  109. package/dist/{Select-DV3Hak_l.js → Select-ByRvkZ3D.js} +8 -11
  110. package/dist/{Select-DV3Hak_l.js.map → Select-ByRvkZ3D.js.map} +1 -1
  111. package/dist/{Sheet-Chf0kX1E.js → Sheet-C-yXk5Da.js} +5 -9
  112. package/dist/Sheet-C-yXk5Da.js.map +1 -0
  113. package/dist/{Sidebar-CTWsHZhF.js → Sidebar-Ds0E6PbR.js} +181 -33
  114. package/dist/Sidebar-Ds0E6PbR.js.map +1 -0
  115. package/dist/{Slider-Bv0B6lI0.js → Slider-DWdu9NuM.js} +3 -3
  116. package/dist/{Slider-Bv0B6lI0.js.map → Slider-DWdu9NuM.js.map} +1 -1
  117. package/dist/{Stepper-C8sm9ZFM.js → Stepper-BLkLhfnd.js} +6 -9
  118. package/dist/{Stepper-C8sm9ZFM.js.map → Stepper-BLkLhfnd.js.map} +1 -1
  119. package/dist/{Switch-B0WdGSjz.js → Switch-DZvNePOm.js} +2 -2
  120. package/dist/{Switch-B0WdGSjz.js.map → Switch-DZvNePOm.js.map} +1 -1
  121. package/dist/{Table-CvYuTuNU.js → Table-BaVT5Tkn.js} +6 -11
  122. package/dist/{Table-CvYuTuNU.js.map → Table-BaVT5Tkn.js.map} +1 -1
  123. package/dist/{Tabs-eB974xJf.js → Tabs-Dt9oLYHC.js} +3 -3
  124. package/dist/{Tabs-eB974xJf.js.map → Tabs-Dt9oLYHC.js.map} +1 -1
  125. package/dist/{TextInput-DiEMxVF6.js → TextInput-CDG2XpBl.js} +12 -15
  126. package/dist/TextInput-CDG2XpBl.js.map +1 -0
  127. package/dist/{ThemeProvider-BI6JWBdJ.js → ThemeProvider-DXsxFg1U.js} +13 -31
  128. package/dist/ThemeProvider-DXsxFg1U.js.map +1 -0
  129. package/dist/{TimePicker-BGeqc-Ed.js → TimePicker-CDGYrRxi.js} +2 -2
  130. package/dist/{TimePicker-BGeqc-Ed.js.map → TimePicker-CDGYrRxi.js.map} +1 -1
  131. package/dist/{Timeline-BG5Xogxh.js → Timeline-B-I6sb0M.js} +2 -2
  132. package/dist/{Timeline-BG5Xogxh.js.map → Timeline-B-I6sb0M.js.map} +1 -1
  133. package/dist/{Toast-Dr6Uw7ao.js → Toast-PfQf3vj-.js} +2 -2
  134. package/dist/{Toast-Dr6Uw7ao.js.map → Toast-PfQf3vj-.js.map} +1 -1
  135. package/dist/{Workbench-UR2FBC7I.js → Workbench-DmZzpkj7.js} +2 -2
  136. package/dist/{Workbench-UR2FBC7I.js.map → Workbench-DmZzpkj7.js.map} +1 -1
  137. package/dist/{ZoomableSvg-U_VH3QRO.js → ZoomableSvg-BzXVfgnI.js} +5 -19
  138. package/dist/ZoomableSvg-BzXVfgnI.js.map +1 -0
  139. package/dist/charts.d.ts +21 -52
  140. package/dist/charts.js +13 -39
  141. package/dist/charts.js.map +1 -1
  142. package/dist/{context-D7X470dy.js → context-U293r3v-.js} +5 -9
  143. package/dist/context-U293r3v-.js.map +1 -0
  144. package/dist/editors.d.ts +27 -124
  145. package/dist/editors.js +29 -71
  146. package/dist/editors.js.map +1 -1
  147. package/dist/{findLiteralMatches-BGBw8Vbl.js → findLiteralMatches-DgGLzyG0.js} +8 -20
  148. package/dist/findLiteralMatches-DgGLzyG0.js.map +1 -0
  149. package/dist/flint.d.ts +3 -6
  150. package/dist/flint.js +31 -80
  151. package/dist/flint.js.map +1 -1
  152. package/dist/{icons-Cek151jC.js → icons-wcA70iQx.js} +105 -2
  153. package/dist/icons-wcA70iQx.js.map +1 -0
  154. package/dist/icons.d.ts +2 -2
  155. package/dist/icons.js +2 -2
  156. package/dist/{index-m-kQEWiY.d.ts → index-B7k-09i1.d.ts} +14 -2
  157. package/dist/index.d.ts +1461 -1809
  158. package/dist/index.js +70 -67
  159. package/dist/internal/blocks/AIKit.js +2 -2
  160. package/dist/internal/blocks/AppShell.js +1 -1
  161. package/dist/internal/blocks/AuthLayout.js +7 -27
  162. package/dist/internal/blocks/AuthLayout.js.map +1 -1
  163. package/dist/internal/blocks/AutoSaveTextarea.js +1 -1
  164. package/dist/internal/blocks/BrandEditor.js +1 -1
  165. package/dist/internal/blocks/ChartPanel.js +4 -8
  166. package/dist/internal/blocks/ChartPanel.js.map +1 -1
  167. package/dist/internal/blocks/ChipEditor.js +129 -0
  168. package/dist/internal/blocks/ChipEditor.js.map +1 -0
  169. package/dist/internal/blocks/ClipboardButton.js +1 -1
  170. package/dist/internal/blocks/ColorInput.js +1 -1
  171. package/dist/internal/blocks/ColorModeSwitch.js +1 -1
  172. package/dist/internal/blocks/Command.js +1 -1
  173. package/dist/internal/blocks/CopyField.js +1 -1
  174. package/dist/internal/blocks/DashboardHero.js +4 -7
  175. package/dist/internal/blocks/DashboardHero.js.map +1 -1
  176. package/dist/internal/blocks/DateInput.js +1 -1
  177. package/dist/internal/blocks/DateRangeInput.js +1 -1
  178. package/dist/internal/blocks/EmptyConfigurationActionCard.js +1 -1
  179. package/dist/internal/blocks/EmptyState.js +5 -9
  180. package/dist/internal/blocks/EmptyState.js.map +1 -1
  181. package/dist/internal/blocks/ErrorState.js +5 -9
  182. package/dist/internal/blocks/ErrorState.js.map +1 -1
  183. package/dist/internal/blocks/ExportMenu.js +6 -10
  184. package/dist/internal/blocks/ExportMenu.js.map +1 -1
  185. package/dist/internal/blocks/Form/connectors/ComboboxField.js +40 -0
  186. package/dist/internal/blocks/Form/connectors/ComboboxField.js.map +1 -0
  187. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +5 -22
  188. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js.map +1 -1
  189. package/dist/internal/blocks/Form.js +1 -1
  190. package/dist/internal/blocks/FormGroup.js +1 -1
  191. package/dist/internal/blocks/GoogleButton.js +1 -1
  192. package/dist/internal/blocks/MicrosoftButton.js +1 -1
  193. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  194. package/dist/internal/blocks/MultiCombobox.js +162 -165
  195. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  196. package/dist/internal/blocks/NumberInput.js +1 -1
  197. package/dist/internal/blocks/OtpInput.js +1 -1
  198. package/dist/internal/blocks/PageHeader.js +1 -1
  199. package/dist/internal/blocks/PageLayout.js +1 -1
  200. package/dist/internal/blocks/PageToolbar.js +1 -1
  201. package/dist/internal/blocks/PasswordInput.js +4 -4
  202. package/dist/internal/blocks/PasswordInput.js.map +1 -1
  203. package/dist/internal/blocks/SearchInput.js +1 -1
  204. package/dist/internal/blocks/SearchInputWithNavigation.js +4 -4
  205. package/dist/internal/blocks/SectionNav.js +1 -1
  206. package/dist/internal/blocks/SplitButton.js +3 -3
  207. package/dist/internal/blocks/StatCard.js +4 -8
  208. package/dist/internal/blocks/StatCard.js.map +1 -1
  209. package/dist/internal/blocks/TextInput.js +1 -1
  210. package/dist/internal/blocks/Textarea.js +2 -2
  211. package/dist/internal/blocks/TimeInput.js +5 -5
  212. package/dist/internal/blocks/TimeInput.js.map +1 -1
  213. package/dist/internal/components/Alert.js +1 -1
  214. package/dist/internal/components/AlertModal.js +1 -1
  215. package/dist/internal/components/Avatar.js +1 -1
  216. package/dist/internal/components/Badge.js +1 -1
  217. package/dist/internal/components/BrandLogo.js +1 -1
  218. package/dist/internal/components/Breadcrumb.js +1 -1
  219. package/dist/internal/components/Button.js +1 -1
  220. package/dist/internal/components/ButtonGroup.js.map +1 -1
  221. package/dist/internal/components/Calendar.js +1 -1
  222. package/dist/internal/components/Card.js +1 -1
  223. package/dist/internal/components/Checkbox.js +1 -1
  224. package/dist/internal/components/Clipboard.js +1 -1
  225. package/dist/internal/components/CollapsiblePanel.js +2 -2
  226. package/dist/internal/components/Combobox.js +2 -2
  227. package/dist/internal/components/DatePicker.js +1 -1
  228. package/dist/internal/components/DateRangePicker.js +1 -1
  229. package/dist/internal/components/DropdownMenu.js +1 -1
  230. package/dist/internal/components/FileUpload.js +1 -1
  231. package/dist/internal/components/FullScreenModal.js +1 -1
  232. package/dist/internal/components/HoverCard.js +1 -1
  233. package/dist/internal/components/InputGroup.js +1 -1
  234. package/dist/internal/components/Kbd.js +1 -1
  235. package/dist/internal/components/MarkedText.js +1 -1
  236. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +1 -1
  237. package/dist/internal/components/Modal.js +1 -1
  238. package/dist/internal/components/Navbar.js +1 -1
  239. package/dist/internal/components/Pagination.js +1 -1
  240. package/dist/internal/components/PanelWithDetails.js +1 -1
  241. package/dist/internal/components/Popconfirm.js +1 -1
  242. package/dist/internal/components/Popover.js +1 -1
  243. package/dist/internal/components/RadioGroup.js +1 -1
  244. package/dist/internal/components/Search.js +1 -1
  245. package/dist/internal/components/Select.js +1 -1
  246. package/dist/internal/components/Separator.js.map +1 -1
  247. package/dist/internal/components/Sheet.js +1 -1
  248. package/dist/internal/components/Sidebar.js +1 -1
  249. package/dist/internal/components/Skeleton/Skeleton.js +5 -9
  250. package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
  251. package/dist/internal/components/Slider.js +1 -1
  252. package/dist/internal/components/SpotlightBackdrop.js +3 -8
  253. package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
  254. package/dist/internal/components/StatusDot.js +60 -0
  255. package/dist/internal/components/StatusDot.js.map +1 -0
  256. package/dist/internal/components/Stepper.js +1 -1
  257. package/dist/internal/components/Switch.js +1 -1
  258. package/dist/internal/components/Table.js +1 -1
  259. package/dist/internal/components/Tabs.js +1 -1
  260. package/dist/internal/components/ThemeProvider.js +3 -3
  261. package/dist/internal/components/TimePicker.js +1 -1
  262. package/dist/internal/components/Timeline.js +1 -1
  263. package/dist/internal/components/Toast.js +2 -2
  264. package/dist/internal/components/Tooltip.js +2 -2
  265. package/dist/internal/components/Truncated.js +4 -8
  266. package/dist/internal/components/Truncated.js.map +1 -1
  267. package/dist/internal/components/Workbench.js +1 -1
  268. package/dist/internal/components/ZoomableSvg.js +1 -1
  269. package/dist/internal/hooks/useScrollbarPosition.js +1 -1
  270. package/dist/internal/hooks/useStableCallback.js +4 -13
  271. package/dist/internal/hooks/useStableCallback.js.map +1 -1
  272. package/dist/internal/utils/mergeRefs.js +27 -9
  273. package/dist/internal/utils/mergeRefs.js.map +1 -1
  274. package/dist/internal/utils.js +3 -3
  275. package/dist/markdown-editor.d.ts +15 -37
  276. package/dist/markdown-editor.js +17 -23
  277. package/dist/markdown-editor.js.map +1 -1
  278. package/dist/mermaid.d.ts +4 -6
  279. package/dist/mermaid.js +1 -1
  280. package/dist/rjsf.d.ts +9 -19
  281. package/dist/rjsf.js +44 -84
  282. package/dist/rjsf.js.map +1 -1
  283. package/dist/{styles-BAFscjSV.js → styles-gzcjOyKv.js} +6 -6
  284. package/dist/styles-gzcjOyKv.js.map +1 -0
  285. package/dist/styles.css +1 -1
  286. package/dist/svgTransforms-Dw2hRA-i.js +51 -0
  287. package/dist/svgTransforms-Dw2hRA-i.js.map +1 -0
  288. package/dist/testing.d.ts +3 -10
  289. package/dist/testing.js +5 -12
  290. package/dist/testing.js.map +1 -1
  291. package/dist/themeTokens-7DEab0kp.js +31 -0
  292. package/dist/themeTokens-7DEab0kp.js.map +1 -0
  293. package/dist/{toast-DIC0iNRf.js → toast-CyXEdaCZ.js} +3 -3
  294. package/dist/toast-CyXEdaCZ.js.map +1 -0
  295. package/dist/{themeScopeContext-D7fSyb06.js → useColorSchemeState-Cw4MCXUs.js} +14 -14
  296. package/dist/useColorSchemeState-Cw4MCXUs.js.map +1 -0
  297. package/dist/{useControllableState-M6494mCT.js → useControllableState-CUYXMsfz.js} +3 -7
  298. package/dist/useControllableState-CUYXMsfz.js.map +1 -0
  299. package/dist/useElement-D-RjrGa4.js +21 -0
  300. package/dist/useElement-D-RjrGa4.js.map +1 -0
  301. package/dist/useThemeAttributes-B199Regy.js +67 -0
  302. package/dist/useThemeAttributes-B199Regy.js.map +1 -0
  303. package/dist/{utils-DnkrFYqY.js → utils-Bd28bWgm.js} +53 -20
  304. package/dist/utils-Bd28bWgm.js.map +1 -0
  305. package/dist/vega.d.ts +8 -30
  306. package/dist/vega.js +5 -13
  307. package/dist/vega.js.map +1 -1
  308. package/dist/{vegaTheme-CSvFEMBl.js → vegaTheme-VQMWTlBw.js} +7 -21
  309. package/dist/vegaTheme-VQMWTlBw.js.map +1 -0
  310. package/package.json +11 -9
  311. package/src/styles.css +120 -14
  312. package/src/theme.css +126 -6
  313. package/dist/AIKit-CQxVwyAk.js.map +0 -1
  314. package/dist/Alert-C4Y9IwMI.js.map +0 -1
  315. package/dist/AlertModal-BGJdaRRj.js.map +0 -1
  316. package/dist/AppShell-DRgJxpXW.js.map +0 -1
  317. package/dist/Badge-o5jURtpB.js.map +0 -1
  318. package/dist/BrandLogo-CoKBk4MI.js.map +0 -1
  319. package/dist/Breadcrumb-D1id7YXd.js.map +0 -1
  320. package/dist/Button-DsRrU5F1.js.map +0 -1
  321. package/dist/Calendar-cG5NIJ4O.js.map +0 -1
  322. package/dist/Card-Dyo7055Q.js.map +0 -1
  323. package/dist/Checkbox-Bqr6zXcW.js.map +0 -1
  324. package/dist/CodeEditor-C9AS8Ch0.js.map +0 -1
  325. package/dist/ColorInput-Dg87lKcR.js.map +0 -1
  326. package/dist/ColorModeSwitch-CsWLiTBX.js.map +0 -1
  327. package/dist/Combobox-BfanUAqY.js +0 -619
  328. package/dist/Combobox-BfanUAqY.js.map +0 -1
  329. package/dist/DateRangeInput-9MIw7P6L.js.map +0 -1
  330. package/dist/DateRangePicker-DjSUFjh4.js.map +0 -1
  331. package/dist/DropdownMenu-CASr-jgl.js.map +0 -1
  332. package/dist/FieldItem-DtPTzNef.js.map +0 -1
  333. package/dist/FormGroup-Bl8JmnzJ.js.map +0 -1
  334. package/dist/FullScreenModal-CN9nAs72.js.map +0 -1
  335. package/dist/InputGroup-DcZRlVnN.js.map +0 -1
  336. package/dist/Kbd-D1Azcc4g.js.map +0 -1
  337. package/dist/MermaidDiagram-CujFxVzk.js.map +0 -1
  338. package/dist/Modal-Coj-H02o.js.map +0 -1
  339. package/dist/ModalTitle-C76ke2eo.js.map +0 -1
  340. package/dist/PageHeader-Q3IpCnQd.js.map +0 -1
  341. package/dist/PageLayout-DSVM-ASz.js.map +0 -1
  342. package/dist/PageToolbar-BKVJiDAL.js.map +0 -1
  343. package/dist/Popover-BEbQrC_P.js.map +0 -1
  344. package/dist/SearchInput-Q85p8Ews.js.map +0 -1
  345. package/dist/SectionNav-mpmSM3OC.js.map +0 -1
  346. package/dist/Sheet-Chf0kX1E.js.map +0 -1
  347. package/dist/Sidebar-CTWsHZhF.js.map +0 -1
  348. package/dist/TextInput-DiEMxVF6.js.map +0 -1
  349. package/dist/ThemeProvider-BI6JWBdJ.js.map +0 -1
  350. package/dist/ZoomableSvg-U_VH3QRO.js.map +0 -1
  351. package/dist/context-D7X470dy.js.map +0 -1
  352. package/dist/findLiteralMatches-BGBw8Vbl.js.map +0 -1
  353. package/dist/icons-Cek151jC.js.map +0 -1
  354. package/dist/styles-BAFscjSV.js.map +0 -1
  355. package/dist/svgTransforms-CJAYPk7o.js +0 -81
  356. package/dist/svgTransforms-CJAYPk7o.js.map +0 -1
  357. package/dist/themeScopeContext-D7fSyb06.js.map +0 -1
  358. package/dist/themeTokens-qP1-55O7.js +0 -119
  359. package/dist/themeTokens-qP1-55O7.js.map +0 -1
  360. package/dist/toast-DIC0iNRf.js.map +0 -1
  361. package/dist/useControllableState-M6494mCT.js.map +0 -1
  362. package/dist/useElement-DkF6esWL.js +0 -15
  363. package/dist/useElement-DkF6esWL.js.map +0 -1
  364. package/dist/utils-DnkrFYqY.js.map +0 -1
  365. package/dist/vegaTheme-CSvFEMBl.js.map +0 -1
@@ -1,66 +1,38 @@
1
- import { useArgoDesign } from "../../context-D7X470dy.js";
2
- import { ChevronDown, Plus, X } from "../../icons-Cek151jC.js";
3
- import { InputGroup } from "../../InputGroup-DcZRlVnN.js";
4
- import { Combobox as Combobox$1, createCreatableItem, defaultGroupToLabel, defaultItemToDisabled, defaultItemToIcon, defaultItemToLabel, defaultQueryToCreateLabel, defaultToCreateValue, isCreatableItem, isGroupItem, isGroupItems, isSelectAllItem, namedLabel, sanitizeTypedInput, selectAllItem, toItemEquality, toLabel, useQueryReporter } from "../../Combobox-BfanUAqY.js";
5
- import { Fragment, useMemo, useState } from "react";
1
+ import { splitEntry } from "../../utils-Bd28bWgm.js";
2
+ import { useArgoDesign } from "../../context-U293r3v-.js";
3
+ import { useControllableState } from "../../useControllableState-CUYXMsfz.js";
4
+ import { Combobox as Combobox$1, ComboboxClearButton, ComboboxOpenButton, ComboboxOptions, createCreatableItem, defaultGroupToLabel, defaultItemToDisabled, defaultItemToIcon, defaultQueryToCreateLabel, defaultRowLabel, defaultToCreateValue, flatItems, isCreatableItem, isGroupHeaderItem, isSelectAllItem, sanitizeTypedInput, selectAllItem, toEntries, toLabel, useCreatableStringValue, useGroupHeaders, useItemEquality, useQueryReporter, useVirtualList, useWithCreated } from "../../Combobox-CxRAYOBt.js";
5
+ import { useCallback, useMemo, useState } from "react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
7
7
  import { Combobox } from "@base-ui/react/combobox";
8
8
  //#region src/blocks/MultiCombobox/MultiCombobox.tsx
9
+ /** Joins the create row's values with the entry's separator; a `RegExp` uses the default one. */
10
+ const joinCreateParts = (parts, separator) => parts.join(`${typeof separator === "string" ? separator : ","} `);
11
+ const NO_ITEMS = [];
12
+ const NO_VALUES = [];
9
13
  /**
10
- * The strings one creatable entry stands for.
14
+ * Searchable multi-select with chips, built on Base UI Combobox.
11
15
  *
12
- * - `id1, id2,` is two values: the blanks a stray separator leaves are dropped.
13
- * - A repeat collapses to its first occurrence, case-insensitively, as everything the control
14
- * matches by display string does — one entry cannot add the same value twice.
15
- * - A `null` separator yields the entry itself.
16
+ * @see RECIPES.md#creatable-multi-combobox
17
+ * @see RECIPES.md#filter-toolbar
16
18
  */
17
- const DEFAULT_CREATE_SEPARATOR = ",";
18
- /**
19
- * How the create row lists the values it adds: each separated by the entry's own separator, then
20
- * a space. A `RegExp` stands for many strings, so the default separator stands in for it.
21
- */
22
- const joinCreateParts = (parts, separator) => parts.join(`${typeof separator === "string" ? separator : DEFAULT_CREATE_SEPARATOR} `);
23
- const splitCreateEntry = (entry, separator) => {
24
- if (separator === null) return [entry];
25
- const seen = /* @__PURE__ */ new Set();
26
- return entry.split(separator).map((part) => part.trim()).filter((part) => {
27
- if (part === "") return false;
28
- const key = part.toLowerCase();
29
- if (seen.has(key)) return false;
30
- seen.add(key);
31
- return true;
19
+ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onValueChange, itemToStringLabel, itemToStringValue, disabled, filter: filterProp, isItemEqualToValue: isItemEqualToValueProp, inputRef, variant, sizing, focusVariant, state, placeholder, allowClear = true, id, name, onBlur, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, className, allowSelectAll = false, empty = "No items", isLoading = false, indicator, virtualized = false, inputValueSanitizer, onQueryChange, allowCreate, canCreate, queryToCreateValue, queryToCreateLabel = defaultQueryToCreateLabel, createSeparator = ",", itemToDisabled = defaultItemToDisabled, itemToLabel: itemToLabelProp, itemToIcon = defaultItemToIcon, groupToLabel = defaultGroupToLabel, collapsibleGroups = false, selectableGroups = false, itemToChipLabel, itemToChipColor, pinnedChipLabels, renderChips, maxVisible = 3 }) => {
20
+ const itemsProp = _itemsProp ?? NO_ITEMS;
21
+ const [valueProp, setValueProp] = useControllableState({
22
+ prop: _valueProp === null ? NO_VALUES : _valueProp,
23
+ defaultProp: defaultValue ?? NO_VALUES
32
24
  });
33
- };
34
- /**
35
- * Multi-selection combobox with chip display and search. Built on Base UI Combobox.
36
- *
37
- * **When to use:** picking several items from a searchable enumerated list (filter by tags, assign labels).
38
- * Items render as chips above the input; `maxVisible` collapses excess into a `+N more` chip.
39
- * **When NOT to use:** for single selection use `Combobox`; for short enums without search use `Select`.
40
- * **Composition:** wrap in `FormGroup` for label + help text, or use `useAppForm` for form integration.
41
- * Pass `allowSelectAll` for a "Select All" item when the full enum is small — it covers the whole set
42
- * and hides itself while a query is active. Pass `allowCreate` to let the user add free-form values
43
- * that are not in `items` (e.g. entering column names by hand).
44
- *
45
- * @see RECIPES.md#creatable-multi-combobox — for free-form-plus-enumerated patterns
46
- * @see RECIPES.md#filter-toolbar — for combining multi-select with other filter chips
47
- */
48
- const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onValueChange, itemToStringLabel, itemToStringValue, disabled, filter: filterProp, isItemEqualToValue: isItemEqualToValueProp, inputRef, variant, sizing, focusVariant, state, placeholder, allowClear = true, id, name, onBlur, "aria-describedby": ariaDescribedBy, "aria-invalid": ariaInvalid, "aria-required": ariaRequired, className, allowSelectAll = false, empty = "No items", indicator, inputValueSanitizer, onQueryChange, allowCreate, canCreate, queryToCreateValue, queryToCreateLabel = defaultQueryToCreateLabel, createSeparator = DEFAULT_CREATE_SEPARATOR, itemToDisabled = defaultItemToDisabled, itemToLabel: itemToLabelProp, itemToIcon = defaultItemToIcon, groupToLabel = defaultGroupToLabel, itemToChipLabel, itemToChipColor, pinnedChipLabels, renderChips, maxVisible = 3 }) => {
49
- const itemsProp = _itemsProp ?? [];
50
- const valueProp = _valueProp ?? [];
51
- const itemToLabel = itemToLabelProp ?? (itemToStringLabel ? (item) => namedLabel(itemToStringLabel(item)) : defaultItemToLabel);
25
+ const itemToString = useCallback((item) => itemToStringLabel?.(item) ?? toLabel(item), [itemToStringLabel]);
26
+ const itemToLabel = itemToLabelProp ?? defaultRowLabel(itemToStringLabel);
52
27
  const chipVariant = useArgoDesign() ? "pill" : "default";
53
28
  const [inputValue, setInputValue] = useState("");
54
29
  const [createdItems, setCreatedItems] = useState([]);
55
30
  const query = inputValue.trim();
56
31
  useQueryReporter(query, onQueryChange);
57
- const ownsInput = Boolean(allowCreate || inputValueSanitizer || onQueryChange);
58
- const baseItems = (() => {
59
- if (createdItems.length === 0) return itemsProp;
60
- if (isGroupItems(itemsProp)) return [...itemsProp, { items: createdItems }];
61
- return [...itemsProp, ...createdItems];
62
- })();
63
- const allFlatItems = baseItems.flatMap((item) => isGroupItem(item) ? item.items : item);
32
+ const busy = isLoading || void 0;
33
+ const ownsInput = Boolean(allowCreate || inputValueSanitizer || onQueryChange || itemToLabelProp || collapsibleGroups || selectableGroups);
34
+ const baseItems = useWithCreated(itemsProp, createdItems);
35
+ const allFlatItems = flatItems(baseItems);
64
36
  const sampleItem = allFlatItems[0];
65
37
  const hasSelectAllRow = allowSelectAll && allFlatItems.length > 0;
66
38
  const isAllSelected = hasSelectAllRow && allFlatItems.length === (valueProp?.length ?? 0);
@@ -68,24 +40,44 @@ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onV
68
40
  multiple: true,
69
41
  value: valueProp
70
42
  });
71
- const itemsWithSelectAllItem = hasSelectAllRow ? [selectAllItem, ...baseItems] : baseItems;
72
- const itemToString = (item) => itemToStringLabel?.(item) ?? toLabel(item);
43
+ const wrappedItemToStringLabel = useMemo(() => {
44
+ if (!allowCreate && !collapsibleGroups && !selectableGroups) return itemToStringLabel && itemToString;
45
+ return (item) => {
46
+ if (isCreatableItem(item)) return item.value;
47
+ if (isGroupHeaderItem(item)) return item.label;
48
+ return itemToString(item);
49
+ };
50
+ }, [
51
+ allowCreate,
52
+ collapsibleGroups,
53
+ selectableGroups,
54
+ itemToStringLabel,
55
+ itemToString
56
+ ]);
57
+ const itemFilter = filterProp ?? defaultFilter.contains;
58
+ const isItemEqualToValue = useItemEquality(isItemEqualToValueProp);
59
+ const groupHeaders = useGroupHeaders({
60
+ items: itemsProp,
61
+ collapsible: collapsibleGroups,
62
+ selectable: selectableGroups,
63
+ query,
64
+ matches: (item) => itemFilter(item, query, wrappedItemToStringLabel),
65
+ isItemEqualToValue
66
+ });
67
+ const listItems = useWithCreated(groupHeaders.items, createdItems);
68
+ const virtualList = useVirtualList(baseItems, virtualized);
73
69
  const labelKey = (item) => itemToString(item).toLowerCase();
74
- const createParts = !allowCreate || disabled || !query ? [] : splitCreateEntry(query, createSeparator);
70
+ const createParts = !allowCreate || disabled || !query ? [] : splitEntry(query, createSeparator);
75
71
  const selectedKeys = /* @__PURE__ */ new Set();
76
72
  if (createParts.length > 0) for (const item of valueProp) selectedKeys.add(labelKey(item));
77
73
  const itemKeys = /* @__PURE__ */ new Set();
78
74
  if (createParts.length > 0 && canCreate) for (const item of allFlatItems) itemKeys.add(labelKey(item));
79
75
  const namesAnItem = (key) => canCreate ? itemKeys.has(key) : allFlatItems.some((item) => labelKey(item) === key);
80
76
  /**
81
- * What the entry adds to the selection: its values the selection does not already hold.
77
+ * The entry's values not yet selected, minus those `canCreate` rejects.
82
78
  *
83
- * - The create row is named from this and committing it adds exactly this, so the row cannot
84
- * promise something else. A value naming an existing item counts — committing selects it.
85
- * - `canCreate` drops a value the control would mint and the gate rejects. One naming an item
86
- * is selected rather than minted, so its format is not that gate's business.
87
- * - `value` is the whole selection (it is never `undefined`, so the control is always the
88
- * controlled one), which is why the commit path re-derives nothing.
79
+ * - Both names the create row and is exactly what committing it adds.
80
+ * - A value naming an existing item counts and bypasses `canCreate` — committing selects it.
89
81
  */
90
82
  const addedCreateParts = createParts.filter((part) => {
91
83
  const key = part.toLowerCase();
@@ -94,34 +86,59 @@ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onV
94
86
  });
95
87
  const soleValueKey = createParts.length === 1 ? createParts[0].toLowerCase() : void 0;
96
88
  const showCreateRow = addedCreateParts.length > 0 && (soleValueKey === void 0 || !namesAnItem(soleValueKey));
97
- const items = (() => {
98
- const base = itemsWithSelectAllItem;
99
- if (!showCreateRow) return base;
100
- const creatable = createCreatableItem(query);
101
- return isGroupItems(base) ? [...base, { items: [creatable] }] : [...base, creatable];
102
- })();
103
- const filter = (item, query, itemToString) => {
89
+ const items = useMemo(() => {
90
+ const withSelectAll = hasSelectAllRow ? [...toEntries(listItems, [selectAllItem]), ...listItems] : listItems;
91
+ return showCreateRow ? [...withSelectAll, ...toEntries(listItems, [createCreatableItem(query)])] : withSelectAll;
92
+ }, [
93
+ hasSelectAllRow,
94
+ showCreateRow,
95
+ listItems,
96
+ query
97
+ ]);
98
+ const filterHeader = groupHeaders.enabled ? groupHeaders.filterHeader : void 0;
99
+ const filter = useCallback((item, query, itemToString) => {
104
100
  if (isSelectAllItem(item)) return query.trim() === "";
105
101
  if (isCreatableItem(item)) return true;
106
- if (filterProp) return filterProp(item, query, itemToString);
107
- return defaultFilter.contains(item, query, itemToString);
108
- };
109
- const isItemEqualToValue = useMemo(() => toItemEquality(isItemEqualToValueProp), [isItemEqualToValueProp]);
110
- const wrappedItemToStringLabel = !allowCreate ? itemToStringLabel : (item) => isCreatableItem(item) ? item.value : itemToString(item);
111
- const wrappedItemToStringValue = !allowCreate || !itemToStringValue ? itemToStringValue : (item) => isCreatableItem(item) ? item.value : itemToStringValue(item);
102
+ return filterHeader?.(item) ?? itemFilter(item, query, itemToString);
103
+ }, [filterHeader, itemFilter]);
104
+ const wrappedItemToStringValue = useCreatableStringValue(itemToStringValue, allowCreate);
112
105
  const value = isAllSelected ? [...valueProp, selectAllItem] : valueProp;
106
+ const selectedSet = selectableGroups && !isItemEqualToValueProp ? new Set(valueProp) : void 0;
107
+ const isSelected = (item) => selectedSet?.has(item) ?? valueProp.some((selected) => isItemEqualToValue(item, selected));
108
+ /** What a group's row selects: the group's items the query matches, the disabled aside. */
109
+ const groupTargets = (row) => groupHeaders.headerOf(row)?.matching.filter((item) => !itemToDisabled(item)) ?? [];
110
+ /**
111
+ * Replaces a pressed group row in `next` with its items.
112
+ *
113
+ * - Base UI adds the row to `value` like any unselected item.
114
+ * - A row whose items are all selected deselects them.
115
+ */
116
+ const selectGroupRow = (next) => {
117
+ const row = next.find(isGroupHeaderItem);
118
+ if (row === void 0) return next;
119
+ const rest = next.filter((item) => item !== row);
120
+ const targets = groupTargets(row);
121
+ if (!targets.every(isSelected)) return [...rest, ...targets.filter((item) => !isSelected(item))];
122
+ return rest.filter((item) => !targets.some((target) => isItemEqualToValue(target, item)));
123
+ };
124
+ const groupRowChecked = (targets) => {
125
+ const selectedCount = targets.filter(isSelected).length;
126
+ if (selectedCount === 0) return false;
127
+ return selectedCount === targets.length ? true : "mixed";
128
+ };
113
129
  const handleInputValueChange = (next, { reason }) => {
114
130
  setInputValue(sanitizeTypedInput(next, reason, inputValueSanitizer));
115
131
  };
116
132
  const handleValueChange = (next, event) => {
117
133
  if (ownsInput) setInputValue((prev) => prev === "" ? prev : "");
118
- if (!onValueChange) return;
134
+ if (!onValueChange && _valueProp !== void 0) return;
135
+ const picked = selectGroupRow(next);
119
136
  const created = [];
120
137
  const converted = (() => {
121
- if (!allowCreate || !next.some(isCreatableItem)) return next;
138
+ if (!allowCreate || !picked.some(isCreatableItem)) return picked;
122
139
  const itemsByLabel = /* @__PURE__ */ new Map();
123
140
  for (const item of allFlatItems) itemsByLabel.set(labelKey(item), item);
124
- return next.flatMap((item) => {
141
+ return picked.flatMap((item) => {
125
142
  if (!isCreatableItem(item)) return [item];
126
143
  return addedCreateParts.map((part) => {
127
144
  const existing = itemsByLabel.get(part.toLowerCase());
@@ -142,39 +159,23 @@ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onV
142
159
  const selected = new Set(newValue.map(itemToString));
143
160
  setCreatedItems((prev) => [...prev, ...created].filter((item) => selected.has(itemToString(item))));
144
161
  }
145
- onValueChange(newValue, event);
146
- };
147
- /**
148
- * The create row.
149
- *
150
- * - `queryToCreateLabel` receives the values committing the row adds, rather than the entry as
151
- * typed — so the row cannot name a value it drops as a stray separator, a repeat, or one the
152
- * selection already holds, nor stay silent about one it selects from `items`.
153
- * - For an entry standing for a single value that string is the entry itself.
154
- */
155
- const renderCreatableItem = (item) => /* @__PURE__ */ jsx(Combobox$1.Item, {
156
- value: item,
157
- icon: /* @__PURE__ */ jsx(Plus, {}),
158
- children: queryToCreateLabel(joinCreateParts(addedCreateParts, createSeparator))
159
- });
160
- const renderItem = (item) => {
161
- return /* @__PURE__ */ jsx(Combobox$1.Item, {
162
- value: item,
163
- indicator,
164
- icon: itemToIcon(item),
165
- disabled: itemToDisabled(item),
166
- children: itemToLabel(item)
167
- });
162
+ setValueProp(newValue);
163
+ onValueChange?.(newValue, event);
168
164
  };
169
165
  return /* @__PURE__ */ jsxs(Combobox$1.Root, {
170
166
  multiple: true,
171
167
  autoHighlight: true,
172
168
  items,
173
169
  value,
174
- defaultValue,
175
170
  filter,
176
171
  isItemEqualToValue,
177
172
  onValueChange: handleValueChange,
173
+ onOpenChange: groupHeaders.onOpenChange,
174
+ onItemHighlighted: (item, details) => {
175
+ groupHeaders.onItemHighlighted(item);
176
+ virtualList.onItemHighlighted(details);
177
+ },
178
+ virtualized: virtualList.enabled,
178
179
  itemToStringLabel: wrappedItemToStringLabel,
179
180
  itemToStringValue: wrappedItemToStringValue,
180
181
  disabled,
@@ -183,71 +184,67 @@ const MultiCombobox = ({ items: _itemsProp, value: _valueProp, defaultValue, onV
183
184
  inputValue,
184
185
  onInputValueChange: handleInputValueChange
185
186
  } : {},
186
- children: [/* @__PURE__ */ jsx(Combobox.Chips, {
187
- render: /* @__PURE__ */ jsx(Fragment, {}),
188
- children: /* @__PURE__ */ jsx(Combobox$1.InputGroup, {
189
- variant,
190
- sizing,
191
- state,
192
- focusVariant,
193
- className,
194
- children: /* @__PURE__ */ jsxs("div", {
195
- className: "tw:flex tw:min-w-0 tw:flex-1 tw:flex-wrap tw:items-center tw:gap-1.5 tw:px-4 tw:py-1.5",
196
- children: [/* @__PURE__ */ jsx(Combobox$1.Chips, {
197
- maxVisible,
198
- variant: chipVariant,
199
- itemToChipLabel: itemToChipLabel ?? itemToLabel,
200
- itemToChipColor,
201
- pinnedChipLabels,
202
- children: renderChips
203
- }), /* @__PURE__ */ jsxs("div", {
204
- className: "tw:flex tw:flex-1 tw:items-center tw:gap-1",
205
- children: [
206
- /* @__PURE__ */ jsx(Combobox$1.Input, {
207
- id,
208
- name,
209
- onBlur,
210
- "aria-describedby": ariaDescribedBy,
211
- "aria-invalid": ariaInvalid,
212
- "aria-required": ariaRequired,
213
- placeholder,
214
- disabled,
215
- className: "tw:w-auto tw:min-w-[120px] tw:flex-1 tw:!px-0 tw:!py-0"
216
- }),
217
- allowClear && /* @__PURE__ */ jsx(InputGroup.Button, {
218
- asChild: true,
219
- "aria-label": "Clear",
220
- disabled,
221
- children: /* @__PURE__ */ jsx(Combobox.Clear, { children: /* @__PURE__ */ jsx(X, { className: "tw:size-4" }) })
222
- }),
223
- /* @__PURE__ */ jsx(InputGroup.Button, {
224
- disabled,
225
- asChild: true,
226
- "aria-label": "Open combobox",
227
- children: /* @__PURE__ */ jsx(Combobox.Trigger, { children: /* @__PURE__ */ jsx(ChevronDown, { className: "tw:size-4" }) })
228
- })
229
- ]
230
- })]
231
- })
187
+ children: [/* @__PURE__ */ jsx(Combobox$1.InputGroup, {
188
+ variant,
189
+ sizing,
190
+ state,
191
+ focusVariant,
192
+ className,
193
+ children: /* @__PURE__ */ jsxs(Combobox.Chips, {
194
+ className: "tw:flex tw:min-w-0 tw:flex-1 tw:flex-wrap tw:items-center tw:gap-1.5 tw:px-4 tw:py-1.5",
195
+ children: [/* @__PURE__ */ jsx(Combobox$1.Chips, {
196
+ maxVisible,
197
+ variant: chipVariant,
198
+ itemToChipLabel: itemToChipLabel ?? ((item) => itemToLabel(item, "")),
199
+ itemToChipColor,
200
+ pinnedChipLabels,
201
+ children: renderChips
202
+ }), /* @__PURE__ */ jsxs("div", {
203
+ className: "tw:flex tw:min-w-0 tw:grow tw:items-center tw:gap-1",
204
+ children: [
205
+ /* @__PURE__ */ jsx(Combobox$1.Input, {
206
+ id,
207
+ name,
208
+ onBlur,
209
+ "aria-label": ariaLabel,
210
+ "aria-labelledby": ariaLabelledBy,
211
+ "aria-describedby": ariaDescribedBy,
212
+ "aria-invalid": ariaInvalid,
213
+ "aria-required": ariaRequired,
214
+ "aria-busy": busy,
215
+ placeholder,
216
+ disabled,
217
+ onKeyDown: groupHeaders.onInputKeyDown,
218
+ className: "tw:w-auto tw:min-w-0 tw:grow tw:basis-[120px] tw:!px-0 tw:!py-0"
219
+ }),
220
+ allowClear && /* @__PURE__ */ jsx(ComboboxClearButton, { disabled }),
221
+ /* @__PURE__ */ jsx(ComboboxOpenButton, {
222
+ disabled,
223
+ isLoading
224
+ })
225
+ ]
226
+ })]
232
227
  })
233
- }), /* @__PURE__ */ jsxs(Combobox$1.Content, { children: [/* @__PURE__ */ jsx(Combobox$1.Empty, { children: empty }), /* @__PURE__ */ jsx(Combobox$1.List, { children: (itemOrGroup) => {
234
- if (isSelectAllItem(itemOrGroup)) return /* @__PURE__ */ jsx(Combobox$1.Item, {
235
- value: itemOrGroup,
236
- indicator: "checkbox",
237
- children: itemOrGroup.label
238
- });
239
- if (isCreatableItem(itemOrGroup)) return renderCreatableItem(itemOrGroup);
240
- if (isGroupItem(itemOrGroup)) {
241
- const maybeCreatable = itemOrGroup.items[0];
242
- if (isCreatableItem(maybeCreatable)) return renderCreatableItem(maybeCreatable);
243
- const groupLabel = groupToLabel(itemOrGroup);
244
- return /* @__PURE__ */ jsxs(Combobox$1.Group, {
245
- items: itemOrGroup.items,
246
- children: [groupLabel && /* @__PURE__ */ jsx(Combobox$1.GroupLabel, { children: groupLabel }), /* @__PURE__ */ jsx(Combobox$1.GroupList, { children: renderItem })]
247
- });
248
- }
249
- return renderItem(itemOrGroup);
250
- } })] })]
228
+ }), /* @__PURE__ */ jsx(Combobox$1.Content, { children: /* @__PURE__ */ jsx(ComboboxOptions, {
229
+ isLoading,
230
+ empty,
231
+ virtualized: virtualList.enabled,
232
+ listRef: virtualList.ref,
233
+ groupHeaders,
234
+ groupToLabel,
235
+ indicator,
236
+ itemToLabel: (item) => itemToLabel(item, query),
237
+ itemToIcon,
238
+ itemToDisabled,
239
+ createLabel: () => queryToCreateLabel(joinCreateParts(addedCreateParts, createSeparator)),
240
+ groupRowState: selectableGroups ? (row) => {
241
+ const targets = groupTargets(row);
242
+ return {
243
+ checked: groupRowChecked(targets),
244
+ disabled: targets.length === 0
245
+ };
246
+ } : void 0
247
+ }) })]
251
248
  });
252
249
  };
253
250
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"MultiCombobox.js","names":["BaseCombobox","Combobox"],"sources":["../../../src/blocks/MultiCombobox/MultiCombobox.tsx"],"sourcesContent":["import { type ComponentProps, Fragment, type ReactNode, useMemo, useState } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { Combobox } from '../../components/Combobox';\nimport { namedLabel } from '../../components/Combobox/blankValues';\nimport { sanitizeTypedInput, useQueryReporter } from '../../components/Combobox/query';\nimport type { CreatableItem, Group } from '../../components/Combobox/types';\nimport {\n createCreatableItem,\n defaultGroupToLabel,\n defaultItemToDisabled,\n defaultItemToIcon,\n defaultItemToLabel,\n defaultQueryToCreateLabel,\n defaultToCreateValue,\n isCreatableItem,\n isGroupItem,\n isGroupItems,\n isSelectAllItem,\n selectAllItem,\n toItemEquality,\n toLabel,\n} from '../../components/Combobox/utils';\nimport { InputGroup } from '../../components/InputGroup';\nimport { useArgoDesign } from '../../components/ThemeProvider/context';\nimport { ChevronDown, Plus, X } from '../../icons';\n\ntype ComboboxProps<Value> = BaseCombobox.Root.Props<Value, true>;\ntype ComboboxInputProps = ComponentProps<typeof Combobox.Input>;\ntype ComboboxInputGroupProps = ComponentProps<typeof Combobox.InputGroup>;\ntype ComboboxItemProps = ComponentProps<typeof Combobox.Item>;\ntype ComboboxChipsProps<Value> = ComponentProps<typeof Combobox.Chips<Value>>;\n\ntype Indicator = NonNullable<ComboboxItemProps['indicator']>;\n\n/**\n * The strings one creatable entry stands for.\n *\n * - `id1, id2,` is two values: the blanks a stray separator leaves are dropped.\n * - A repeat collapses to its first occurrence, case-insensitively, as everything the control\n * matches by display string does — one entry cannot add the same value twice.\n * - A `null` separator yields the entry itself.\n */\nconst DEFAULT_CREATE_SEPARATOR = ',';\n\n/**\n * How the create row lists the values it adds: each separated by the entry's own separator, then\n * a space. A `RegExp` stands for many strings, so the default separator stands in for it.\n */\nconst joinCreateParts = (parts: string[], separator: string | RegExp | null) =>\n parts.join(`${typeof separator === 'string' ? separator : DEFAULT_CREATE_SEPARATOR} `);\n\nconst splitCreateEntry = (entry: string, separator: string | RegExp | null): string[] => {\n if (separator === null) return [entry];\n\n const seen = new Set<string>();\n return entry\n .split(separator)\n .map((part) => part.trim())\n .filter((part) => {\n if (part === '') return false;\n const key = part.toLowerCase();\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n};\n\ntype CreatableProps<Value> = {\n allowCreate?: boolean;\n /**\n * Words the create row. Receives the values committing the row will add — an entry standing for\n * several values arrives trimmed and re-joined with its own separator, not as typed.\n */\n queryToCreateLabel?: (query: string) => ReactNode;\n /**\n * Projects one entered string into an item. Called once per value, so a split entry calls it\n * several times, each with an already-trimmed part.\n */\n queryToCreateValue?: (query: string) => Value;\n /**\n * Gate on each value the entry stands for, for `allowCreate`.\n *\n * - Returning `false` drops that value, so an entry left with none hides the create row and the\n * empty state shows instead.\n * - Only called for a value that matches no item and nothing already selected — one naming an\n * item is selected rather than minted, so its format is not this gate's business.\n * - Reach for it when a free-form value has a format (a column name, an email address).\n */\n canCreate?: (query: string) => boolean;\n /**\n * Separator that makes one creatable entry stand for several values. Defaults to **`','`**, so\n * pasting `id1, id2, id3` adds three chips.\n *\n * - Pass a string or a non-capturing `RegExp` for another convention: `';'` for an Outlook\n * address list, `/[\\s,]+/` where a value can never contain a space. A capture group would be\n * handed back as a value of its own — that is `String.prototype.split`'s own behaviour.\n * - Pass `null` where a value legitimately contains the separator — a free-text label, a\n * sentence — and one entry must stay one chip.\n * - Whitespace is deliberately not part of the default: tags and column names contain spaces,\n * and each part is trimmed anyway, so `id1, id2` needs nothing more than the comma.\n */\n createSeparator?: string | RegExp | null;\n};\n\n/**\n * Props for `MultiCombobox`. Generic over `Value` (the item shape) and `GroupShape` (optional group wrapper).\n * Use `itemToLabel` / `itemToIcon` / `itemToDisabled` to project custom item shapes; use `filter` to override\n * the default substring matcher. Pass `isItemEqualToValue` when the items are objects a store recreates —\n * without it Base UI matches `value` against `items` by reference. Pass `allowCreate` to let the user add\n * free-form values not in `items`.\n */\ntype Props<Value, GroupShape extends Group<Value> = Group<Value>> = Pick<\n ComboboxInputProps,\n // `name`, `onBlur` and the `aria-*` set are forwarded to the input so a form connector can hand\n // over the wiring it derives from the field — without the `aria-*` set the control cannot be linked\n // to its own help and error text, and without `onBlur` the field never registers as blurred, which\n // is the gate `FieldItem` reveals errors on.\n 'placeholder' | 'id' | 'name' | 'onBlur' | 'aria-describedby' | 'aria-invalid' | 'aria-required'\n> &\n Pick<ComboboxInputGroupProps, 'variant' | 'focusVariant' | 'sizing' | 'state' | 'className'> &\n Pick<\n ComboboxProps<Value>,\n | 'disabled'\n | 'inputRef'\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'itemToStringLabel'\n | 'itemToStringValue'\n | 'filter'\n | 'isItemEqualToValue'\n > &\n Pick<\n ComboboxChipsProps<Value>,\n 'itemToChipLabel' | 'itemToChipColor' | 'pinnedChipLabels' | 'maxVisible'\n > &\n CreatableProps<Value> & {\n items?: readonly (Value | GroupShape)[];\n\n // root specific\n /**\n * Offer a clear-all button once something is selected. Defaults to **`true`**.\n *\n * - `BaseCombobox.Clear` only mounts while chips exist, so an empty control renders identically\n * either way. Individual chips stay removable regardless.\n * - Pass `false` where emptying the whole selection must not be one click away.\n */\n allowClear?: boolean;\n /**\n * Adds a \"Select All\" row that selects the whole item set.\n *\n * - The row is hidden while a query narrows the list — it never means \"everything matching\".\n * - Selecting it while everything is already selected clears the selection.\n */\n allowSelectAll?: boolean;\n empty?: ReactNode;\n indicator?: Indicator;\n\n // query specific\n /**\n * Rewrites what the user types before the control adopts it.\n *\n * - The query the list filters by is the rewritten text, and so is every value a created entry\n * is split into — a character the user cannot type is one they cannot create.\n * - Reach for it where a created value has a character set: a column name, a scope, an\n * identifier. `canCreate` is the gate for a format the user must get right themselves.\n * - It has to rewrite rather than drop: it sees the whole text on every keystroke, so one\n * calling `trim()` swallows the space before the next word.\n */\n inputValueSanitizer?: (input: string) => string;\n /**\n * Reports the query the list filters by, `inputValueSanitizer` already applied.\n *\n * - For an owner that needs the query for itself: a server-side search, an option order, the\n * text a synthetic row is offered for. The mount render reports too, so a search driven by\n * this needs no first fetch of its own.\n * - Notification only, and deliberately not Base UI's own `onInputValueChange`: the control\n * keeps ownership of the text — a pick clears it — so there is no controlled `inputValue`\n * to hold in sync.\n */\n onQueryChange?: (query: string) => void;\n\n // item specific\n /**\n * The item's row in the list, and its chip unless `itemToChipLabel` overrides it.\n *\n * - Defaults to `itemToStringLabel`, so a control that projects its items — ids carrying the\n * selection, the label looked up beside them — states the projection once.\n * - Pass it separately only where the row is richer than the input's own text.\n */\n itemToLabel?: (item: Value) => ReactNode;\n itemToIcon?: (item: Value) => ReactNode;\n itemToDisabled?: (item: Value) => boolean;\n\n // chip specific\n /**\n * Renders the chip area from the selected values, in place of the default chips.\n *\n * - For the case no per-value accessor can express: one node standing for the whole selection\n * (\"3 tables selected\"), or a chip count that is not the value count.\n * - A chip that merely holds richer content — a link, an action of its own — needs no slot:\n * `itemToChipLabel` returns a `ReactNode` and the chip lets it take the keyboard.\n * - The chip props above go unused while this is set, `maxVisible` and its `+N` chip included.\n * - `Combobox.Chip` builds a removable chip.\n */\n renderChips?: (values: Value[]) => ReactNode;\n\n // group specific\n groupToLabel?: (group: GroupShape) => ReactNode;\n };\n\n/**\n * Multi-selection combobox with chip display and search. Built on Base UI Combobox.\n *\n * **When to use:** picking several items from a searchable enumerated list (filter by tags, assign labels).\n * Items render as chips above the input; `maxVisible` collapses excess into a `+N more` chip.\n * **When NOT to use:** for single selection use `Combobox`; for short enums without search use `Select`.\n * **Composition:** wrap in `FormGroup` for label + help text, or use `useAppForm` for form integration.\n * Pass `allowSelectAll` for a \"Select All\" item when the full enum is small — it covers the whole set\n * and hides itself while a query is active. Pass `allowCreate` to let the user add free-form values\n * that are not in `items` (e.g. entering column names by hand).\n *\n * @see RECIPES.md#creatable-multi-combobox — for free-form-plus-enumerated patterns\n * @see RECIPES.md#filter-toolbar — for combining multi-select with other filter chips\n */\nexport const MultiCombobox = <Value, GroupShape extends Group<Value> = Group<Value>>({\n // root props\n items: _itemsProp,\n value: _valueProp,\n defaultValue,\n onValueChange,\n itemToStringLabel,\n itemToStringValue,\n disabled,\n filter: filterProp,\n isItemEqualToValue: isItemEqualToValueProp,\n inputRef,\n\n // input props\n variant,\n sizing,\n focusVariant,\n state,\n placeholder,\n allowClear = true,\n id,\n name,\n onBlur,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n className,\n\n // own props\n allowSelectAll = false,\n empty = 'No items',\n indicator,\n\n // query\n inputValueSanitizer,\n onQueryChange,\n\n // creatable\n allowCreate,\n canCreate,\n queryToCreateValue,\n queryToCreateLabel = defaultQueryToCreateLabel,\n createSeparator = DEFAULT_CREATE_SEPARATOR,\n\n // own item props\n itemToDisabled = defaultItemToDisabled,\n itemToLabel: itemToLabelProp,\n itemToIcon = defaultItemToIcon,\n groupToLabel = defaultGroupToLabel,\n itemToChipLabel,\n itemToChipColor,\n pinnedChipLabels,\n renderChips,\n // Nothing chose 3: value editors override it to `Infinity` (a chip inside `+N` can be neither\n // read nor removed) and single-row filters to `1`. Changing it moves eleven call sites at once,\n // so it waits for a PR that can look at them.\n maxVisible = 3,\n}: Props<Value, GroupShape>) => {\n const itemsProp = _itemsProp ?? [];\n const valueProp = _valueProp ?? [];\n // `itemToStringLabel` is a projection, not a display accessor, so a blank it returns still needs\n // naming — rows and chips are where a blank value would otherwise render as nothing.\n const itemToLabel =\n itemToLabelProp ??\n (itemToStringLabel ? (item: Value) => namedLabel(itemToStringLabel(item)) : defaultItemToLabel);\n const renderArgo = useArgoDesign();\n const chipVariant = renderArgo ? 'pill' : 'default';\n\n const [inputValue, setInputValue] = useState('');\n const [createdItems, setCreatedItems] = useState<Value[]>([]);\n const query = inputValue.trim();\n\n useQueryReporter(query, onQueryChange);\n\n // Who holds the input's text. Base UI keeps it unless something here needs to read or rewrite\n // it, because taking it means re-rendering this component on every keystroke — a cost the many\n // controls that only pick from a list should not pay.\n const ownsInput = Boolean(allowCreate || inputValueSanitizer || onQueryChange);\n\n // Created values are appended to `items` so Base UI can keep resolving them (as chips and as\n // list options) once the query clears — otherwise a value that isn't in `items` gets dropped.\n // `handleValueChange` drops the ones the selection no longer holds, so this list tracks the\n // selection rather than every value ever typed.\n const baseItems = (() => {\n if (createdItems.length === 0) return itemsProp;\n if (isGroupItems(itemsProp))\n return [...itemsProp, { items: createdItems } as unknown as GroupShape];\n return [...itemsProp, ...createdItems];\n })();\n\n const allFlatItems = baseItems.flatMap((item) => (isGroupItem(item) ? item.items : item));\n const sampleItem = allFlatItems[0] as Value | undefined;\n // An empty item set has no Select All row: there is nothing to select all of, and reading\n // `0 === 0` as \"everything is selected\" would put the row's own entry into `value`.\n const hasSelectAllRow = allowSelectAll && allFlatItems.length > 0;\n const isAllSelected = hasSelectAllRow && allFlatItems.length === (valueProp?.length ?? 0);\n\n const defaultFilter = BaseCombobox.useFilter({\n multiple: true,\n value: valueProp,\n });\n\n const itemsWithSelectAllItem = hasSelectAllRow ? [selectAllItem, ...baseItems] : baseItems;\n\n const itemToString = (item: Value) => itemToStringLabel?.(item) ?? toLabel(item);\n // An item's display string, case-folded — the key an entered value is matched against.\n const labelKey = (item: Value) => itemToString(item).toLowerCase();\n\n // The values the current entry stands for. Everything the create row is decided from hangs off\n // this, so an empty entry costs a creatable control nothing.\n const createParts =\n !allowCreate || disabled || !query ? [] : splitCreateEntry(query, createSeparator);\n\n const selectedKeys = new Set<string>();\n if (createParts.length > 0) for (const item of valueProp) selectedKeys.add(labelKey(item));\n\n // Does an item carry this display string? `canCreate` asks it per value, so there it earns a\n // set; without the gate only a single-value entry asks, and an early-exiting scan is cheaper.\n const itemKeys = new Set<string>();\n if (createParts.length > 0 && canCreate) {\n for (const item of allFlatItems) itemKeys.add(labelKey(item));\n }\n const namesAnItem = (key: string) =>\n canCreate ? itemKeys.has(key) : allFlatItems.some((item) => labelKey(item) === key);\n\n /**\n * What the entry adds to the selection: its values the selection does not already hold.\n *\n * - The create row is named from this and committing it adds exactly this, so the row cannot\n * promise something else. A value naming an existing item counts — committing selects it.\n * - `canCreate` drops a value the control would mint and the gate rejects. One naming an item\n * is selected rather than minted, so its format is not that gate's business.\n * - `value` is the whole selection (it is never `undefined`, so the control is always the\n * controlled one), which is why the commit path re-derives nothing.\n */\n const addedCreateParts = createParts.filter((part) => {\n const key = part.toLowerCase();\n if (selectedKeys.has(key)) return false;\n return !canCreate || namesAnItem(key) || canCreate(part);\n });\n\n // The one value a single-value entry stands for, keyed — `undefined` for a split entry.\n const soleValueKey = createParts.length === 1 ? createParts[0]!.toLowerCase() : undefined;\n\n // A single value naming an item needs no create row: the list already offers that item's own\n // row, which the default substring filter matches for a single-value entry but not for a split\n // one. The item scan runs only for an entry that would otherwise show the row.\n const showCreateRow =\n addedCreateParts.length > 0 && (soleValueKey === undefined || !namesAnItem(soleValueKey));\n\n const items = (() => {\n const base = itemsWithSelectAllItem;\n if (!showCreateRow) return base;\n\n const creatable = createCreatableItem(query);\n return isGroupItems(base)\n ? [...base, { items: [creatable] } as unknown as GroupShape]\n : [...base, creatable as unknown as Value];\n })();\n\n const filter = (item: Value, query: string, itemToString?: (value: Value) => string) => {\n // Select All covers the whole item set, so it exists only while no query narrows the list.\n if (isSelectAllItem(item)) return query.trim() === '';\n // always offer the transient \"create\" option\n if (isCreatableItem(item)) return true;\n\n if (filterProp) return filterProp(item, query, itemToString);\n return defaultFilter.contains(item, query, itemToString);\n };\n\n // Base UI stores the comparer and lists it in an effect's deps, so a fresh identity per render\n // re-renders every option row and rescans the item list.\n const isItemEqualToValue = useMemo(\n () => toItemEquality(isItemEqualToValueProp),\n [isItemEqualToValueProp],\n );\n\n const wrappedItemToStringLabel: ComboboxProps<Value>['itemToStringLabel'] = !allowCreate\n ? itemToStringLabel\n : (item) => (isCreatableItem(item) ? item.value : itemToString(item));\n\n const wrappedItemToStringValue: ComboboxProps<Value>['itemToStringValue'] =\n !allowCreate || !itemToStringValue\n ? itemToStringValue\n : (item) => (isCreatableItem(item) ? item.value : itemToStringValue(item));\n\n const value = isAllSelected ? [...valueProp, selectAllItem as Value] : valueProp;\n\n const handleInputValueChange: NonNullable<ComboboxProps<Value>['onInputValueChange']> = (\n next,\n { reason },\n ) => {\n setInputValue(sanitizeTypedInput(next, reason, inputValueSanitizer));\n };\n\n const handleValueChange: ComboboxProps<Value>['onValueChange'] = (next, event) => {\n // Emptying the input once the selection changes is this component's job while it holds the\n // text; Base UI does it itself otherwise. React bails out when the text is already empty.\n if (ownsInput) setInputValue((prev) => (prev === '' ? prev : ''));\n if (!onValueChange) return;\n\n const created: Value[] = [];\n const converted = (() => {\n if (!allowCreate || !next.some(isCreatableItem)) return next;\n\n // Items by display string, so a value naming one selects it rather than minting a twin that\n // would be a second chip for one value. Built per commit — the render path only needs to\n // know whether a single value names an item.\n const itemsByLabel = new Map<string, Value>();\n for (const item of allFlatItems) itemsByLabel.set(labelKey(item), item);\n\n return next.flatMap((item) => {\n if (!isCreatableItem(item)) return [item];\n\n return addedCreateParts.map((part) => {\n const existing = itemsByLabel.get(part.toLowerCase());\n if (existing !== undefined) return existing;\n\n const value = defaultToCreateValue(part, sampleItem, queryToCreateValue) as Value;\n created.push(value);\n return value;\n });\n });\n })();\n\n const hasSelectAll = converted.some((item) => isSelectAllItem(item));\n const newValue = (() => {\n if (!hasSelectAllRow) return converted;\n if (!hasSelectAll) return isAllSelected ? [] : converted;\n return isAllSelected ? converted.filter((item) => !isSelectAllItem(item)) : allFlatItems;\n })();\n\n if (allowCreate) {\n // Keep only the created values the selection being emitted still holds — `valueProp` is the\n // selection before this change, so a value created right now is not in it yet.\n const selected = new Set(newValue.map(itemToString));\n setCreatedItems((prev) =>\n [...prev, ...created].filter((item) => selected.has(itemToString(item))),\n );\n }\n\n onValueChange(newValue, event);\n };\n\n /**\n * The create row.\n *\n * - `queryToCreateLabel` receives the values committing the row adds, rather than the entry as\n * typed — so the row cannot name a value it drops as a stray separator, a repeat, or one the\n * selection already holds, nor stay silent about one it selects from `items`.\n * - For an entry standing for a single value that string is the entry itself.\n */\n const renderCreatableItem = (item: CreatableItem) => (\n <Combobox.Item value={item} icon={<Plus />}>\n {queryToCreateLabel(joinCreateParts(addedCreateParts, createSeparator))}\n </Combobox.Item>\n );\n\n const renderItem = (item: Value) => {\n return (\n <Combobox.Item\n value={item}\n indicator={indicator}\n icon={itemToIcon(item)}\n disabled={itemToDisabled(item)}\n >\n {itemToLabel(item)}\n </Combobox.Item>\n );\n };\n\n return (\n <Combobox.Root<Value, true>\n multiple\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 items={items}\n value={value}\n defaultValue={defaultValue}\n filter={filter}\n isItemEqualToValue={isItemEqualToValue}\n onValueChange={handleValueChange}\n itemToStringLabel={wrappedItemToStringLabel}\n itemToStringValue={wrappedItemToStringValue}\n disabled={disabled}\n inputRef={inputRef}\n {...(ownsInput ? { inputValue, onInputValueChange: handleInputValueChange } : {})}\n >\n <BaseCombobox.Chips render={<Fragment />}>\n <Combobox.InputGroup\n variant={variant}\n sizing={sizing}\n state={state}\n focusVariant={focusVariant}\n className={className}\n >\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-wrap tw:items-center tw:gap-1.5 tw:px-4 tw:py-1.5\">\n <Combobox.Chips<Value>\n maxVisible={maxVisible}\n variant={chipVariant}\n itemToChipLabel={itemToChipLabel ?? itemToLabel}\n itemToChipColor={itemToChipColor}\n pinnedChipLabels={pinnedChipLabels}\n >\n {renderChips}\n </Combobox.Chips>\n <div className=\"tw:flex tw:flex-1 tw:items-center tw:gap-1\">\n <Combobox.Input\n id={id}\n name={name}\n onBlur={onBlur}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n aria-required={ariaRequired}\n placeholder={placeholder}\n disabled={disabled}\n // This row already owns its own edge padding above, and chips share the row with\n // the input rather than sitting outside it — cancel the group's own `&_input`\n // padding so it doesn't double up on top of this row's.\n className=\"tw:w-auto tw:min-w-[120px] tw:flex-1 tw:!px-0 tw:!py-0\"\n />\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 </div>\n </div>\n </Combobox.InputGroup>\n </BaseCombobox.Chips>\n <Combobox.Content>\n <Combobox.Empty>{empty}</Combobox.Empty>\n <Combobox.List>\n {(itemOrGroup: Value | GroupShape) => {\n if (isSelectAllItem(itemOrGroup)) {\n return (\n <Combobox.Item value={itemOrGroup} indicator=\"checkbox\">\n {itemOrGroup.label}\n </Combobox.Item>\n );\n }\n\n if (isCreatableItem(itemOrGroup)) {\n return renderCreatableItem(itemOrGroup);\n }\n\n if (isGroupItem(itemOrGroup)) {\n const maybeCreatable = itemOrGroup.items[0];\n\n if (isCreatableItem(maybeCreatable)) {\n return renderCreatableItem(maybeCreatable);\n }\n\n const groupLabel = groupToLabel(itemOrGroup);\n return (\n <Combobox.Group items={itemOrGroup.items}>\n {groupLabel && <Combobox.GroupLabel>{groupLabel}</Combobox.GroupLabel>}\n <Combobox.GroupList>{renderItem}</Combobox.GroupList>\n </Combobox.Group>\n );\n }\n\n return renderItem(itemOrGroup);\n }}\n </Combobox.List>\n </Combobox.Content>\n </Combobox.Root>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"MultiCombobox.js","names":["BaseCombobox","Combobox"],"sources":["../../../src/blocks/MultiCombobox/MultiCombobox.tsx"],"sourcesContent":["import { type ComponentProps, type ReactNode, useCallback, useMemo, useState } from 'react';\nimport { Combobox as BaseCombobox } from '@base-ui/react/combobox';\n\nimport { Combobox } from '../../components/Combobox';\nimport { ComboboxClearButton } from '../../components/Combobox/ComboboxClearButton';\nimport { ComboboxOpenButton } from '../../components/Combobox/ComboboxOpenButton';\nimport { ComboboxOptions } from '../../components/Combobox/ComboboxOptions';\nimport { useWithCreated } from '../../components/Combobox/createdItems';\nimport { useGroupHeaders } from '../../components/Combobox/groupHeaders';\nimport { sanitizeTypedInput, useQueryReporter } from '../../components/Combobox/query';\nimport type { Group } from '../../components/Combobox/types';\nimport {\n createCreatableItem,\n defaultGroupToLabel,\n defaultItemToDisabled,\n defaultItemToIcon,\n defaultQueryToCreateLabel,\n defaultRowLabel,\n defaultToCreateValue,\n flatItems,\n isCreatableItem,\n isGroupHeaderItem,\n isSelectAllItem,\n selectAllItem,\n toEntries,\n toLabel,\n useCreatableStringValue,\n useItemEquality,\n} from '../../components/Combobox/utils';\nimport { useVirtualList, type VirtualizedProps } from '../../components/Combobox/virtualList';\nimport { useArgoDesign } from '../../components/ThemeProvider/context';\nimport { useControllableState } from '../../hooks/useControllableState';\nimport { DEFAULT_ENTRY_SEPARATOR, splitEntry } from '../../utils';\n\ntype ComboboxProps<Value> = BaseCombobox.Root.Props<Value, true>;\ntype ComboboxInputProps = ComponentProps<typeof Combobox.Input>;\ntype ComboboxInputGroupProps = ComponentProps<typeof Combobox.InputGroup>;\ntype ComboboxItemProps = ComponentProps<typeof Combobox.Item>;\ntype ComboboxChipsProps<Value> = ComponentProps<typeof Combobox.Chips<Value>>;\n\ntype Indicator = Exclude<NonNullable<ComboboxItemProps['indicator']>, 'none'>;\n\n/** Joins the create row's values with the entry's separator; a `RegExp` uses the default one. */\nconst joinCreateParts = (parts: string[], separator: string | RegExp | null) =>\n parts.join(`${typeof separator === 'string' ? separator : DEFAULT_ENTRY_SEPARATOR} `);\n\ntype CreatableProps<Value> = {\n allowCreate?: boolean;\n /** Words the create row. Receives the values it adds, trimmed and re-joined — not the entry as typed. */\n queryToCreateLabel?: (query: string) => ReactNode;\n /** Projects one entered value into an item. Called once per trimmed part of a split entry. */\n queryToCreateValue?: (query: string) => Value;\n /** Rejects a value `allowCreate` would mint; values naming an item or already selected skip it. */\n canCreate?: (query: string) => boolean;\n /** Splits one entry into several values (default `','`). A `RegExp` must not capture; `null` never splits. */\n createSeparator?: string | RegExp | null;\n};\n\n/**\n * Props for `MultiCombobox`.\n *\n * - Pass `isItemEqualToValue` when a store recreates item objects — Base UI matches by reference.\n */\ntype Props<Value, GroupShape extends Group<Value> = Group<Value>> = Pick<\n ComboboxInputProps,\n // Go to the input, which is the `combobox` role; on the group they reach nothing.\n // - The `aria-*` set links a form field's label, help and error text.\n // - `onBlur` is the gate `FieldItem` reveals errors on.\n | 'placeholder'\n | 'id'\n | 'name'\n | 'onBlur'\n | 'aria-label'\n | 'aria-labelledby'\n | 'aria-describedby'\n | 'aria-invalid'\n | 'aria-required'\n> &\n Pick<ComboboxInputGroupProps, 'variant' | 'focusVariant' | 'sizing' | 'state' | 'className'> &\n Pick<\n ComboboxProps<Value>,\n | 'disabled'\n | 'inputRef'\n | 'value'\n | 'defaultValue'\n | 'onValueChange'\n | 'itemToStringLabel'\n | 'itemToStringValue'\n | 'filter'\n | 'isItemEqualToValue'\n > &\n Pick<\n ComboboxChipsProps<Value>,\n 'itemToChipLabel' | 'itemToChipColor' | 'pinnedChipLabels' | 'maxVisible'\n > &\n CreatableProps<Value> &\n VirtualizedProps & {\n /** Read as immutable: pass a new array to change it; one mutated in place is not re-filtered. */\n items?: readonly (Value | GroupShape)[];\n\n // root specific\n /** Clear-all button, shown only while chips exist. Chips stay removable either way. */\n allowClear?: boolean;\n /** \"Select All\" row for the whole set; hidden while a query is active, clears when all are selected. */\n allowSelectAll?: boolean;\n empty?: ReactNode;\n /** Options still arriving; doesn't disable — pass `disabled` where the user must wait. */\n isLoading?: boolean;\n indicator?: Indicator;\n\n // query specific\n /** Rewrites typed text before filtering and creating. Sees the whole text per keystroke — don't `trim()`. */\n inputValueSanitizer?: (input: string) => string;\n /** Reports the sanitized query, on mount too. Notification only — the control owns the text. */\n onQueryChange?: (query: string) => void;\n\n // item specific\n /**\n * Row and chip content (unless `itemToChipLabel`), `itemToStringLabel` by default.\n * - `query` is the search text, for `MarkedText`; a chip gets `''`.\n */\n itemToLabel?: (item: Value, query: string) => ReactNode;\n itemToIcon?: (item: Value) => ReactNode;\n itemToDisabled?: (item: Value) => boolean;\n\n // chip specific\n /** Replaces the default chips; the chip props, `maxVisible` included, are then ignored. */\n renderChips?: (values: Value[]) => ReactNode;\n\n // group specific\n /** Defaults to the group's `label`, as `Select` shows it. */\n groupToLabel?: (group: GroupShape) => ReactNode;\n /** A row per group that folds it. A query shows every match regardless; state is keyed by position. */\n collapsibleGroups?: boolean;\n /** A group's row selects its matching enabled items. The row itself never enters `value`. */\n selectableGroups?: boolean;\n };\n\nconst NO_ITEMS: readonly never[] = [];\nconst NO_VALUES: never[] = [];\n\n/**\n * Searchable multi-select with chips, built on Base UI Combobox.\n *\n * @see RECIPES.md#creatable-multi-combobox\n * @see RECIPES.md#filter-toolbar\n */\nexport const MultiCombobox = <Value, GroupShape extends Group<Value> = Group<Value>>({\n // root props\n items: _itemsProp,\n value: _valueProp,\n defaultValue,\n onValueChange,\n itemToStringLabel,\n itemToStringValue,\n disabled,\n filter: filterProp,\n isItemEqualToValue: isItemEqualToValueProp,\n inputRef,\n\n // input props\n variant,\n sizing,\n focusVariant,\n state,\n placeholder,\n allowClear = true,\n id,\n name,\n onBlur,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-describedby': ariaDescribedBy,\n 'aria-invalid': ariaInvalid,\n 'aria-required': ariaRequired,\n className,\n\n // own props\n allowSelectAll = false,\n empty = 'No items',\n isLoading = false,\n indicator,\n virtualized = false,\n\n // query\n inputValueSanitizer,\n onQueryChange,\n\n // creatable\n allowCreate,\n canCreate,\n queryToCreateValue,\n queryToCreateLabel = defaultQueryToCreateLabel,\n createSeparator = DEFAULT_ENTRY_SEPARATOR,\n\n // own item props\n itemToDisabled = defaultItemToDisabled,\n itemToLabel: itemToLabelProp,\n itemToIcon = defaultItemToIcon,\n groupToLabel = defaultGroupToLabel,\n collapsibleGroups = false,\n selectableGroups = false,\n itemToChipLabel,\n itemToChipColor,\n pinnedChipLabels,\n renderChips,\n // Value editors pass `Infinity` (a chip inside `+N` can't be removed); single-row filters `1`.\n maxVisible = 3,\n}: Props<Value, GroupShape>) => {\n const itemsProp = _itemsProp ?? NO_ITEMS;\n // Held here while `value` is absent; Base UI always gets the selection as `value`.\n const [valueProp, setValueProp] = useControllableState<Value[]>({\n prop: _valueProp === null ? NO_VALUES : _valueProp,\n defaultProp: defaultValue ?? NO_VALUES,\n });\n const itemToString = useCallback(\n (item: Value) => itemToStringLabel?.(item) ?? toLabel(item),\n [itemToStringLabel],\n );\n const itemToLabel = itemToLabelProp ?? defaultRowLabel(itemToStringLabel);\n const renderArgo = useArgoDesign();\n const chipVariant = renderArgo ? 'pill' : 'default';\n\n const [inputValue, setInputValue] = useState('');\n const [createdItems, setCreatedItems] = useState<Value[]>([]);\n const query = inputValue.trim();\n\n useQueryReporter(query, onQueryChange);\n\n // `aria-busy` on the input only (list items stay pickable); absent rather than `false`.\n const busy = isLoading || undefined;\n\n // Held here only when needed — owning the text re-renders on every keystroke.\n // - `itemToLabel` needs it: its rows receive the query.\n const ownsInput = Boolean(\n allowCreate ||\n inputValueSanitizer ||\n onQueryChange ||\n itemToLabelProp ||\n collapsibleGroups ||\n selectableGroups,\n );\n\n const baseItems = useWithCreated(itemsProp, createdItems);\n\n const allFlatItems = flatItems(baseItems);\n const sampleItem = allFlatItems[0];\n // Otherwise `0 === 0` reads as all selected and puts the row's entry into `value`.\n const hasSelectAllRow = allowSelectAll && allFlatItems.length > 0;\n const isAllSelected = hasSelectAllRow && allFlatItems.length === (valueProp?.length ?? 0);\n\n const defaultFilter = BaseCombobox.useFilter({\n multiple: true,\n value: valueProp,\n });\n\n // Keeps the control's own rows (create, group header) away from the caller's projection.\n // Stable while the caller's accessor is: Base UI re-filters on every new identity.\n const wrappedItemToStringLabel = useMemo<ComboboxProps<Value>['itemToStringLabel']>(() => {\n // No caller projection keeps Base UI's own accessor.\n if (!allowCreate && !collapsibleGroups && !selectableGroups) {\n return itemToStringLabel && itemToString;\n }\n return (item) => {\n if (isCreatableItem(item)) return item.value;\n if (isGroupHeaderItem(item)) return item.label;\n return itemToString(item);\n };\n }, [allowCreate, collapsibleGroups, selectableGroups, itemToStringLabel, itemToString]);\n\n const itemFilter: NonNullable<ComboboxProps<Value>['filter']> =\n filterProp ?? defaultFilter.contains;\n\n const isItemEqualToValue = useItemEquality(isItemEqualToValueProp);\n\n const groupHeaders = useGroupHeaders<Value, GroupShape>({\n items: itemsProp,\n collapsible: collapsibleGroups,\n selectable: selectableGroups,\n query,\n matches: (item) => itemFilter(item, query, wrappedItemToStringLabel),\n isItemEqualToValue,\n });\n\n const listItems = useWithCreated(groupHeaders.items, createdItems);\n\n const virtualList = useVirtualList(baseItems, virtualized);\n\n const labelKey = (item: Value) => itemToString(item).toLowerCase();\n\n const createParts = !allowCreate || disabled || !query ? [] : splitEntry(query, createSeparator);\n\n const selectedKeys = new Set<string>();\n if (createParts.length > 0) for (const item of valueProp) selectedKeys.add(labelKey(item));\n\n // A set only when `canCreate` asks per value; otherwise one early-exiting scan is cheaper.\n const itemKeys = new Set<string>();\n if (createParts.length > 0 && canCreate) {\n for (const item of allFlatItems) itemKeys.add(labelKey(item));\n }\n const namesAnItem = (key: string) =>\n canCreate ? itemKeys.has(key) : allFlatItems.some((item) => labelKey(item) === key);\n\n /**\n * The entry's values not yet selected, minus those `canCreate` rejects.\n *\n * - Both names the create row and is exactly what committing it adds.\n * - A value naming an existing item counts and bypasses `canCreate` — committing selects it.\n */\n const addedCreateParts = createParts.filter((part) => {\n const key = part.toLowerCase();\n if (selectedKeys.has(key)) return false;\n return !canCreate || namesAnItem(key) || canCreate(part);\n });\n\n const soleValueKey = createParts.length === 1 ? createParts[0]!.toLowerCase() : undefined;\n\n // A single value naming an item already has its own row; a split entry matches no row.\n const showCreateRow =\n addedCreateParts.length > 0 && (soleValueKey === undefined || !namesAnItem(soleValueKey));\n\n const items = useMemo(() => {\n const withSelectAll = hasSelectAllRow\n ? [...toEntries(listItems, [selectAllItem]), ...listItems]\n : listItems;\n return showCreateRow\n ? [...withSelectAll, ...toEntries(listItems, [createCreatableItem(query)])]\n : withSelectAll;\n }, [hasSelectAllRow, showCreateRow, listItems, query]);\n\n const filterHeader = groupHeaders.enabled ? groupHeaders.filterHeader : undefined;\n const filter = useCallback(\n (item: Value, query: string, itemToString?: (value: Value) => string) => {\n // Select All covers the whole item set, so it exists only while no query narrows the list.\n if (isSelectAllItem(item)) return query.trim() === '';\n if (isCreatableItem(item)) return true;\n\n return filterHeader?.(item) ?? itemFilter(item, query, itemToString);\n },\n [filterHeader, itemFilter],\n );\n\n const wrappedItemToStringValue = useCreatableStringValue(itemToStringValue, allowCreate);\n\n const value = isAllSelected ? [...valueProp, selectAllItem as Value] : valueProp;\n\n // Without a comparer Base UI compares by identity, so a `Set` suffices.\n const selectedSet = selectableGroups && !isItemEqualToValueProp ? new Set(valueProp) : undefined;\n const isSelected = (item: Value) =>\n selectedSet?.has(item) ?? valueProp.some((selected) => isItemEqualToValue(item, selected));\n\n /** What a group's row selects: the group's items the query matches, the disabled aside. */\n const groupTargets = (row: unknown) =>\n groupHeaders.headerOf(row)?.matching.filter((item) => !itemToDisabled(item)) ?? [];\n\n /**\n * Replaces a pressed group row in `next` with its items.\n *\n * - Base UI adds the row to `value` like any unselected item.\n * - A row whose items are all selected deselects them.\n */\n const selectGroupRow = (next: Value[]) => {\n const row = next.find(isGroupHeaderItem);\n if (row === undefined) return next;\n\n const rest = next.filter((item) => item !== row);\n const targets = groupTargets(row);\n if (!targets.every(isSelected))\n return [...rest, ...targets.filter((item) => !isSelected(item))];\n return rest.filter((item) => !targets.some((target) => isItemEqualToValue(target, item)));\n };\n\n const groupRowChecked = (targets: Value[]) => {\n const selectedCount = targets.filter(isSelected).length;\n if (selectedCount === 0) return false;\n return selectedCount === targets.length ? true : 'mixed';\n };\n\n const handleInputValueChange: NonNullable<ComboboxProps<Value>['onInputValueChange']> = (\n next,\n { reason },\n ) => {\n setInputValue(sanitizeTypedInput(next, reason, inputValueSanitizer));\n };\n\n const handleValueChange: ComboboxProps<Value>['onValueChange'] = (next, event) => {\n // Base UI clears the text itself only when it owns it.\n if (ownsInput) setInputValue((prev) => (prev === '' ? prev : ''));\n // A pinned `value` with no handler: the change lands nowhere, so nothing is minted either.\n if (!onValueChange && _valueProp !== undefined) return;\n\n const picked = selectGroupRow(next);\n const created: Value[] = [];\n const converted = (() => {\n if (!allowCreate || !picked.some(isCreatableItem)) return picked;\n\n // A value naming an item selects it rather than minting a duplicate chip.\n const itemsByLabel = new Map<string, Value>();\n for (const item of allFlatItems) itemsByLabel.set(labelKey(item), item);\n\n return picked.flatMap((item) => {\n if (!isCreatableItem(item)) return [item];\n\n return addedCreateParts.map((part) => {\n const existing = itemsByLabel.get(part.toLowerCase());\n if (existing !== undefined) return existing;\n\n const value = defaultToCreateValue(part, sampleItem, queryToCreateValue) as Value;\n created.push(value);\n return value;\n });\n });\n })();\n\n const hasSelectAll = converted.some((item) => isSelectAllItem(item));\n const newValue = (() => {\n if (!hasSelectAllRow) return converted;\n if (!hasSelectAll) return isAllSelected ? [] : converted;\n return isAllSelected ? converted.filter((item) => !isSelectAllItem(item)) : allFlatItems;\n })();\n\n if (allowCreate) {\n // Filter by `newValue`: `valueProp` lacks values created in this change.\n const selected = new Set(newValue.map(itemToString));\n setCreatedItems((prev) =>\n [...prev, ...created].filter((item) => selected.has(itemToString(item))),\n );\n }\n\n setValueProp(newValue);\n onValueChange?.(newValue, event);\n };\n\n return (\n <Combobox.Root<Value, true>\n multiple\n // Otherwise Enter after typing selects nothing and closes the popup.\n autoHighlight\n items={items}\n value={value}\n filter={filter}\n isItemEqualToValue={isItemEqualToValue}\n onValueChange={handleValueChange}\n onOpenChange={groupHeaders.onOpenChange}\n onItemHighlighted={(item, details) => {\n groupHeaders.onItemHighlighted(item);\n virtualList.onItemHighlighted(details);\n }}\n virtualized={virtualList.enabled}\n itemToStringLabel={wrappedItemToStringLabel}\n itemToStringValue={wrappedItemToStringValue}\n disabled={disabled}\n inputRef={inputRef}\n {...(ownsInput ? { inputValue, onInputValueChange: handleInputValueChange } : {})}\n >\n <Combobox.InputGroup\n variant={variant}\n sizing={sizing}\n state={state}\n focusVariant={focusVariant}\n className={className}\n >\n {/* Chips plus the input row; its press handler focuses the input, arrows move between chips. */}\n <BaseCombobox.Chips className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-wrap tw:items-center tw:gap-1.5 tw:px-4 tw:py-1.5\">\n <Combobox.Chips<Value>\n maxVisible={maxVisible}\n variant={chipVariant}\n itemToChipLabel={itemToChipLabel ?? ((item) => itemToLabel(item, ''))}\n itemToChipColor={itemToChipColor}\n pinnedChipLabels={pinnedChipLabels}\n >\n {renderChips}\n </Combobox.Chips>\n {/* Wraps below the chips under 120px; alone on its row it shrinks to keep both buttons inside. */}\n <div className=\"tw:flex tw:min-w-0 tw:grow tw:items-center tw:gap-1\">\n <Combobox.Input\n id={id}\n name={name}\n onBlur={onBlur}\n aria-label={ariaLabel}\n aria-labelledby={ariaLabelledBy}\n aria-describedby={ariaDescribedBy}\n aria-invalid={ariaInvalid}\n aria-required={ariaRequired}\n aria-busy={busy}\n placeholder={placeholder}\n disabled={disabled}\n onKeyDown={groupHeaders.onInputKeyDown}\n // Cancels the group's `&_input` padding; the chip row already pads.\n className=\"tw:w-auto tw:min-w-0 tw:grow tw:basis-[120px] tw:!px-0 tw:!py-0\"\n />\n {allowClear && <ComboboxClearButton disabled={disabled} />}\n <ComboboxOpenButton disabled={disabled} isLoading={isLoading} />\n </div>\n </BaseCombobox.Chips>\n </Combobox.InputGroup>\n <Combobox.Content>\n <ComboboxOptions<Value, GroupShape>\n isLoading={isLoading}\n empty={empty}\n virtualized={virtualList.enabled}\n listRef={virtualList.ref}\n groupHeaders={groupHeaders}\n groupToLabel={groupToLabel}\n indicator={indicator}\n itemToLabel={(item) => itemToLabel(item, query)}\n itemToIcon={itemToIcon}\n itemToDisabled={itemToDisabled}\n // Names exactly the values committing the row adds.\n createLabel={() => queryToCreateLabel(joinCreateParts(addedCreateParts, createSeparator))}\n groupRowState={\n selectableGroups\n ? (row) => {\n const targets = groupTargets(row);\n return { checked: groupRowChecked(targets), disabled: targets.length === 0 };\n }\n : undefined\n }\n />\n </Combobox.Content>\n </Combobox.Root>\n );\n};\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { InputGroup } from "../../InputGroup-DcZRlVnN.js";
1
+ import { InputGroup } from "../../InputGroup-B4QOPxHl.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  //#region src/blocks/NumberInput/NumberInput.tsx
4
4
  const toNumberOrNull = (event) => Number.isNaN(event.target.valueAsNumber) ? null : event.target.valueAsNumber;
@@ -1,2 +1,2 @@
1
- import { OtpInput, REGEXP_ONLY_CHARS, REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from "../../OtpInput-CbbymqYs.js";
1
+ import { OtpInput, REGEXP_ONLY_CHARS, REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS } from "../../OtpInput-I8B8Vjdl.js";
2
2
  export { OtpInput, REGEXP_ONLY_CHARS, REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS };
@@ -1,2 +1,2 @@
1
- import { PageHeader } from "../../PageHeader-Q3IpCnQd.js";
1
+ import { PageHeader } from "../../PageHeader-CgfyXpf1.js";
2
2
  export { PageHeader };
@@ -1,2 +1,2 @@
1
- import { PageLayout } from "../../PageLayout-DSVM-ASz.js";
1
+ import { PageLayout } from "../../PageLayout-DiAAILuS.js";
2
2
  export { PageLayout };
@@ -1,2 +1,2 @@
1
- import { PageToolbar } from "../../PageToolbar-BKVJiDAL.js";
1
+ import { PageToolbar } from "../../PageToolbar-DOAtAnfL.js";
2
2
  export { PageToolbar };
@@ -1,8 +1,8 @@
1
- import { createChangeInputEvent } from "../../utils-DnkrFYqY.js";
1
+ import { createChangeInputEvent } from "../../utils-Bd28bWgm.js";
2
2
  import { mergeRefs } from "../utils/mergeRefs.js";
3
- import { ArrowBigUpDash, Eye, EyeOff, X } from "../../icons-Cek151jC.js";
4
- import { InputGroup } from "../../InputGroup-DcZRlVnN.js";
5
- import { useControllableState } from "../../useControllableState-M6494mCT.js";
3
+ import { ArrowBigUpDash, Eye, EyeOff, X } from "../../icons-wcA70iQx.js";
4
+ import { InputGroup } from "../../InputGroup-B4QOPxHl.js";
5
+ import { useControllableState } from "../../useControllableState-CUYXMsfz.js";
6
6
  import { useRef, useState } from "react";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  //#region src/blocks/PasswordInput/PasswordInput.tsx